Skip to content

Commit

Permalink
feat(exit): sys.exit() returns a promise
Browse files Browse the repository at this point in the history
exit() returns a promise so it can async close down workers and watchers
  • Loading branch information
adamdbradley committed Aug 20, 2020
1 parent cf335e3 commit 208ef8c
Show file tree
Hide file tree
Showing 10 changed files with 146 additions and 49 deletions.
16 changes: 10 additions & 6 deletions src/cli/run.ts
Expand Up @@ -42,13 +42,17 @@ export const run = async (init: CliInitOptions) => {
const findConfigResults = await findConfig({ sys, configPath: flags.config });
if (hasError(findConfigResults.diagnostics)) {
logger.printDiagnostics(findConfigResults.diagnostics);
sys.exit(1);
return sys.exit(1);
}

const ensureDepsResults = await sys.ensureDependencies({ rootDir: findConfigResults.rootDir, logger, dependencies: dependencies as any });
const ensureDepsResults = await sys.ensureDependencies({
rootDir: findConfigResults.rootDir,
logger,
dependencies: dependencies as any,
});
if (hasError(ensureDepsResults.diagnostics)) {
logger.printDiagnostics(ensureDepsResults.diagnostics);
sys.exit(1);
return sys.exit(1);
}

const coreCompiler = await loadCoreCompiler(sys);
Expand Down Expand Up @@ -79,7 +83,7 @@ export const run = async (init: CliInitOptions) => {
if (validated.diagnostics.length > 0) {
logger.printDiagnostics(validated.diagnostics);
if (hasError(validated.diagnostics)) {
sys.exit(1);
return sys.exit(1);
}
}

Expand All @@ -93,7 +97,7 @@ export const run = async (init: CliInitOptions) => {
} catch (e) {
if (!shouldIgnoreError(e)) {
logger.error(`uncaught cli error: ${e}${logger.getLevel() === 'debug' ? e.stack : ''}`);
sys.exit(1);
return sys.exit(1);
}
}
};
Expand Down Expand Up @@ -139,6 +143,6 @@ export const runTask = async (coreCompiler: CoreCompiler, config: Config, task:
default:
config.logger.error(`${config.logger.emoji('❌ ')}Invalid stencil command, please see the options below:`);
taskHelp(config.sys, config.logger);
config.sys.exit(1);
return config.sys.exit(1);
}
};
10 changes: 8 additions & 2 deletions src/cli/task-build.ts
Expand Up @@ -28,7 +28,13 @@ export const taskBuild = async (coreCompiler: CoreCompiler, config: Config) => {
if (results.hasError) {
exitCode = 1;
} else if (config.flags.prerender) {
const prerenderDiagnostics = await runPrerenderTask(coreCompiler, config, results.hydrateAppFilePath, results.componentGraph, null);
const prerenderDiagnostics = await runPrerenderTask(
coreCompiler,
config,
results.hydrateAppFilePath,
results.componentGraph,
null,
);
config.logger.printDiagnostics(prerenderDiagnostics);

if (prerenderDiagnostics.some(d => d.level === 'error')) {
Expand All @@ -43,6 +49,6 @@ export const taskBuild = async (coreCompiler: CoreCompiler, config: Config) => {
}

if (exitCode > 0) {
config.sys.exit(exitCode);
return config.sys.exit(exitCode);
}
};
34 changes: 26 additions & 8 deletions src/cli/task-generate.ts
Expand Up @@ -9,34 +9,35 @@ import { validateComponentTag } from '@utils';
export const taskGenerate = async (coreCompiler: CoreCompiler, config: Config) => {
if (!IS_NODE_ENV) {
config.logger.error(`"generate" command is currently only implemented for a NodeJS environment`);
config.sys.exit(1);
return config.sys.exit(1);
}

const path = coreCompiler.path;

if (!config.configPath) {
config.logger.error('Please run this command in your root directory (i. e. the one containing stencil.config.ts).');
config.sys.exit(1);
return config.sys.exit(1);
}

const absoluteSrcDir = config.srcDir;

if (!absoluteSrcDir) {
config.logger.error(`Stencil's srcDir was not specified.`);
config.sys.exit(1);
return config.sys.exit(1);
}

const { prompt } = await import('prompts');

const input =
config.flags.unknownArgs.find(arg => !arg.startsWith('-')) || ((await prompt({ name: 'tagName', type: 'text', message: 'Component tag name (dash-case):' })).tagName as string);
config.flags.unknownArgs.find(arg => !arg.startsWith('-')) ||
((await prompt({ name: 'tagName', type: 'text', message: 'Component tag name (dash-case):' })).tagName as string);

const { dir, base: componentName } = path.parse(input);

const tagError = validateComponentTag(componentName);
if (tagError) {
config.logger.error(tagError);
config.sys.exit(1);
return config.sys.exit(1);
}

const extensionsToGenerate: GeneratableExtension[] = ['tsx', ...(await chooseFilesToGenerate())];
Expand All @@ -47,7 +48,16 @@ export const taskGenerate = async (coreCompiler: CoreCompiler, config: Config) =
await config.sys.createDir(path.join(outDir, testFolder), { recursive: true });

const writtenFiles = await Promise.all(
extensionsToGenerate.map(extension => writeFileByExtension(coreCompiler, config, outDir, componentName, extension, extensionsToGenerate.includes('css'))),
extensionsToGenerate.map(extension =>
writeFileByExtension(
coreCompiler,
config,
outDir,
componentName,
extension,
extensionsToGenerate.includes('css'),
),
),
).catch(error => config.logger.error(error));

if (!writtenFiles) {
Expand Down Expand Up @@ -85,7 +95,14 @@ const chooseFilesToGenerate = async () => {
/**
* Get a file's boilerplate by its extension and write it to disk.
*/
const writeFileByExtension = async (coreCompiler: CoreCompiler, config: Config, path: string, name: string, extension: GeneratableExtension, withCss: boolean) => {
const writeFileByExtension = async (
coreCompiler: CoreCompiler,
config: Config,
path: string,
name: string,
extension: GeneratableExtension,
withCss: boolean,
) => {
if (isTest(extension)) {
path = coreCompiler.path.join(path, 'test');
}
Expand Down Expand Up @@ -205,7 +222,8 @@ describe('${name}', () => {
/**
* Convert a dash case string to pascal case.
*/
const toPascalCase = (str: string) => str.split('-').reduce((res, part) => res + part[0].toUpperCase() + part.substr(1), '');
const toPascalCase = (str: string) =>
str.split('-').reduce((res, part) => res + part[0].toUpperCase() + part.substr(1), '');

/**
* Extensions available to generate.
Expand Down
4 changes: 2 additions & 2 deletions src/cli/task-prerender.ts
Expand Up @@ -10,7 +10,7 @@ export const taskPrerender = async (coreCompiler: CoreCompiler, config: Config)

if (typeof hydrateAppFilePath !== 'string') {
config.logger.error(`Missing hydrate app script path`);
config.sys.exit(1);
return config.sys.exit(1);
}

const srcIndexHtmlPath = config.srcIndexHtml;
Expand All @@ -19,7 +19,7 @@ export const taskPrerender = async (coreCompiler: CoreCompiler, config: Config)
config.logger.printDiagnostics(diagnostics);

if (diagnostics.some(d => d.level === 'error')) {
config.sys.exit(1);
return config.sys.exit(1);
}
};

Expand Down
6 changes: 3 additions & 3 deletions src/cli/task-test.ts
Expand Up @@ -4,7 +4,7 @@ import { IS_NODE_ENV } from '../compiler/sys/environment';
export const taskTest = async (config: Config) => {
if (!IS_NODE_ENV) {
config.logger.error(`"test" command is currently only implemented for a NodeJS environment`);
config.sys.exit(1);
return config.sys.exit(1);
}

try {
Expand Down Expand Up @@ -48,10 +48,10 @@ export const taskTest = async (config: Config) => {
await testing.destroy();

if (!passed) {
config.sys.exit(1);
return config.sys.exit(1);
}
} catch (e) {
config.logger.error(e);
config.sys.exit(1);
return config.sys.exit(1);
}
};
10 changes: 8 additions & 2 deletions src/cli/task-watch.ts
Expand Up @@ -44,7 +44,13 @@ export const taskWatch = async (coreCompiler: CoreCompiler, config: Config) => {
if (config.flags.prerender) {
watcher.on('buildFinish', async results => {
if (!results.hasError) {
const prerenderDiagnostics = await runPrerenderTask(coreCompiler, config, results.hydrateAppFilePath, results.componentGraph, null);
const prerenderDiagnostics = await runPrerenderTask(
coreCompiler,
config,
results.hydrateAppFilePath,
results.componentGraph,
null,
);
config.logger.printDiagnostics(prerenderDiagnostics);
}
});
Expand All @@ -64,6 +70,6 @@ export const taskWatch = async (coreCompiler: CoreCompiler, config: Config) => {
}

if (exitCode > 0) {
config.sys.exit(exitCode);
return config.sys.exit(exitCode);
}
};
21 changes: 16 additions & 5 deletions src/compiler/sys/stencil-sys.ts
Expand Up @@ -87,7 +87,11 @@ export const createSystem = (c?: { logger?: Logger }) => {
return results;
};

const createDirRecursiveSync = (p: string, opts: CompilerSystemCreateDirectoryOptions, results: CompilerSystemCreateDirectoryResults) => {
const createDirRecursiveSync = (
p: string,
opts: CompilerSystemCreateDirectoryOptions,
results: CompilerSystemCreateDirectoryResults,
) => {
const parentDir = dirname(p);

if (opts && opts.recursive && !isRootPath(parentDir)) {
Expand Down Expand Up @@ -279,7 +283,11 @@ export const createSystem = (c?: { logger?: Logger }) => {
return results;
};

const remoreDirSyncRecursive = (p: string, opts: CompilerSystemRemoveDirectoryOptions, results: CompilerSystemRemoveDirectoryResults) => {
const remoreDirSyncRecursive = (
p: string,
opts: CompilerSystemRemoveDirectoryOptions,
results: CompilerSystemRemoveDirectoryResults,
) => {
if (!results.error) {
p = normalize(p);

Expand Down Expand Up @@ -515,7 +523,8 @@ export const createSystem = (c?: { logger?: Logger }) => {
return results;
};

const getLocalModulePath = (opts: { rootDir: string; moduleId: string; path: string }) => join(opts.rootDir, 'node_modules', opts.moduleId, opts.path);
const getLocalModulePath = (opts: { rootDir: string; moduleId: string; path: string }) =>
join(opts.rootDir, 'node_modules', opts.moduleId, opts.path);

const getRemoteModuleUrl = (opts: { moduleId: string; path: string; version?: string }) => {
const npmBaseUrl = 'https://cdn.jsdelivr.net/npm/';
Expand All @@ -539,7 +548,7 @@ export const createSystem = (c?: { logger?: Logger }) => {
createDirSync,
destroy,
encodeToBase64,
exit: exitCode => logger.warn(`exit ${exitCode}`),
exit: async exitCode => logger.warn(`exit ${exitCode}`),
getCurrentDirectory,
getCompilerExecutingPath,
getLocalModulePath,
Expand Down Expand Up @@ -571,7 +580,9 @@ export const createSystem = (c?: { logger?: Logger }) => {
writeFile,
writeFileSync,
generateContentHash,
createWorkerController: HAS_WEB_WORKER ? maxConcurrentWorkers => createWebWorkerMainController(sys, maxConcurrentWorkers) : null,
createWorkerController: HAS_WEB_WORKER
? maxConcurrentWorkers => createWebWorkerMainController(sys, maxConcurrentWorkers)
: null,
details: {
cpuModel: '',
freemem: () => 0,
Expand Down
2 changes: 1 addition & 1 deletion src/declarations/stencil-public-compiler.ts
Expand Up @@ -840,7 +840,7 @@ export interface CompilerSystem {
/**
* process.exit()
*/
exit(exitCode: number): void;
exit(exitCode: number): Promise<void>;
/**
* Optionally provide a fetch() function rather than using the built-in fetch().
* First arg is a url string or Request object (RequestInfo).
Expand Down
59 changes: 50 additions & 9 deletions src/sys/deno/deno-sys.ts
Expand Up @@ -8,7 +8,21 @@ import type {
CompilerSystemWriteFileResults,
Diagnostic,
} from '../../declarations';
import { basename, delimiter, dirname, extname, isAbsolute, join, normalize, parse, relative, resolve, sep, win32, posix } from './deps';
import {
basename,
delimiter,
dirname,
extname,
isAbsolute,
join,
normalize,
parse,
relative,
resolve,
sep,
win32,
posix,
} from './deps';
import { convertPathToFileProtocol, isRemoteUrl, normalizePath, catchError, buildError } from '@utils';
import { createDenoWorkerMainController } from './deno-worker-main';
import { denoCopyTasks } from './deno-copy-tasks';
Expand All @@ -27,7 +41,8 @@ export function createDenoSys(c: { Deno?: any } = {}) {
const hardwareConcurrency = 0;
const isRemoteHost = isRemoteUrl(import.meta.url);

const getLocalModulePath = (opts: { rootDir: string; moduleId: string; path: string }) => join(opts.rootDir, 'node_modules', opts.moduleId, opts.path);
const getLocalModulePath = (opts: { rootDir: string; moduleId: string; path: string }) =>
join(opts.rootDir, 'node_modules', opts.moduleId, opts.path);

const getRemoteModuleUrl = (module: { moduleId: string; path: string; version?: string }) => {
const npmBaseUrl = 'https://cdn.jsdelivr.net/npm/';
Expand Down Expand Up @@ -159,13 +174,29 @@ export function createDenoSys(c: { Deno?: any } = {}) {

stencilRemoteUrl = new URL(`../../compiler/stencil.js`, import.meta.url).href;
if (!isRemoteUrl(stencilRemoteUrl)) {
stencilRemoteUrl = sys.getRemoteModuleUrl({ moduleId: stencilDep.name, version: stencilDep.version, path: stencilDep.main });
stencilRemoteUrl = sys.getRemoteModuleUrl({
moduleId: stencilDep.name,
version: stencilDep.version,
path: stencilDep.main,
});
}
stencilBaseUrl = new URL(`../../`, stencilRemoteUrl);
stencilExePath = sys.getLocalModulePath({ rootDir: opts.rootDir, moduleId: stencilDep.name, path: stencilDep.main });
stencilExePath = sys.getLocalModulePath({
rootDir: opts.rootDir,
moduleId: stencilDep.name,
path: stencilDep.main,
});

typescriptRemoteUrl = sys.getRemoteModuleUrl({ moduleId: typescriptDep.name, version: typescriptDep.version, path: typescriptDep.main });
typescriptExePath = sys.getLocalModulePath({ rootDir: opts.rootDir, moduleId: typescriptDep.name, path: typescriptDep.main });
typescriptRemoteUrl = sys.getRemoteModuleUrl({
moduleId: typescriptDep.name,
version: typescriptDep.version,
path: typescriptDep.main,
});
typescriptExePath = sys.getLocalModulePath({
rootDir: opts.rootDir,
moduleId: typescriptDep.name,
path: typescriptDep.main,
});

const ensureStencil = fetchWrite(diagnostics, stencilRemoteUrl, stencilExePath);
const ensureTypescript = fetchWrite(diagnostics, typescriptRemoteUrl, typescriptExePath);
Expand All @@ -188,8 +219,16 @@ export function createDenoSys(c: { Deno?: any } = {}) {

const deps: { url: string; path: string }[] = [];

const stencilPkg = sys.getLocalModulePath({ rootDir: opts.rootDir, moduleId: stencilDep.name, path: 'package.json' });
const typescriptPkg = sys.getLocalModulePath({ rootDir: opts.rootDir, moduleId: typescriptDep.name, path: 'package.json' });
const stencilPkg = sys.getLocalModulePath({
rootDir: opts.rootDir,
moduleId: stencilDep.name,
path: 'package.json',
});
const typescriptPkg = sys.getLocalModulePath({
rootDir: opts.rootDir,
moduleId: typescriptDep.name,
path: 'package.json',
});

const stencilCheck = sys.access(stencilPkg);
const typescriptCheck = sys.access(typescriptPkg);
Expand Down Expand Up @@ -241,7 +280,9 @@ export function createDenoSys(c: { Deno?: any } = {}) {
timespan.finish(`ensure resources end: ${deps.length}`);
}
},
exit: deno.exit,
exit: async exitCode => {
deno.exit(exitCode);
},
getCompilerExecutingPath() {
return stencilExePath;
},
Expand Down

0 comments on commit 208ef8c

Please sign in to comment.