Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
.vscode

node_modules
build
build

28 changes: 15 additions & 13 deletions assets/scripts/GitAgent.js
Original file line number Diff line number Diff line change
Expand Up @@ -418,25 +418,27 @@ export default class GitAgent {
*
* @param {string} login
* @param {string} email
* @returns {Promise<ReturnType<isomorphicGit["setConfig"]>>}
* @returns {Promise<any>}
*/
async setAuthor(login, email) {
if (!login || !email) {
return
}

await git.setConfig({
fs: this.#fs,
dir: this.#repoDirectory,
path: 'user.name',
value: login,
})
return await git.setConfig({
fs: this.#fs,
dir: this.#repoDirectory,
path: 'user.email',
value: email,
})
return Promise.all([
git.setConfig({
fs: this.#fs,
dir: this.#repoDirectory,
path: 'user.name',
value: login,
}),
git.setConfig({
fs: this.#fs,
dir: this.#repoDirectory,
path: 'user.email',
value: email,
})
])
}

/**
Expand Down
184 changes: 184 additions & 0 deletions assets/scripts/ScribouilliGitRepo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
//@ts-check

import {parseDocument} from 'yaml'
import { fetchAuthenticatedUserLogin } from './actions/current-user'

/** @import GitAgent from './GitAgent' */
/** @import YAML from 'yaml' */
/** @import {ScribouilliGitRepo, OAuthServiceAPI, ScribouilliGitUser} from './types.js' */

/**
* @type {ScribouilliGitRepo}
*/
export default class {

/** @type {OAuthServiceAPI} */
#gitServiceProvider

/** @type {Promise<YAML.Document>} */
#jekyllConfig

/** @type {((error: string | Error) => void) | undefined} */
#onLoginFailed

/** @type {ScribouilliGitUser['login']} */
#login
get login(){
return this.#login
}


/**
*
* @param { object } _
* @param { string } [_.repoId]
* @param { string } _.origin
* @param { string } _.publicRepositoryURL
* @param { string } _.owner
* @param { string } _.repoName
* @param { OAuthServiceAPI } _.gitServiceProvider
* @param { GitAgent } _.gitAgent
* @param { (error: string | Error) => void } [_.onLoginFailed]
*/
constructor({
repoId,
origin,
publicRepositoryURL,
owner,
repoName,
gitServiceProvider,
gitAgent,
onLoginFailed
}) {
throw "repoId in gitlab is encodeURIComponent(`${owner}/${repoName}`) mais pour le fs, ça ne marcherait pas"


this.origin = origin
this.publicRepositoryURL = publicRepositoryURL
this.owner = owner
this.repoName = repoName
/** @type {GitAgent} */
this.gitAgent = gitAgent
this.#gitServiceProvider = gitServiceProvider
this.#onLoginFailed = onLoginFailed

this.repoId = repoId ? repoId : makeRepoId(owner, repoName)

this.publishedWebsiteURL = new Promise(resolve => {
const interval = setInterval(() => {
this.#gitServiceProvider.getPublishedWebsiteURL(this)
.then(url => {
if(url){
clearInterval(interval)
resolve(url)
}
})
}, 1000)
})

const authorSet = this.fetchAuthenticatedUserLoginAndEmail()
.then(({login, email}) => gitAgent.setAuthor(login, email))

const repoSynced = gitAgent.pullOrCloneRepo()

repoSynced.then(() => {
this.#jekyllConfig = this.gitAgent
.getFile('_config.yml')
.then(configStr => parseDocument(configStr))

this.#jekyllConfig.then(conf => console.log('conf', conf))
})



throw `PPP
rajouter ici setBaseUrlInConfigIfNecessary() (après le parsing du config.yml)
rajouter les store.mutations.setLogin qui ont disparu ?
`


this.ready = Promise.all([authorSet, repoSynced]).then(() => undefined)



throw `PPP
- internaliser le clone ici + setBaseUrlInConfigIfNecessary (sortir la fonction des actions et la mettre ici)
- recups + parser le _config.yml ici avec la fonction parseDocument (qui préserve les commentaires)
- permettre un accès en lecture à la config
- remplacer toutes les lectures de _config.yml dans le code par ce qu'il se passe ici
- permettre un changeConfig avec un Object.assign + commit push direct
`
}

/**
* @summary edit the config with the diff passed as argument
*
*
*/
editConfig(configDiff){

}

/**
*
* @returns {Promise<{login: string, email: string}>}
*/
fetchAuthenticatedUserLoginAndEmail(){
const loginP = this.#gitServiceProvider
.getAuthenticatedUser()
.then(({ login }) => {
if (!login) {
throw new Error('No login')
}

return login
})
.catch(err => {
if(this.#onLoginFailed){
this.#onLoginFailed(err)
}
throw err
})

const emailP = this.#gitServiceProvider
.getUserEmails()
.then(emails => {
const email = (emails.find(e => e.primary) ?? emails[0]).email
return email
})
.catch(err => {
if(this.#onLoginFailed){
this.#onLoginFailed(err)
}
throw err
})

return Promise.all([loginP, emailP])
.then(([login, email]) => ({login, email}))
}


}

/**
*
* @param {string} owner // may be an individual Github user or an organisation
* @param {string} repoName
* @returns {string}
*/
export function makeRepoId(owner, repoName) {
return `${owner}/${repoName}`
}

/**
*
* @param {string} owner // may be an individual Github user or an organisation
* @param {string} repoName
* @param {string} origin
* @returns {string}
*/
export function makePublicRepositoryURL(owner, repoName, origin) {
return `${origin}/${owner}/${repoName}`
}


112 changes: 112 additions & 0 deletions assets/scripts/actions/autoUpdateScribouilliWebsite.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
//@ts-check

import {stringify} from 'yaml'

import {getRepoConfig} from './repoConfig.js'
import { writeFileAndPushChanges } from './file.js'

/** @typedef {import('../GitAgent.js').default} GitAgent */

/**
* Cette fonction met à jour automatiquement un repo scribouilli
* Cette fonctionnalté est devenue nécessaire notamment avec Github qui
* déprécie Node.js 16
* https://github.blog/changelog/2024-03-07-github-actions-all-actions-will-run-on-node20-instead-of-node16-by-default/
* Pour cette situation, nous devons mettre à jour les fichiers workflow pour les sites github
* C'est l'occasion de mettre en place un système de mise à jour automatisé pour s'occuper de toutes ces questions
* dont les personnes qui utilisent Scribouilli ne vont pas s'occuper
*
*
* @param {GitAgent} gitAgent
*/
export default async function autoUpdateScribouilliWebsite(gitAgent){

const scribouilliRepo = await isScribouilliRepo(gitAgent)

if(scribouilliRepo){


throw `PPP
check check si la personne sait se débrouiller
- si oui, ne pas faire les updates automatisées
- si non, faire les update automatisées
`
}
}

/**
*
* @param {GitAgent} gitAgent
*
* @returns {Promise<boolean>}
*/
export async function isScribouilliRepo(gitAgent){
const explicitelyScribouilliRepo = await isExplicitScribouilliRepo(gitAgent)

if(explicitelyScribouilliRepo){
console.info('Repo explicitement Scribouilli')
return true
}
else{
const implicitScribouilliRepo = await isImplicitScribouilliRepo(gitAgent)
if(implicitScribouilliRepo){
// Cette branche ne sera plus nécessaire en 2026, par exemple
console.info('Repo implicitement Scribouilli. On le rend explicitement Scribouilli')
await makeExplicitScribouilliRepo(gitAgent)
return true
}
else{
return false
}
}
}

/**
* @param {GitAgent} gitAgent
* @returns {Promise<boolean>}
*/
async function isExplicitScribouilliRepo(gitAgent){
return getRepoConfig(gitAgent)
.then(config => !!config.scribouilli)
}

/**
* @param {GitAgent} gitAgent
* @returns {Promise<void>}
*/
async function makeExplicitScribouilliRepo(gitAgent){
const config = await getRepoConfig(gitAgent)
config.scribouilli = true

const configYmlContent = stringify(config)

console.log('configYmlContent', configYmlContent)
return writeFileAndPushChanges(
'_config.yml',
configYmlContent,
`Rajouter 'scribouilli:true' dans le _config.yml pour rendre le repo explicitement Scribouilli`,
)
}

/**
*
* @param {GitAgent} gitAgent
* @returns {Promise<boolean>}
*/
async function isImplicitScribouilliRepo(gitAgent){
const workflowFile = await gitAgent.getFile('.github/workflows/build-and-deploy.yml')

if(workflowFile.includes('Scribouilli')){
return true;
}

const readmeFile = await gitAgent.getFile('LICENSE')

if(readmeFile.includes('Scribouilli')){
return true;
}

// si un jour on découvre que c'est insuffisant, on peut tenter de regarder dans les topics du repo

return false
}
Loading