Skip to content

Commit

Permalink
cache config and add options to configure globs
Browse files Browse the repository at this point in the history
  • Loading branch information
alaindresse committed Sep 26, 2024
1 parent 6a69acb commit 1d0c32b
Show file tree
Hide file tree
Showing 8 changed files with 136 additions and 59 deletions.
10 changes: 10 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -556,6 +556,16 @@
"type": "boolean",
"default": false,
"markdownDescription": "%asciidoc.antora.enableAntoraSupport.desc%"
},
"asciidoc.antora.search.antoraConfig": {
"type": "array",
"default": ["**/antora.yml"],
"markdownDescription": "%asciidoc.antora.search.antoraConfig.desc%"
},
"asciidoc.antora.search.exclude": {
"type": "array",
"default": [],
"markdownDescription": "%asciidoc.antora.search.exclude.desc%"
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion package.nls.de.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,5 +69,7 @@
"asciidoc.use_kroki.desc": "**Veraltet:** Aktiviert die Kroki-Integration zur Generierung von Diagrammen.",
"asciidoc.use_kroki.deprecationMessage": "Diese Einstellung wurde durch `#asciidoc.extensions.enableKroki#` ersetzt und hat keine Auswirkungen mehr.",
"asciidoc.antora.title": "Antora",
"asciidoc.antora.enableAntoraSupport.desc": "Aktiviere [Antora](https://antora.org/) Unterstützung."
"asciidoc.antora.enableAntoraSupport.desc": "Aktiviere [Antora](https://antora.org/) Unterstützung.",
"asciidoc.antora.search.antoraConfig.desc": "Antora config globs",
"asciidoc.antora.search.exclude.desc": "Globs to exclude from antora file search"
}
4 changes: 3 additions & 1 deletion package.nls.fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,5 +69,7 @@
"asciidoc.use_kroki.desc": "**Obsolète:** Active l'extension Kroki afin de générer des diagrammes.",
"asciidoc.use_kroki.deprecationMessage": "Ce paramètre a été remplacé par `#asciidoc.extensions.enableKroki#` et n'a plus aucun effet.",
"asciidoc.antora.title": "Antora",
"asciidoc.antora.enableAntoraSupport.desc": "Active le support [Antora](https://antora.org/)."
"asciidoc.antora.enableAntoraSupport.desc": "Active le support [Antora](https://antora.org/).",
"asciidoc.antora.search.antoraConfig.desc": "Antora config globs",
"asciidoc.antora.search.exclude.desc": "Globs to exclude from antora file search"
}
4 changes: 3 additions & 1 deletion package.nls.ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,5 +69,7 @@
"asciidoc.use_kroki.desc": "**非推奨:** ダイアグラム生成Krokiを使用します。",
"asciidoc.use_kroki.deprecationMessage": "本設定は、`#asciidoc.extensions.enableKroki#`に置き換えられ、動作しません。",
"asciidoc.antora.title": "Antora",
"asciidoc.antora.enableAntoraSupport.desc": "[Antora](https://antora.org/)サポートを有効にします。"
"asciidoc.antora.enableAntoraSupport.desc": "[Antora](https://antora.org/)サポートを有効にします。",
"asciidoc.antora.search.antoraConfig.desc": "Antora config globs",
"asciidoc.antora.search.exclude.desc": "Globs to exclude from antora file search"
}
4 changes: 3 additions & 1 deletion package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -78,5 +78,7 @@
"asciidoc.use_kroki.deprecationMessage": "This setting has been replaced by `#asciidoc.extensions.enableKroki#` and no longer has any effect.",

"asciidoc.antora.title": "Antora",
"asciidoc.antora.enableAntoraSupport.desc": "Enable [Antora](https://antora.org/) support."
"asciidoc.antora.enableAntoraSupport.desc": "Enable [Antora](https://antora.org/) support.",
"asciidoc.antora.search.antoraConfig.desc": "Antora config globs",
"asciidoc.antora.search.exclude.desc": "Globs to exclude from antora file search"
}
99 changes: 99 additions & 0 deletions src/features/antora/antoraConfigs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
import vscode, { CancellationTokenSource, FileType } from 'vscode'
import { findAntoraFiles } from './findAntoraFiles'
import yaml from 'js-yaml'
import ospath from 'path'

