Skip to content

Commit

Permalink
refactor(cli): migrate from watchService to fs.watch
Browse files Browse the repository at this point in the history
still WIP. made things sync. commented out watch flow and reduced crazy timeouts.
things fail, as implementation is disabled, but this is a better starting point for the fix.
  • Loading branch information
AviVahl committed Dec 21, 2024
1 parent 96c7f14 commit 9f55657
Show file tree
Hide file tree
Showing 24 changed files with 197 additions and 227 deletions.
2 changes: 1 addition & 1 deletion packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
"stc-format": "bin/stc-format.js"
},
"scripts": {
"test": "mocha \"./dist/test/**/*.spec.js\" --timeout 25000"
"test": "mocha \"./dist/test/**/*.spec.js\""
},
"dependencies": {
"@file-services/node": "^9.4.1",
Expand Down
6 changes: 3 additions & 3 deletions packages/cli/src/base-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,12 @@ export class IndexGenerator {
);
}

public async generateIndexFile(fs: IFileSystem) {
public generateIndexFile(fs: IFileSystem) {
const indexFileContent = this.generateIndexSource();
ensureDirectory(fs.dirname(this.indexFileTargetPath), fs);

await tryRun(
() => fs.promises.writeFile(this.indexFileTargetPath, '\n' + indexFileContent + '\n'),
tryRun(
() => fs.writeFileSync(this.indexFileTargetPath, '\n' + indexFileContent + '\n'),
'Write Index File Error',
);

Expand Down
6 changes: 3 additions & 3 deletions packages/cli/src/build-stylable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ export interface BuildStylableContext
};
}

export async function buildStylable(
export function buildStylable(
rootDir: string,
{
defaultOptions = createDefaultOptions(),
Expand Down Expand Up @@ -59,7 +59,7 @@ export async function buildStylable(
const { config } = resolveConfig(rootDir, fs, configFilePath) || {};
validateDefaultConfig(config?.defaultConfig);

const projects = await projectsConfig(rootDir, overrideBuildOptions, defaultOptions, config);
const projects = projectsConfig(rootDir, overrideBuildOptions, defaultOptions, config);
const watchHandler = new WatchHandler(fileSystem, {
log,
resolverCache,
Expand Down Expand Up @@ -102,7 +102,7 @@ export async function buildStylable(
requireModule('@stylable/node').resolveNamespace,
});

const { service, generatedFiles } = await build(buildOptions, {
const { service, generatedFiles } = build(buildOptions, {
watch,
stylable,
log,
Expand Down
12 changes: 6 additions & 6 deletions packages/cli/src/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { StylableOptimizer } from '@stylable/optimizer';
import type { Stylable } from '@stylable/core';
import type { IFileSystem } from '@file-services/types';

export async function build(
export function build(
{
srcDir,
outDir,
Expand Down Expand Up @@ -129,7 +129,7 @@ export async function build(
throw error;
}
},
async processFiles(_, affectedFiles, deletedFiles, changeOrigin) {
processFiles(_, affectedFiles, deletedFiles, changeOrigin) {
if (changeOrigin) {
// handle deleted files by removing their generated content
if (deletedFiles.size) {
Expand Down Expand Up @@ -196,7 +196,7 @@ export async function build(
// rewire invalidations
updateWatcherDependencies(affectedFiles);
// rebuild assets from aggregated content: index files and assets
await buildAggregatedEntities(affectedFiles, processGeneratedFiles);
buildAggregatedEntities(affectedFiles, processGeneratedFiles);
// rebundle
if (bundle) {
tryRun(() => {
Expand Down Expand Up @@ -242,7 +242,7 @@ export async function build(
},
});

await service.init(fullSrcDir);
service.init(fullSrcDir);

if (sourceFiles.size === 0) {
log(mode, buildMessages.BUILD_SKIPPED(isMultiPackagesProject ? identifier : undefined));
Expand Down Expand Up @@ -362,9 +362,9 @@ export async function build(
});
}

async function buildAggregatedEntities(affectedFiles: Set<string>, generated: Set<string>) {
function buildAggregatedEntities(affectedFiles: Set<string>, generated: Set<string>) {
if (indexFileGenerator) {
await indexFileGenerator.generateIndexFile(fs);
indexFileGenerator.generateIndexFile(fs);

generated.add(indexFileGenerator.indexFileTargetPath);
outputFiles.set(indexFileGenerator.indexFileTargetPath, affectedFiles);
Expand Down
101 changes: 47 additions & 54 deletions packages/cli/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,64 +4,57 @@ import { buildStylable } from './build-stylable';
import { createDefaultOptions, getCliArguments, resolveCliOptions } from './config/resolve-options';
import { createLogger } from './logger';

async function main() {
const argv = getCliArguments();
const { resolve } = fs;
const {
watch,
require: requires,
log: shouldLog,
namespaceResolver,
preserveWatchOutput,
config,
} = argv;
const rootDir = resolve(argv.rootDir);
const explicitResolveNs =
namespaceResolver &&
require(
require.resolve(namespaceResolver, {
paths: [rootDir],
}),
);

//
const log = createLogger(
(level, ...messages) => {
if (shouldLog || level === 'info') {
const currentTime = new Date().toLocaleTimeString();
console.log('[Stylable]', `[${currentTime}]`, ...messages);
}
},
() => !shouldLog && !preserveWatchOutput && console.clear(),
const argv = getCliArguments();
const { resolve } = fs;
const {
watch,
require: requires,
log: shouldLog,
namespaceResolver,
preserveWatchOutput,
config,
} = argv;
const rootDir = resolve(argv.rootDir);
const explicitResolveNs =
namespaceResolver &&
require(
require.resolve(namespaceResolver, {
paths: [rootDir],
}),
);

// execute all require hooks before running the CLI build
for (const request of requires) {
require(request);
}
//
const log = createLogger(
(level, ...messages) => {
if (shouldLog || level === 'info') {
const currentTime = new Date().toLocaleTimeString();
console.log('[Stylable]', `[${currentTime}]`, ...messages);
}
},
() => !shouldLog && !preserveWatchOutput && console.clear(),
);

const defaultOptions = createDefaultOptions();
const overrideBuildOptions = resolveCliOptions(argv, defaultOptions);
const { watchHandler } = await buildStylable(rootDir, {
overrideBuildOptions,
defaultOptions,
fs,
resolveNamespace: explicitResolveNs?.resolveNamespace,
watch,
log,
configFilePath: config,
});
// execute all require hooks before running the CLI build
for (const request of requires) {
require(request);
}

process.on('SIGTERM', () => {
void watchHandler.stop();
});
const defaultOptions = createDefaultOptions();
const overrideBuildOptions = resolveCliOptions(argv, defaultOptions);
const { watchHandler } = buildStylable(rootDir, {
overrideBuildOptions,
defaultOptions,
fs,
resolveNamespace: explicitResolveNs?.resolveNamespace,
watch,
log,
configFilePath: config,
});

process.on('SIGINT', () => {
void watchHandler.stop();
});
}
process.on('SIGTERM', () => {
void watchHandler.stop();
});

main().catch((e) => {
process.exitCode = 1;
console.error(e);
process.on('SIGINT', () => {
void watchHandler.stop();
});
48 changes: 20 additions & 28 deletions packages/cli/src/config/projects-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { resolveNpmRequests } from './resolve-requests';
import type { StylableConfig } from '@stylable/core';
import type { IFileSystem } from '@file-services/types';

interface StylableRuntimeConfigs {
export interface StylableRuntimeConfigs {
stcConfig?: Configuration<string> | undefined;
defaultConfig?: Pick<
StylableConfig,
Expand All @@ -28,12 +28,12 @@ interface StylableRuntimeConfigs {
>;
}

export async function projectsConfig(
export function projectsConfig(
rootDir: string,
overrideBuildOptions: Partial<BuildOptions>,
defaultOptions: BuildOptions = createDefaultOptions(),
config?: StylableRuntimeConfigs,
): Promise<STCProjects> {
): STCProjects {
const topLevelOptions = mergeBuildOptions(
defaultOptions,
config?.stcConfig?.options,
Expand All @@ -42,29 +42,21 @@ export async function projectsConfig(

validateOptions(topLevelOptions);

let projects: STCProjects;

if (isMultipleConfigProject(config)) {
const { entities } = processProjects(config.stcConfig, {
defaultOptions: topLevelOptions,
});

projects = await resolveProjectsRequests({
rootDir,
entities,
resolveRequests:
config.stcConfig.projectsOptions?.resolveRequests ?? resolveNpmRequests,
});
} else {
projects = [
{
projectRoot: rootDir,
options: [topLevelOptions],
},
];
}

return projects;
return isMultipleConfigProject(config)
? resolveProjectsRequests({
rootDir,
entities: processProjects(config.stcConfig, {
defaultOptions: topLevelOptions,
}).entities,
resolveRequests:
config.stcConfig.projectsOptions?.resolveRequests ?? resolveNpmRequests,
})
: [
{
projectRoot: rootDir,
options: [topLevelOptions],
},
];
}

export function resolveConfig(context: string, fs: IFileSystem, request?: string) {
Expand Down Expand Up @@ -110,15 +102,15 @@ function isMultipleConfigProject(
return Boolean(config?.stcConfig?.projects);
}

async function resolveProjectsRequests({
function resolveProjectsRequests({
entities,
rootDir,
resolveRequests,
}: {
rootDir: string;
entities: Array<RawProjectEntity>;
resolveRequests: ResolveRequests;
}): Promise<STCProjects> {
}): STCProjects {
const context: ResolveProjectsContext = { rootDir };

return resolveRequests(entities, context);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export interface DirectoryProcessServiceOptions {
affectedFiles: Set<string>,
deletedFiles: Set<string>,
changeOrigin?: IWatchEvent,
): Promise<{ generatedFiles: Set<string> }> | { generatedFiles: Set<string> };
): { generatedFiles: Set<string> };
directoryFilter?(directoryPath: string): boolean;
fileFilter?(filePath: string): boolean;
onError?(error: Error): void;
Expand All @@ -31,23 +31,23 @@ export class DirectoryProcessService {
}
}
public startWatch() {
this.fs.watchService.addGlobalListener(this.watchHandler);
// this.fs.watchService.addGlobalListener(this.watchHandler);
}
public async dispose() {
for (const path of this.watchedDirectoryFiles.keys()) {
await this.fs.watchService.unwatchPath(path);
}
public dispose() {
// for (const path of this.watchedDirectoryFiles.keys()) {
// await this.fs.watchService.unwatchPath(path);
// }

this.invalidationMap.clear();
this.watchedDirectoryFiles.clear();
}
public async init(directoryPath: string) {
await this.watchPath(directoryPath);
public init(directoryPath: string) {
// await this.watchPath(directoryPath);
const items = directoryDeepChildren(this.fs, directoryPath, this.filterWatchItems);
const affectedFiles = new Set<string>();
for await (const item of items) {
for (const item of items) {
if (item.type === 'directory') {
await this.watchPath(item.path);
// await this.watchPath(item.path);
} else if (item.type === 'file') {
affectedFiles.add(item.path);
this.addFileToWatchedDirectory(item.path);
Expand All @@ -56,7 +56,7 @@ export class DirectoryProcessService {
}
if (affectedFiles.size) {
try {
await this.options.processFiles?.(this, affectedFiles, new Set());
this.options.processFiles?.(this, affectedFiles, new Set());
} catch (error) {
this.options.onError?.(error as Error);
}
Expand Down Expand Up @@ -101,20 +101,20 @@ export class DirectoryProcessService {
this.watchedDirectoryFiles.set(directoryPath, new Set());
return this.fs.watchService.watchPath(directoryPath);
}
public async handleWatchChange(
public handleWatchChange(
files: Map<string, IWatchEvent>,
originalEvent: IWatchEvent,
): Promise<{
): {
hasChanges: boolean;
generatedFiles: Set<string>;
}> {
} {
const affectedFiles = new Set<string>();
const deletedFiles = new Set<string>();

for (const event of files.values()) {
if (event.stats?.isDirectory()) {
if (this.options.directoryFilter?.(event.path) ?? true) {
for (const filePath of await this.init(event.path)) {
for (const filePath of this.init(event.path)) {
affectedFiles.add(filePath);
}
}
Expand Down Expand Up @@ -163,7 +163,7 @@ export class DirectoryProcessService {
}

if (this.options.processFiles && (affectedFiles.size || deletedFiles.size)) {
const { generatedFiles } = await this.options.processFiles(
const { generatedFiles } = this.options.processFiles(
this,
affectedFiles,
deletedFiles,
Expand Down Expand Up @@ -203,7 +203,11 @@ export class DirectoryProcessService {
files.set(file, createWatchEvent(file, this.fs));
}

this.handleWatchChange(files, event).catch((error) => this.options.onError?.(error));
try {
this.handleWatchChange(files, event);
} catch (error) {
this.options.onError?.(error as Error);
}
};
private filterWatchItems = (event: DirectoryItem): boolean => {
const { fileFilter, directoryFilter } = this.options;
Expand Down
Loading

0 comments on commit 9f55657

Please # to comment.