Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
3y3 committed Jan 16, 2025
1 parent fa9b5b4 commit c843b83
Show file tree
Hide file tree
Showing 35 changed files with 919 additions and 975 deletions.
9 changes: 1 addition & 8 deletions src/commands/build/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -259,15 +259,8 @@ export class Build

await run.vars.init();
await run.toc.init();
await run.vcs.init();

const excluded = await run.glob(['**/*.md', '**/index.yaml', ...run.config.ignore], {
cwd: run.input,
ignore: ['**/_*/**/*', '**/_include--*'].concat(run.toc.entries),
});

for (const file of excluded) {
await run.remove(join(run.input, file));
}
await Promise.all([handler(run), this[Hooks].Run.promise(run)]);

await this[Hooks].AfterRun.for(this.config.outputFormat).promise(run);
Expand Down
15 changes: 11 additions & 4 deletions src/commands/build/run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ import {
} from '~/constants';
import {Run as BaseRun} from '~/core/run';
import {VarsService} from '~/core/vars';
import {MetaService} from '~/core/meta';
import {TocService} from '~/core/toc';
import {VcsService} from '~/core/vcs';

/**
* This is transferable context for build command.
Expand All @@ -29,16 +31,20 @@ export class Run extends BaseRun<BuildConfig> {

readonly vars: VarsService;

readonly meta: MetaService;

readonly toc: TocService;

get bundlePath() {
return join(this.output, BUNDLE_FOLDER);
}
readonly vcs: VcsService;

get configPath() {
return this.config[configPath] || join(this.config.input, YFM_CONFIG_FILENAME);
}

get bundlePath() {
return join(this.output, BUNDLE_FOLDER);
}

get redirectsPath() {
return join(this.originalInput, REDIRECTS_FILENAME);
}
Expand All @@ -59,7 +65,8 @@ export class Run extends BaseRun<BuildConfig> {
this.scopes.set('<result>', this.originalOutput);

this.vars = new VarsService(this);
this.meta = new MetaService(this);
this.toc = new TocService(this);

this.vcs = new VcsService(this);
}
}
74 changes: 74 additions & 0 deletions src/commands/lint/handler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import type {Run} from './run';

import {ArgvService, PluginService, PresetService} from '~/services';

Check failure on line 3 in src/commands/lint/handler.ts

View workflow job for this annotation

GitHub Actions / Verify Files

'ArgvService' is defined but never used. Allowed unused vars must match /^_/u

Check failure on line 3 in src/commands/lint/handler.ts

View workflow job for this annotation

GitHub Actions / Verify Files

'PluginService' is defined but never used. Allowed unused vars must match /^_/u

Check failure on line 3 in src/commands/lint/handler.ts

View workflow job for this annotation

GitHub Actions / Verify Files

'PresetService' is defined but never used. Allowed unused vars must match /^_/u
import {processLogs} from '~/steps';
import {bounded, isExternalHref, logger, own} from '~/utils';

Check failure on line 5 in src/commands/lint/handler.ts

View workflow job for this annotation

GitHub Actions / Verify Files

'bounded' is defined but never used. Allowed unused vars must match /^_/u

Check failure on line 5 in src/commands/lint/handler.ts

View workflow job for this annotation

GitHub Actions / Verify Files

'logger' is defined but never used. Allowed unused vars must match /^_/u
import {LINTING_FINISHED, MIN_CHUNK_SIZE, WORKERS_COUNT} from '~/constants';

Check failure on line 6 in src/commands/lint/handler.ts

View workflow job for this annotation

GitHub Actions / Verify Files

'MIN_CHUNK_SIZE' is defined but never used. Allowed unused vars must match /^_/u
import log from '@diplodoc/transform/lib/log';

Check failure on line 7 in src/commands/lint/handler.ts

View workflow job for this annotation

GitHub Actions / Verify Files

'log' is defined but never used. Allowed unused vars must match /^_/u
import {Pool, Thread, Worker, spawn} from 'threads';

Check failure on line 8 in src/commands/lint/handler.ts

View workflow job for this annotation

GitHub Actions / Verify Files

'Thread' is defined but never used. Allowed unused vars must match /^_/u
import {ProcessLinterWorker} from '~/workers/linter';

Check failure on line 9 in src/commands/lint/handler.ts

View workflow job for this annotation

GitHub Actions / Verify Files

'ProcessLinterWorker' is defined but never used. Allowed unused vars must match /^_/u
import {lintPage} from '~/resolvers';

Check failure on line 10 in src/commands/lint/handler.ts

View workflow job for this annotation

GitHub Actions / Verify Files

'lintPage' is defined but never used. Allowed unused vars must match /^_/u
import {extname} from 'path';

function connect(run: Run, linter: Worker) {
return linter;
}

export async function handler(run: Run) {
try {
if (!run.config.lint.enabled) {
return;
}

const workers = new Pool(
async () => {
return connect(run, await spawn(new Worker('./linter')));
},
{
size: WORKERS_COUNT,
},
);

run.toc.hooks.ItemResolved.tap((item, toc, path) => {
if (own<string, 'href'>(item, 'href') && !isExternalHref(item.href)) {
workers.queue(async (linter) => {
const result = await linter.process([item.href, path]);

run.logger.info(path, LINTING_FINISHED);

return result;
});
}
});

await run.toc.init();
await workers.completed();
await workers.terminate();

/* Subscribe on the linted page event */
// await workers.map(([worker]) => {
// worker.getProcessedPages().subscribe((pathToFile) => {
// logger.info(pathToFile as string, LINTING_FINISHED);
// });
// });