export class AntoraConfig {
public contentSourceRootPath: string
public contentSourceRootFsPath: string

private static versionMap = new Map<string, number>()

constructor (public uri: vscode.Uri, public config: { [key: string]: any }) {
const path = uri.path
this.contentSourceRootPath = path.slice(0, path.lastIndexOf('/'))
this.contentSourceRootFsPath = ospath.dirname(uri.fsPath)
if (config.version === true || config.version === undefined) {
config.version = this.getVersionForPath(path)
}
}

public getVersionForPath (path: string): string {
const version = AntoraConfig.versionMap.get(path)
if (version) return `V-${version}`

const nextVersion = AntoraConfig.versionMap.size + 1
AntoraConfig.versionMap.set(path, nextVersion)
return `V-${nextVersion}`
}
}

const cache = {
antoraConfigs: [] as AntoraConfig[],
antoraConfigUris: [] as vscode.Uri[],
}

let ongoingRefreshPromise : Promise<void> | undefined

async function refreshAntoraConfigs (token?: vscode.CancellationToken) {
if (!ongoingRefreshPromise) {
ongoingRefreshPromise = asyncTriggerRefresh(token).then(() => {
ongoingRefreshPromise = undefined
})
}
await ongoingRefreshPromise

async function asyncTriggerRefresh (token: vscode.CancellationToken): Promise<void> {
const antoraConfigArray = vscode.workspace.getConfiguration('asciidoc.antora.search', null).get<string[]>('antoraConfig')
const glob = '{' + antoraConfigArray.join(',') + '}'
const antoraConfigUris = await findAntoraFiles(glob, token)

const cancellationToken = new CancellationTokenSource()
cancellationToken.token.onCancellationRequested((e) => {
console.log('Cancellation requested, cause: ' + e)
})
// check for Antora configuration
const antoraConfigs = (await Promise.all(antoraConfigUris.map(async (antoraConfigUri) => {
let config = {}
const parentPath = antoraConfigUri.path.slice(0, antoraConfigUri.path.lastIndexOf('/'))
const parentDirectoryStat = await vscode.workspace.fs.stat(antoraConfigUri.with({ path: parentPath }))
if (parentDirectoryStat.type === (FileType.Directory | FileType.SymbolicLink) || parentDirectoryStat.type === FileType.SymbolicLink) {
// ignore!
return undefined
}
try {
config = yaml.load(await vscode.workspace.fs.readFile(antoraConfigUri)) || {}
} catch (err) {
console.log(`Unable to parse ${antoraConfigUri}, cause:` + err.toString())
}
return new AntoraConfig(antoraConfigUri, config)
}))).filter((c) => c) // filter undefined

cache.antoraConfigs = antoraConfigs
cache.antoraConfigUris = antoraConfigUris
}
}

export async function getAntoraConfigs (token?: vscode.CancellationToken) {
if (!cache.antoraConfigs.length) {
await refreshAntoraConfigs(token)
}
return cache.antoraConfigs
}

export async function getAntoraConfigUris (token?: vscode.CancellationToken) {
if (!cache.antoraConfigUris.length) {
await refreshAntoraConfigs(token)
}
return cache.antoraConfigUris
}

// initial refresh of antora configs
refreshAntoraConfigs()

// Update the configs when an antora.yml file changes
vscode.workspace.onDidChangeTextDocument(async (event) => {
if (event.document.uri.path.endsWith('antora.yml')) {
await refreshAntoraConfigs()
}
})
63 changes: 8 additions & 55 deletions src/features/antora/antoraSupport.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import vscode, { CancellationTokenSource, FileType, Memento, Uri } from 'vscode'
import vscode, { CancellationTokenSource, Memento, Uri } from 'vscode'
import fs from 'fs'
import yaml from 'js-yaml'
import ospath, { posix as posixpath } from 'path'
Expand All @@ -9,6 +9,9 @@ import ContentCatalog from '@antora/content-classifier/content-catalog'
import { getWorkspaceFolder } from '../../util/workspace'
import { dir, exists } from '../../util/file'
import * as contentClassifier from '@antora/content-classifier'
import { AntoraConfig, getAntoraConfigs, getAntoraConfigUris } from './antoraConfigs'
import { findAntoraFiles } from './findAntoraFiles'

const classifyContent = contentClassifier.default || contentClassifier

const MAX_DEPTH_SEARCH_ANTORA_CONFIG = 100
Expand All @@ -19,32 +22,6 @@ export interface AntoraResourceContext {
version: string;
module: string;
}

