Skip to content

Commit

Permalink
fix(cli): export cli types and runTask, move checkVersion to sys, add…
Browse files Browse the repository at this point in the history
… tests
  • Loading branch information
adamdbradley committed Jul 9, 2020
1 parent 4964ecf commit 02c62b5
Show file tree
Hide file tree
Showing 23 changed files with 375 additions and 212 deletions.
2 changes: 1 addition & 1 deletion bin/stencil
Expand Up @@ -44,7 +44,7 @@ if (typeof globalThis === 'undefined') {
var cli = require('../cli/index.cjs.js');
var nodeApi = require('../sys/node/index.js');
var nodeLogger = nodeApi.createNodeLogger({ process: process });
var nodeSys = nodeApi.createNodeSysWithWatch({ process: process, logger: nodeLogger });
var nodeSys = nodeApi.createNodeSys({ process: process, logger: nodeLogger });

nodeApi.setupNodeProcess({ process: process, logger: nodeLogger });

Expand Down
2 changes: 1 addition & 1 deletion scripts/build.ts
Expand Up @@ -25,7 +25,7 @@ export async function run(rootDir: string, args: string[]) {
}

if (args.includes('--validate-build')) {
validateBuild(rootDir);
await validateBuild(rootDir);
}
} catch (e) {
console.error(e);
Expand Down
23 changes: 21 additions & 2 deletions scripts/bundles/cli.ts
@@ -1,3 +1,4 @@
import fs from 'fs-extra';
import { join } from 'path';
import rollupJson from '@rollup/plugin-json';
import rollupCommonjs from '@rollup/plugin-commonjs';
Expand All @@ -8,23 +9,41 @@ import { relativePathPlugin } from './plugins/relative-path-plugin';
import { BuildOptions } from '../utils/options';
import { RollupOptions, OutputOptions } from 'rollup';
import { prettyMinifyPlugin } from './plugins/pretty-minify';
import { writePkgJson } from '../utils/write-pkg-json';

export async function cli(opts: BuildOptions) {
const inputDir = join(opts.transpiledDir, 'cli');
const outputDir = opts.output.cliDir;
const esmFilename = 'index.js';
const cjsFilename = 'index.cjs.js';
const dtsFilename = 'index.d.ts';

const esOutput: OutputOptions = {
format: 'es',
file: join(outputDir, 'index.js'),
file: join(outputDir, esmFilename),
preferConst: true,
};

const cjsOutput: OutputOptions = {
format: 'cjs',
file: join(outputDir, 'index.cjs.js'),
file: join(outputDir, cjsFilename),
preferConst: true,
};

// create public d.ts
let dts = await fs.readFile(join(inputDir, 'public.d.ts'), 'utf8');
dts = dts.replace('@stencil/core/internal', '../internal/index');
await fs.writeFile(join(opts.output.cliDir, dtsFilename), dts);

// write @stencil/core/compiler/package.json
writePkgJson(opts, opts.output.cliDir, {
name: '@stencil/core/cli',
description: 'Stencil CLI.',
main: cjsFilename,
module: esmFilename,
types: dtsFilename,
});

const cliBundle: RollupOptions = {
input: join(inputDir, 'index.js'),
output: [esOutput, cjsOutput],
Expand Down
17 changes: 16 additions & 1 deletion scripts/bundles/sys-node.ts
Expand Up @@ -9,11 +9,26 @@ import { RollupOptions } from 'rollup';
import { relativePathPlugin } from './plugins/relative-path-plugin';
import { aliasPlugin } from './plugins/alias-plugin';
import { prettyMinifyPlugin } from './plugins/pretty-minify';
import { writePkgJson } from '../utils/write-pkg-json';

export async function sysNode(opts: BuildOptions) {
const inputFile = join(opts.transpiledDir, 'sys', 'node', 'index.js');
const inputDir = join(opts.transpiledDir, 'sys', 'node');
const inputFile = join(inputDir, 'index.js');
const outputFile = join(opts.output.sysNodeDir, 'index.js');

// create public d.ts
let dts = await fs.readFile(join(inputDir, 'public.d.ts'), 'utf8');
dts = dts.replace('@stencil/core/internal', '../../internal/index');
await fs.writeFile(join(opts.output.sysNodeDir, 'index.d.ts'), dts);

// write @stencil/core/compiler/package.json
writePkgJson(opts, opts.output.sysNodeDir, {
name: '@stencil/core/sys/node',
description: 'Stencil Node System.',
main: 'index.js',
types: 'index.d.ts',
});

const sysNodeBundle: RollupOptions = {
input: inputFile,
output: {
Expand Down
55 changes: 53 additions & 2 deletions scripts/test/validate-build.ts
Expand Up @@ -12,6 +12,7 @@ import ts from 'typescript';
const pkgs: TestPackage[] = [
{
// cli
packageJson: 'cli/package.json',
files: ['cli/index.js', 'cli/index.cjs.js'],
},
{
Expand Down Expand Up @@ -77,6 +78,7 @@ const pkgs: TestPackage[] = [
},
{
// sys/node
packageJson: 'sys/node/package.json',
files: ['sys/node/autoprefixer.js', 'sys/node/graceful-fs.js', 'sys/node/node-fetch.js'],
},
{
Expand All @@ -93,16 +95,17 @@ const pkgs: TestPackage[] = [
},
];

export function validateBuild(rootDir: string) {
export async function validateBuild(rootDir: string) {
const dtsEntries: string[] = [];
const opts = getOptions(rootDir);
pkgs.forEach(testPkg => {
validatePackage(opts, testPkg, dtsEntries);
});
console.log(`🐡 Validated packages`);

validateDts(opts, dtsEntries);

console.log(`👾 Validated build files and distribution`);
await validateCompiler(opts);
}

function validatePackage(opts: BuildOptions, testPkg: TestPackage, dtsEntries: string[]) {
Expand Down Expand Up @@ -198,6 +201,54 @@ function validateDts(opts: BuildOptions, dtsEntries: string[]) {
};
throw new Error('🧨 ' + ts.formatDiagnostics(tsDiagnostics, host));
}
console.log(`🐟 Validated dts files`);
}

async function validateCompiler(opts: BuildOptions) {
const compilerPath = join(opts.output.compilerDir, 'stencil.js');
const cliPath = join(opts.output.cliDir, 'index.cjs.js');
const sysNodePath = join(opts.output.sysNodeDir, 'index.js');

const compiler = await import(compilerPath);
const cli = await import(cliPath);
const sysNodeApi = await import(sysNodePath);

const nodeLogger = sysNodeApi.createNodeLogger({ process });
const nodeSys = sysNodeApi.createNodeSys({ process });

if (!nodeSys || nodeSys.name !== 'node' || nodeSys.version.length < 4) {
throw new Error(`🧨 unable to validate sys node`);
}
console.log(`🐳 Validated sys node, current ${nodeSys.name} version: ${nodeSys.version}`);

const validated = await compiler.loadConfig({
config: {
logger: nodeLogger,
sys: nodeSys,
},
});
console.log(`${compiler.vermoji} Validated compiler: ${compiler.version}`);

const transpileResults = compiler.transpileSync('const m: string = `transpile!`;', { target: 'es5' });
if (!transpileResults || transpileResults.diagnostics.length > 0 || !transpileResults.code.startsWith(`var m = "transpile!";`)) {
console.error(transpileResults);
throw new Error(`🧨 transpileSync error`);
}
console.log(`🐋 Validated compiler.transpileSync()`);

const orgConsoleLog = console.log;
let loggedVersion = null;
console.log = (value: string) => (loggedVersion = value);

await cli.runTask(compiler, validated.config, 'version');

console.log = orgConsoleLog;

if (typeof loggedVersion !== 'string' || loggedVersion.length < 4) {
throw new Error(`🧨 unable to validate compiler. loggedVersion: "${loggedVersion}"`);
}

console.log(`🐬 Validated cli`);
}

interface TestPackage {
Expand Down
18 changes: 18 additions & 0 deletions src/cli/check-version.ts
@@ -0,0 +1,18 @@
import type { Config } from '../declarations';
import { isFunction } from '@utils';

export const startCheckVersion = async (config: Config, currentVersion: string) => {
if (config.devMode && !config.flags.ci && isFunction(config.sys.checkVersion)) {
return config.sys.checkVersion(config.logger, currentVersion);
}
return null;
};

export const printCheckVersionResults = async (versionChecker: Promise<() => void>) => {
if (versionChecker) {
const checkVersionResults = await versionChecker;
if (isFunction(checkVersionResults)) {
checkVersionResults();
}
}
};
2 changes: 1 addition & 1 deletion src/cli/index.ts
@@ -1 +1 @@
export { run } from './run';
export { run, runTask } from './run';
26 changes: 16 additions & 10 deletions src/cli/logs.ts
@@ -1,25 +1,31 @@
import type { Config, Logger, ConfigFlags, CompilerSystem } from '../declarations';
import type { Config, Logger, ConfigFlags, CompilerSystem, TaskCommand } from '../declarations';
import type { CoreCompiler } from './load-compiler';
import { version, vermoji } from '../version';

export const startupLog = (logger: Logger, flags: ConfigFlags) => {
if (flags.task === 'info' || flags.task === 'serve') {
export const startupLog = (logger: Logger, task: TaskCommand) => {
if (task === 'info' || task === 'serve' || task === 'version') {
return;
}

const isDevBuild = version.includes('-dev.');
logger.info(logger.cyan(`@stencil/core`));
};

export const startupLogVersion = (logger: Logger, task: TaskCommand, coreCompiler: CoreCompiler) => {
if (task === 'info' || task === 'serve' || task === 'version') {
return;
}
const isDevBuild = coreCompiler.version.includes('-dev.');

let startupMsg = logger.cyan(`@stencil/core`);
let startupMsg: string

if (isDevBuild) {
startupMsg += ' ' + logger.yellow('[LOCAL DEV]');
startupMsg = logger.yellow('[LOCAL DEV]');
} else {
startupMsg += ' ' + logger.cyan(`v${version}`);
startupMsg = logger.cyan(`v${coreCompiler.version}`);
}
startupMsg += logger.emoji(' ' + vermoji);
startupMsg += logger.emoji(' ' + coreCompiler.vermoji);

logger.info(startupMsg);
};
}

export const loadedCompilerLog = (sys: CompilerSystem, logger: Logger, flags: ConfigFlags, coreCompiler: CoreCompiler) => {
const sysDetails = sys.details;
Expand Down
17 changes: 17 additions & 0 deletions src/cli/public.ts
@@ -0,0 +1,17 @@
import { CliInitOptions, CompilerSystem, Config, ConfigFlags, Logger, TaskCommand } from '@stencil/core/internal';

/**
* Runs the CLI with the given options. This is used by Stencil's default `bin/stencil` file,
* but can be used externally too.
*/
export declare function run(init: CliInitOptions): Promise<void>;

/**
* Run individual CLI tasks.
* @param coreCompiler The core Stencil compiler to be used. The `run()` method handles loading the core compiler, however, `runTask()` must be passed it.
* @param config Assumes the config has already been validated and has the "sys" and "logger" properties.
* @param task The task command to run, such as `build`.
*/
export declare function runTask(coreCompiler: any, config: Config, task: TaskCommand): Promise<void>;

export { CompilerSystem, Config, ConfigFlags, Logger, TaskCommand };

0 comments on commit 02c62b5

Please sign in to comment.