Print list of articles & sectionTA created and deleted by each modifying text

This commit is contained in:
Emmanuel 2024-12-06 16:56:58 +01:00
parent d078baa6af
commit 9cd4808344

View file

@ -25,16 +25,20 @@ interface Context {
articleById: Record<string, JorfArticle | LegiArticle> articleById: Record<string, JorfArticle | LegiArticle>
articleModificateurIdByActionById: Record< articleModificateurIdByActionById: Record<
string, string,
Record<Action, string | undefined> Partial<Record<Action, string>>
> >
currentInternalIds: Set<string> currentInternalIds: Set<string>
idsByActionByTexteMoficateurId: Record<
string,
Partial<Record<Action, Set<string>>>
>
legiTexteInternalIds: Set<string> legiTexteInternalIds: Set<string>
sectionTaById: Record<string, LegiSectionTa> sectionTaById: Record<string, LegiSectionTa>
targetDir: string targetDir: string
texteManquantById: Record<string, TexteManquant> texteManquantById: Record<string, TexteManquant>
texteModificateurIdByActionById: Record< texteModificateurIdByActionById: Record<
string, string,
Record<Action, string | undefined> Partial<Record<Action, string>>
> >
texteVersionById: Record<string, JorfTexteVersion | LegiTexteVersion | null> texteVersionById: Record<string, JorfTexteVersion | LegiTexteVersion | null>
} }
@ -81,13 +85,8 @@ async function addArticleModificateurId(
return return
} }
let articleModificateurIdByAction = const articleModificateurIdByAction =
context.articleModificateurIdByActionById[modifiedId] (context.articleModificateurIdByActionById[modifiedId] ??= {})
if (articleModificateurIdByAction === undefined) {
articleModificateurIdByAction = context.articleModificateurIdByActionById[
modifiedId
] = { CREATE: undefined, DELETE: undefined }
}
const existingArticleModificateurId = articleModificateurIdByAction[action] const existingArticleModificateurId = articleModificateurIdByAction[action]
if (existingArticleModificateurId === undefined) { if (existingArticleModificateurId === undefined) {
articleModificateurIdByAction[action] = articleModificateurId articleModificateurIdByAction[action] = articleModificateurId
@ -155,19 +154,15 @@ async function addTexteModificateurId(
return return
} }
let texteModificateurIdByAction = const texteModificateurIdByAction = (context.texteModificateurIdByActionById[
context.texteModificateurIdByActionById[modifiedId]
if (texteModificateurIdByAction === undefined) {
texteModificateurIdByAction = context.texteModificateurIdByActionById[
modifiedId modifiedId
] = { ] ??= {})
CREATE: undefined,
DELETE: undefined,
}
}
const existingTexteModificateurId = texteModificateurIdByAction[action] const existingTexteModificateurId = texteModificateurIdByAction[action]
if (existingTexteModificateurId === undefined) { if (existingTexteModificateurId === undefined) {
texteModificateurIdByAction[action] = texteModificateurId texteModificateurIdByAction[action] = texteModificateurId
;((context.idsByActionByTexteMoficateurId[texteModificateurId] ??= {})[
action
] ??= new Set()).add(modifiedId)
} else if (existingTexteModificateurId !== texteModificateurId) { } else if (existingTexteModificateurId !== texteModificateurId) {
const existingTexteVersionModificateur = (await getOrLoadTexteVersion( const existingTexteVersionModificateur = (await getOrLoadTexteVersion(
context, context,
@ -178,6 +173,9 @@ async function addTexteModificateurId(
.DATE_TEXTE! < texteModificateurDateSignature .DATE_TEXTE! < texteModificateurDateSignature
) { ) {
texteModificateurIdByAction[action] = texteModificateurId texteModificateurIdByAction[action] = texteModificateurId
;((context.idsByActionByTexteMoficateurId[texteModificateurId] ??= {})[
action
] ??= new Set()).add(modifiedId)
} }
} }
} }
@ -190,6 +188,7 @@ async function exportLegiTexteToMarkdown(
articleById: {}, articleById: {},
articleModificateurIdByActionById: {}, articleModificateurIdByActionById: {},
currentInternalIds: new Set(), currentInternalIds: new Set(),
idsByActionByTexteMoficateurId: {},
legiTexteInternalIds: new Set(), legiTexteInternalIds: new Set(),
sectionTaById: {}, sectionTaById: {},
targetDir, targetDir,
@ -219,7 +218,7 @@ async function exportLegiTexteToMarkdown(
// First Pass: Register IDs of internal objects // First Pass: Register IDs of internal objects
const textelrStructure = textelr.STRUCT const { STRUCT: textelrStructure } = textelr
const liensArticles = textelrStructure?.LIEN_ART const liensArticles = textelrStructure?.LIEN_ART
if (liensArticles !== undefined) { if (liensArticles !== undefined) {
for (const lienArticle of liensArticles) { for (const lienArticle of liensArticles) {
@ -343,7 +342,6 @@ async function exportLegiTexteToMarkdown(
texteVersion.META.META_SPEC.META_TEXTE_VERSION.TITRE ?? texteVersion.META.META_SPEC.META_TEXTE_VERSION.TITRE ??
texteVersion.META.META_COMMUN.ID texteVersion.META.META_COMMUN.ID
const codeDirName = slugify(codeTitle, "_") const codeDirName = slugify(codeTitle, "_")
const codeRepositoryRelativeDir = codeDirName
await fs.writeFile( await fs.writeFile(
path.join(targetDir, "README.md"), path.join(targetDir, "README.md"),
dedent` dedent`
@ -372,6 +370,7 @@ async function exportLegiTexteToMarkdown(
).toSorted(([date1], [date2]) => date1.localeCompare(date2))) { ).toSorted(([date1], [date2]) => date1.localeCompare(date2))) {
console.log(date) console.log(date)
for (const texteModificateurId of textesModificateursId.toSorted()) { for (const texteModificateurId of textesModificateursId.toSorted()) {
const t1 = performance.now()
let texteVersionModificateur: let texteVersionModificateur:
| JorfTexteVersion | JorfTexteVersion
| LegiTexteVersion | LegiTexteVersion
@ -393,16 +392,28 @@ async function exportLegiTexteToMarkdown(
texteModificateurTitle = `!!! Texte non trouvé ${date} !!!` texteModificateurTitle = `!!! Texte non trouvé ${date} !!!`
} }
console.log(` ${texteModificateurId} ${texteModificateurTitle}`) console.log(` ${texteModificateurId} ${texteModificateurTitle}`)
const idsByAction =
context.idsByActionByTexteMoficateurId[texteModificateurId]
if (idsByAction.DELETE !== undefined) {
console.log(
` DELETE: ${[...idsByAction.DELETE].toSorted().join(", ")}`,
)
}
if (idsByAction.CREATE !== undefined) {
console.log(
` CREATE: ${[...idsByAction.CREATE].toSorted().join(", ")}`,
)
}
const t2 = performance.now()
await generateGitDirectory( await generateTexteGitDirectory(
context, context,
2, 2,
codeTitle, textelr,
liensArticles, texteVersion as LegiTexteVersion,
textelrStructure?.LIEN_SECTION_TA,
codeRepositoryRelativeDir,
texteModificateurId, texteModificateurId,
) )
const t3 = performance.now()
await git.commit({ await git.commit({
dir: targetDir, dir: targetDir,
fs, fs,
@ -412,23 +423,37 @@ async function exportLegiTexteToMarkdown(
}, },
message: texteModificateurTitle, message: texteModificateurTitle,
}) })
const t4 = performance.now()
console.log(`Durations: ${t2 - t1} ${t3 - t2} ${t4 - t3}`)
} }
} }
} }
async function generateGitDirectory( async function generateSectionTaGitDirectory(
context: Context, context: Context,
depth: number, depth: number,
id: string, lienSectionTa: LegiSectionTaLienSectionTa,
title: string, sectionTa: LegiSectionTa,
liensArticles: LegiSectionTaLienArt[] | undefined, parentRepositoryRelativeDir: string,
liensSectionTa: LegiSectionTaLienSectionTa[] | undefined,
repositoryRelativeDir: string,
texteModificateurId: string, texteModificateurId: string,
) { ) {
const sectionTaTitle = sectionTa.TITRE_TA ?? sectionTa.ID
let sectionTaSlug = slugify(sectionTaTitle.split(":")[0].trim(), "_")
if (sectionTaSlug.length > 255) {
sectionTaSlug = sectionTaSlug.slice(0, 254)
if (sectionTaSlug.at(-1) !== "_") {
sectionTaSlug += "_"
}
}
const sectionTaDirName = sectionTaSlug
const repositoryRelativeDir = path.join(
parentRepositoryRelativeDir,
sectionTaDirName,
)
await fs.ensureDir(path.join(context.targetDir, repositoryRelativeDir)) await fs.ensureDir(path.join(context.targetDir, repositoryRelativeDir))
const readmeLinks: Array<{ href: string; title: string }> = [] const readmeLinks: Array<{ href: string; title: string }> = []
const liensArticles = sectionTa.STRUCTURE_TA?.LIEN_ART
if (liensArticles !== undefined) { if (liensArticles !== undefined) {
for (const lienArticle of liensArticles) { for (const lienArticle of liensArticles) {
const articleId = lienArticle["@id"] const articleId = lienArticle["@id"]
@ -470,7 +495,18 @@ async function generateGitDirectory(
path.join(context.targetDir, articleRepositoryRelativeFilePath), path.join(context.targetDir, articleRepositoryRelativeFilePath),
dedent` dedent`
--- ---
ID: ${articleId} ${[
["Type", article.META.META_SPEC.META_ARTICLE.TYPE],
["Date de début", article.META.META_SPEC.META_ARTICLE.DATE_DEBUT],
["Date de fin", article.META.META_SPEC.META_ARTICLE.DATE_FIN],
["Identifiant", articleId],
["Ancien identifiant", article.META.META_COMMUN.ANCIEN_ID],
// TODO: Mettre l'URL dans le Git Tricoteuses
["URL", article.META.META_COMMUN.URL],
]
.filter(([, value]) => value !== undefined)
.map(([key, value]) => `${key}: ${value}`)
.join("\n")}
--- ---
###### ${articleTitle} ###### ${articleTitle}
@ -487,6 +523,7 @@ async function generateGitDirectory(
} }
} }
const liensSectionTa = sectionTa.STRUCTURE_TA?.LIEN_SECTION_TA
if (liensSectionTa !== undefined) { if (liensSectionTa !== undefined) {
for (const lienSectionTa of liensSectionTa) { for (const lienSectionTa of liensSectionTa) {
const sectionTaId = lienSectionTa["@id"] const sectionTaId = lienSectionTa["@id"]
@ -536,10 +573,21 @@ async function generateGitDirectory(
path.join(context.targetDir, readmeRepositoryRelativeFilePath), path.join(context.targetDir, readmeRepositoryRelativeFilePath),
dedent` dedent`
--- ---
ID: ${id} ${[
["Commentaire", sectionTa.COMMENTAIRE],
["État", lienSectionTa["@etat"]],
["Date de début", lienSectionTa["@debut"]],
["Date de fin", lienSectionTa["@fin"]],
["Identifiant", sectionTa.ID],
// TODO: Mettre l'URL dans le Git Tricoteuses
["URL", lienSectionTa["@url"]],
]
.filter(([, value]) => value !== undefined)
.map(([key, value]) => `${key}: ${value}`)
.join("\n")}
--- ---
${"#".repeat(Math.min(depth, 6))} ${title} ${"#".repeat(Math.min(depth, 6))} ${sectionTa.TITRE_TA ?? sectionTa.ID}
${readmeLinks.map(({ href, title }) => `- [${title}](${href})`).join("\n")} ${readmeLinks.map(({ href, title }) => `- [${title}](${href})`).join("\n")}
` + "\n", ` + "\n",
@ -554,6 +602,114 @@ async function generateGitDirectory(
for (const lienSectionTa of liensSectionTa) { for (const lienSectionTa of liensSectionTa) {
const sectionTaId = lienSectionTa["@id"] const sectionTaId = lienSectionTa["@id"]
if (context.currentInternalIds.has(sectionTaId)) { if (context.currentInternalIds.has(sectionTaId)) {
const sectionTa = (await getOrLoadSectionTa(
context,
sectionTaId,
)) as LegiSectionTa
await generateSectionTaGitDirectory(
context,
depth + 1,
lienSectionTa,
sectionTa,
repositoryRelativeDir,
texteModificateurId,
)
}
}
}
}
async function generateTexteGitDirectory(
context: Context,
depth: number,
textelr: LegiTextelr,
texteVersion: LegiTexteVersion,
texteModificateurId: string,
) {
const texteTitle =
texteVersion.META.META_SPEC.META_TEXTE_VERSION.TITREFULL ??
texteVersion.META.META_SPEC.META_TEXTE_VERSION.TITRE ??
texteVersion.META.META_COMMUN.ID
const texteDirName = slugify(texteTitle, "_")
const repositoryRelativeDir = texteDirName
await fs.ensureDir(path.join(context.targetDir, repositoryRelativeDir))
const readmeLinks: Array<{ href: string; title: string }> = []
const { STRUCT: textelrStructure } = textelr
const liensArticles = textelrStructure?.LIEN_ART
if (liensArticles !== undefined) {
for (const lienArticle of liensArticles) {
const articleId = lienArticle["@id"]
const article = (await getOrLoadArticle(
context,
articleId,
)) as LegiArticle
const articleTitle = `Article ${article.META.META_SPEC.META_ARTICLE.NUM ?? articleId}`
let articleSlug = slugify(articleTitle, "_")
if (articleSlug.length > 252) {
articleSlug = articleSlug.slice(0, 251)
if (articleSlug.at(-1) !== "_") {
articleSlug += "_"
}
}
const articleFilename = `${articleSlug}.md`
const articleRepositoryRelativeFilePath = path.join(
repositoryRelativeDir,
articleFilename,
)
const texteModificateurIdByAction =
context.texteModificateurIdByActionById[articleId]
if (context.currentInternalIds.has(articleId)) {
if (texteModificateurIdByAction.DELETE === texteModificateurId) {
await fs.remove(
path.join(context.targetDir, articleRepositoryRelativeFilePath),
)
context.currentInternalIds.delete(articleId)
continue
}
} else {
if (texteModificateurIdByAction.CREATE === texteModificateurId) {
context.currentInternalIds.add(articleId)
} else {
continue
}
}
await fs.writeFile(
path.join(context.targetDir, articleRepositoryRelativeFilePath),
dedent`
---
${[
["Type", article.META.META_SPEC.META_ARTICLE.TYPE],
["Date de début", article.META.META_SPEC.META_ARTICLE.DATE_DEBUT],
["Date de fin", article.META.META_SPEC.META_ARTICLE.DATE_FIN],
["Identifiant", articleId],
["Ancien identifiant", article.META.META_COMMUN.ANCIEN_ID],
// TODO: Mettre l'URL dans le Git Tricoteuses
["URL", article.META.META_COMMUN.URL],
]
.filter(([, value]) => value !== undefined)
.map(([key, value]) => `${key}: ${value}`)
.join("\n")}
---
###### ${articleTitle}
${article.BLOC_TEXTUEL?.CONTENU}
` + "\n",
)
await git.add({
dir: context.targetDir,
filepath: articleRepositoryRelativeFilePath,
fs,
})
readmeLinks.push({ href: articleFilename, title: articleTitle })
}
}
const liensSectionTa = textelrStructure?.LIEN_SECTION_TA
if (liensSectionTa !== undefined) {
for (const lienSectionTa of liensSectionTa) {
const sectionTaId = lienSectionTa["@id"]
const sectionTa = (await getOrLoadSectionTa( const sectionTa = (await getOrLoadSectionTa(
context, context,
sectionTaId, sectionTaId,
@ -571,14 +727,86 @@ async function generateGitDirectory(
repositoryRelativeDir, repositoryRelativeDir,
sectionTaDirName, sectionTaDirName,
) )
await generateGitDirectory( const texteModificateurIdByAction =
context.texteModificateurIdByActionById[sectionTaId]
if (context.currentInternalIds.has(sectionTaId)) {
if (texteModificateurIdByAction.DELETE === texteModificateurId) {
await fs.remove(
path.join(context.targetDir, sectionTaRepositoryRelativeDir),
)
context.currentInternalIds.delete(sectionTaId)
continue
}
} else {
if (texteModificateurIdByAction.CREATE === texteModificateurId) {
context.currentInternalIds.add(sectionTaId)
} else {
continue
}
}
readmeLinks.push({ href: sectionTaDirName, title: sectionTaTitle })
}
}
const readmeRepositoryRelativeFilePath = path.join(
repositoryRelativeDir,
"README.md",
)
await fs.writeFile(
path.join(context.targetDir, readmeRepositoryRelativeFilePath),
dedent`
---
${[
["État", texteVersion.META.META_SPEC.META_TEXTE_VERSION.ETAT],
["Nature", texteVersion.META.META_COMMUN.NATURE],
[
"Date de début",
texteVersion.META.META_SPEC.META_TEXTE_VERSION.DATE_DEBUT,
],
[
"Date de fin",
texteVersion.META.META_SPEC.META_TEXTE_VERSION.DATE_FIN,
],
["Identifiant", texteVersion.META.META_COMMUN.ID],
["NOR", texteVersion.META.META_SPEC.META_TEXTE_CHRONICLE.NOR],
["Ancien identifiant", texteVersion.META.META_COMMUN.ANCIEN_ID],
// TODO: Mettre l'URL dans le Git Tricoteuses
["URL", texteVersion.META.META_COMMUN.URL],
]
.filter(([, value]) => value !== undefined)
.map(([key, value]) => `${key}: ${value}`)
.join("\n")}
---
${"#".repeat(Math.min(depth, 6))} ${
texteVersion.META.META_SPEC.META_TEXTE_VERSION.TITREFULL ??
texteVersion.META.META_SPEC.META_TEXTE_VERSION.TITRE ??
texteVersion.META.META_COMMUN.ID
}
${readmeLinks.map(({ href, title }) => `- [${title}](${href})`).join("\n")}
` + "\n",
)
await git.add({
dir: context.targetDir,
filepath: readmeRepositoryRelativeFilePath,
fs,
})
if (liensSectionTa !== undefined) {
for (const lienSectionTa of liensSectionTa) {
const sectionTaId = lienSectionTa["@id"]
if (context.currentInternalIds.has(sectionTaId)) {
const sectionTa = (await getOrLoadSectionTa(
context,
sectionTaId,
)) as LegiSectionTa
await generateSectionTaGitDirectory(
context, context,
depth + 1, depth + 1,
sectionTaId, lienSectionTa,
sectionTaTitle, sectionTa,
sectionTa?.STRUCTURE_TA?.LIEN_ART, repositoryRelativeDir,
sectionTa?.STRUCTURE_TA?.LIEN_SECTION_TA,
sectionTaRepositoryRelativeDir,
texteModificateurId, texteModificateurId,
) )
} }
@ -895,25 +1123,17 @@ async function registerLegiArticleModifiers(
} }
// If article has no texte créateur at all, then create a fake one. // If article has no texte créateur at all, then create a fake one.
let texteModificateurIdByAction = const texteModificateurIdByAction = (context.texteModificateurIdByActionById[
context.texteModificateurIdByActionById[articleId]
if (texteModificateurIdByAction === undefined) {
texteModificateurIdByAction = context.texteModificateurIdByActionById[
articleId articleId
] = { ] ??= {})
CREATE: undefined,
DELETE: undefined,
}
}
if (texteModificateurIdByAction.CREATE === undefined) { if (texteModificateurIdByAction.CREATE === undefined) {
const texteManquantId = `ZZZZ TEXTE MANQUANT ${articleDateDebut}` const texteManquantId = `ZZZZ TEXTE MANQUANT ${articleDateDebut}`
let texteManquant = context.texteManquantById[texteManquantId] context.texteManquantById[texteManquantId] ??= {
if (texteManquant === undefined) {
texteManquant = context.texteManquantById[texteManquantId] = {
date: articleDateDebut, date: articleDateDebut,
} }
}
texteModificateurIdByAction.CREATE = texteManquantId texteModificateurIdByAction.CREATE = texteManquantId
;((context.idsByActionByTexteMoficateurId[texteManquantId] ??=
{}).CREATE ??= new Set()).add(articleId)
} }
} }
@ -1028,26 +1248,18 @@ async function registerLegiSectionTaModifiers(
} }
} }
// If article has no texte créateur at all, then create a fake one. // If article has no texte créateur at all, then use a fake one.
let texteModificateurIdByAction = const texteModificateurIdByAction = (context.texteModificateurIdByActionById[
context.texteModificateurIdByActionById[sectionTaId]
if (texteModificateurIdByAction === undefined) {
texteModificateurIdByAction = context.texteModificateurIdByActionById[
sectionTaId sectionTaId
] = { ] ??= {})
CREATE: undefined,
DELETE: undefined,
}
}
if (texteModificateurIdByAction.CREATE === undefined) { if (texteModificateurIdByAction.CREATE === undefined) {
const texteManquantId = `ZZZZ TEXTE MANQUANT ${sectionTaDateDebut}` const texteManquantId = `ZZZZ TEXTE MANQUANT ${sectionTaDateDebut}`
let texteManquant = context.texteManquantById[texteManquantId] context.texteManquantById[texteManquantId] ??= {
if (texteManquant === undefined) {
texteManquant = context.texteManquantById[texteManquantId] = {
date: sectionTaDateDebut, date: sectionTaDateDebut,
} }
}
texteModificateurIdByAction.CREATE = texteManquantId texteModificateurIdByAction.CREATE = texteManquantId
;((context.idsByActionByTexteMoficateurId[texteManquantId] ??=
{}).CREATE ??= new Set()).add(sectionTaId)
} }
} }