export class AntoraConfig {
public contentSourceRootPath: string
public contentSourceRootFsPath: string

private static versionMap = new Map<string, number>()

constructor (public uri: vscode.Uri, public config: { [key: string]: any }) {
const path = uri.path
this.contentSourceRootPath = path.slice(0, path.lastIndexOf('/'))
this.contentSourceRootFsPath = ospath.dirname(uri.fsPath)
if (config.version === true || config.version === undefined) {
config.version = this.getVersionForPath(path)
}
}

public getVersionForPath (path: string): string {
const version = AntoraConfig.versionMap.get(path)
if (version) return `V-${version}`

const nextVersion = AntoraConfig.versionMap.size + 1
AntoraConfig.versionMap.set(path, nextVersion)
return `V-${nextVersion}`
}
}

export class AntoraDocumentContext {
private PERMITTED_FAMILIES = ['attachment', 'example', 'image', 'page', 'partial']

Expand Down Expand Up @@ -192,8 +169,8 @@ export async function findAntoraConfigFile (textDocumentUri: Uri): Promise<Uri |
cancellationToken.token.onCancellationRequested((e) => {
console.log('Cancellation requested, cause: ' + e)
})
const antoraConfigUris = await vscode.workspace.findFiles('**/antora.yml', undefined, 100, cancellationToken.token)
// check for Antora configuration
const antoraConfigUris = await getAntoraConfigUris(cancellationToken.token)

for (const antoraConfigUri of antoraConfigUris) {
const antoraConfigParentDirPath = antoraConfigUri.path.slice(0, antoraConfigUri.path.lastIndexOf('/'))
const modulesDirPath = posixpath.normalize(`${antoraConfigParentDirPath}/modules`)
Expand Down Expand Up @@ -233,31 +210,6 @@ export async function antoraConfigFileExists (textDocumentUri: Uri): Promise<boo
return antoraConfig !== undefined
}

export async function getAntoraConfigs (): Promise<AntoraConfig[]> {
const cancellationToken = new CancellationTokenSource()
cancellationToken.token.onCancellationRequested((e) => {
console.log('Cancellation requested, cause: ' + e)
})
const antoraConfigUris = await vscode.workspace.findFiles('**/antora.yml', undefined, 100, cancellationToken.token)
// check for Antora configuration
const antoraConfigs = await Promise.all(antoraConfigUris.map(async (antoraConfigUri) => {
let config = {}
const parentPath = antoraConfigUri.path.slice(0, antoraConfigUri.path.lastIndexOf('/'))
const parentDirectoryStat = await vscode.workspace.fs.stat(antoraConfigUri.with({ path: parentPath }))
if (parentDirectoryStat.type === (FileType.Directory | FileType.SymbolicLink) || parentDirectoryStat.type === FileType.SymbolicLink) {
// ignore!
return undefined
}
try {
config = yaml.load(await vscode.workspace.fs.readFile(antoraConfigUri)) || {}
} catch (err) {
console.log(`Unable to parse ${antoraConfigUri}, cause:` + err.toString())
}
return new AntoraConfig(antoraConfigUri, config)
}))
return antoraConfigs.filter((c) => c) // filter undefined
}

export async function getAntoraConfig (textDocumentUri: Uri): Promise<AntoraConfig | undefined> {
const antoraConfigUri = await findAntoraConfigFile(textDocumentUri)
if (antoraConfigUri === undefined) {
Expand Down Expand Up @@ -293,7 +245,8 @@ export async function getAntoraDocumentContext (textDocumentUri: Uri, workspaceS
const workspaceFolder = getWorkspaceFolder(antoraConfig.uri)
const workspaceRelative = posixpath.relative(workspaceFolder.uri.path, antoraConfig.contentSourceRootPath)
const globPattern = 'modules/*/{attachments,examples,images,pages,partials,assets}/**'
const files = await Promise.all((await vscode.workspace.findFiles(`${workspaceRelative ? `${workspaceRelative}/` : ''}${globPattern}`)).map(async (file) => {
// const files = await Promise.all((await vscode.workspace.findFiles(`${workspaceRelative ? `${workspaceRelative}/` : ''}${globPattern}`)).map(async (file) => {
const files = await Promise.all((await findAntoraFiles(`${workspaceRelative ? `${workspaceRelative}/` : ''}${globPattern}`)).map(async (file) => {
const contentSourceRootPath = antoraConfig.contentSourceRootPath
return {
base: contentSourceRootPath,
Expand Down
7 changes: 7 additions & 0 deletions src/features/antora/findAntoraFiles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import vscode from 'vscode'

export async function findAntoraFiles (glob: string, token?: vscode.CancellationToken) {
const excludeArray = vscode.workspace.getConfiguration('asciidoc.antora.search', null).get<string[]>('exclude')
const excludeString = '{' + excludeArray.join(',') + '}'
return vscode.workspace.findFiles(glob, excludeString, 100, token)
}

0 comments on commit 1d0c32b

Please sign in to comment.