/* Run processing the linter */
// await workers.map(([worker, chunk]) => {
// await worker.init(config, chunk);
// return run.start();
// });
//
// /* Unsubscribe from workers */
// await workers.map(([worker]) => {
// return worker.finish().then((logs) => {
// log.add(logs);
// });
// });

// await workers.terminate();
} catch (error) {
run.logger.error(error);
} finally {
processLogs(run.input);
}
}
30 changes: 30 additions & 0 deletions src/commands/lint/hooks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import {intercept} from '~/utils';
import {AsyncParallelHook, AsyncSeriesHook} from 'tapable';

const name = 'Lint';

export function hooks() {
return intercept(name, {
/**
* Async series hook which runs before start of any Run type.<br/><br/>
* Args:
* - run - [Build.Run](./Run.ts) constructed context.<br/>
* Best place to subscribe on Run hooks.
*/
BeforeAnyRun: new AsyncSeriesHook<Run>(['run'], `${name}.BeforeAnyRun`),
/**
* Async parallel hook which runs on start of any Run type.<br/><br/>
* Args:
* - run - [Build.Run](./Run.ts) constructed context.<br/>
* Best place to do something in parallel with main build process.
*/
Run: new AsyncParallelHook<Run>(['run'], `${name}.Run`),
AfterAnyRun: new AsyncSeriesHook<Run>(['run'], `${name}.AfterAnyRun`),
});
}

export const Hooks = Symbol(`${name}Hooks`);

export function getHooks(program: {[Hooks]?: ReturnType<typeof hooks>}) {
return program[Hooks] || hooks();
}
107 changes: 107 additions & 0 deletions src/commands/lint/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import type {IProgram, BaseArgs as ProgramArgs, BaseConfig as ProgramConfig} from '~/core/program';

import {pick} from 'lodash';

import {BaseProgram} from '~/core/program';
import {GenericIncluderExtension, OpenapiIncluderExtension} from '~/core/toc';
import {Stage, YFM_CONFIG_FILENAME} from '~/constants';
import {Command, Config} from '~/config';

import {options} from '../build/config';
import {Run} from '../build/run';
import {Templating, TemplatingArgs, TemplatingConfig} from '../build/features/templating';
import {LintArgs, LintConfig} from '../build/features/linter';

import {handler} from './handler';
import {Hooks, hooks} from './hooks';

type BaseArgs = {output: AbsolutePath};

type BaseConfig = {
varsPreset: string;
vars: Hash;
allowHtml: boolean;
sanitizeHtml: boolean;
ignoreStage: string[];
ignore: string[];
};

export type {Run};

const command = 'Build';

export type CommandArgs = ProgramArgs & BaseArgs & Partial<TemplatingArgs & LintArgs>;

export type CommandConfig = Config<
BaseArgs & ProgramConfig & BaseConfig & TemplatingConfig & LintConfig
>;

export class Lint
// eslint-disable-next-line new-cap
extends BaseProgram<CommandConfig, CommandArgs>(command, {
config: {
scope: 'link',
defaults: () =>
({
varsPreset: 'default',
vars: {},
ignore: [],
allowHtml: true,
sanitizeHtml: true,
ignoreStage: [Stage.SKIP],
lint: {enabled: true, config: {'log-levels': {}}},
}) as Partial<CommandConfig>,
},
})
implements IProgram<CommandArgs>
{
readonly [Hooks] = hooks();

readonly templating = new Templating();

// readonly linter = new Lint();

readonly command = new Command('build').description('Build documentation in target directory');

readonly options = [
options.input('./'),
options.output({required: true}),
options.varsPreset,
options.vars,
options.allowHtml,
options.sanitizeHtml,
options.ignore,
options.ignoreStage,
options.config(YFM_CONFIG_FILENAME),
];

apply(program?: IProgram) {
this[Hooks].Config.tap('Lint', (config, args) => {
config.ignoreStage = ([] as string[]).concat(config.ignoreStage);

return config;
});

this.templating.apply(this);
this.linter.apply(this);

new GenericIncluderExtension().apply(this);
new OpenapiIncluderExtension().apply(this);

super.apply(program);
}

async action(config?: CommandConfig, chunk?: NormalizedPath[]) {
const run = new Run(config || this.config);

run.logger.pipe(this.logger);

await this[Hooks].BeforeAnyRun.promise(run);

await run.toc.init(chunk);

await Promise.all([handler(run), this[Hooks].Run.promise(run)]);

await this[Hooks].AfterAnyRun.promise(run);
}
}
Empty file added src/commands/lint/worker.ts
Empty file.
Loading

0 comments on commit c843b83

Please sign in to comment.