packages/cli: added app:diff + fixes to template and diff lib
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2020 Spotify AB
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { Command } from 'commander';
|
||||
import {
|
||||
diffTemplateFiles,
|
||||
handlers,
|
||||
handleAllFiles,
|
||||
inquirerPromptFunc,
|
||||
makeCheckPromptFunc,
|
||||
yesPromptFunc,
|
||||
} from '../../lib/diff';
|
||||
import { version } from '../../lib/version';
|
||||
|
||||
const fileHandlers = [
|
||||
{
|
||||
patterns: ['packages/app/package.json'],
|
||||
handler: handlers.appPackageJson,
|
||||
},
|
||||
{
|
||||
patterns: [/tsconfig\.json$/],
|
||||
handler: handlers.exactMatch,
|
||||
},
|
||||
{
|
||||
patterns: [
|
||||
/README\.md$/,
|
||||
/\.eslintrc\.js$/,
|
||||
// make sure files in 1st level of src/ and dev/ exist
|
||||
/^packages\/app\/(src|dev)\/[^/]+$/,
|
||||
],
|
||||
handler: handlers.exists,
|
||||
},
|
||||
{
|
||||
patterns: [
|
||||
'lerna.json',
|
||||
/^src\//,
|
||||
/^patches\//,
|
||||
/^packages\/app\/public\//,
|
||||
/^packages\/app\/cypress/,
|
||||
// Let plugin:diff take care of the plugins
|
||||
/^plugins/,
|
||||
/package\.json$/,
|
||||
],
|
||||
handler: handlers.skip,
|
||||
},
|
||||
];
|
||||
|
||||
export default async (cmd: Command) => {
|
||||
let promptFunc = inquirerPromptFunc;
|
||||
let finalize = () => {};
|
||||
|
||||
if (cmd.check) {
|
||||
[promptFunc, finalize] = makeCheckPromptFunc();
|
||||
} else if (cmd.yes) {
|
||||
promptFunc = yesPromptFunc;
|
||||
}
|
||||
|
||||
const templateFiles = await diffTemplateFiles('default-app', { version });
|
||||
await handleAllFiles(fileHandlers, templateFiles, promptFunc);
|
||||
await finalize();
|
||||
};
|
||||
@@ -39,6 +39,13 @@ const main = (argv: string[]) => {
|
||||
.option('--check', 'Enable type checking and linting')
|
||||
.action(actionHandler(() => require('./commands/app/serve')));
|
||||
|
||||
program
|
||||
.command('app:diff')
|
||||
.option('--check', 'Fail if changes are required')
|
||||
.option('--yes', 'Apply all changes')
|
||||
.description('Diff an existing app with the creation template')
|
||||
.action(actionHandler(() => require('./commands/app/diff')));
|
||||
|
||||
program
|
||||
.command('create-plugin')
|
||||
.description('Creates a new plugin in the current repository')
|
||||
@@ -157,7 +164,7 @@ function actionHandler<T extends readonly any[]>(
|
||||
};
|
||||
}
|
||||
|
||||
process.on('unhandledRejection', (rejection) => {
|
||||
process.on('unhandledRejection', rejection => {
|
||||
if (rejection instanceof Error) {
|
||||
exitWithError(rejection);
|
||||
} else {
|
||||
|
||||
@@ -22,6 +22,7 @@ class PackageJsonHandler {
|
||||
static async handler(
|
||||
{ path, write, missing, targetContents, templateContents }: FileDiff,
|
||||
prompt: PromptFunc,
|
||||
variant?: string,
|
||||
) {
|
||||
console.log('Checking package.json');
|
||||
|
||||
@@ -32,19 +33,33 @@ class PackageJsonHandler {
|
||||
const pkg = JSON.parse(templateContents);
|
||||
const targetPkg = JSON.parse(targetContents);
|
||||
|
||||
const handler = new PackageJsonHandler(write, prompt, pkg, targetPkg);
|
||||
const handler = new PackageJsonHandler(
|
||||
write,
|
||||
prompt,
|
||||
pkg,
|
||||
targetPkg,
|
||||
variant,
|
||||
);
|
||||
await handler.handle();
|
||||
}
|
||||
|
||||
static async appHandler(file: FileDiff, prompt: PromptFunc) {
|
||||
return PackageJsonHandler.handler(file, prompt, 'app');
|
||||
}
|
||||
|
||||
constructor(
|
||||
private readonly writeFunc: WriteFileFunc,
|
||||
private readonly prompt: PromptFunc,
|
||||
private readonly pkg: any,
|
||||
private readonly targetPkg: any,
|
||||
private readonly variant?: string,
|
||||
) {}
|
||||
|
||||
async handle() {
|
||||
await this.syncField('main');
|
||||
if (this.variant !== 'app') {
|
||||
await this.syncField('main:src');
|
||||
}
|
||||
await this.syncField('types');
|
||||
await this.syncField('files');
|
||||
await this.syncScripts();
|
||||
@@ -78,7 +93,7 @@ class PackageJsonHandler {
|
||||
targetObj[fieldName] = newValue;
|
||||
await this.write();
|
||||
}
|
||||
} else {
|
||||
} else if (fieldName in obj) {
|
||||
if (
|
||||
await this.prompt(
|
||||
`package.json is missing field ${fullFieldName}, set to ${coloredNewValue}?`,
|
||||
@@ -95,6 +110,10 @@ class PackageJsonHandler {
|
||||
const targetScripts = (this.targetPkg.scripts =
|
||||
this.targetPkg.scripts || {});
|
||||
|
||||
if (!pkgScripts) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const key of Object.keys(pkgScripts)) {
|
||||
await this.syncField(key, pkgScripts, targetScripts, 'scripts');
|
||||
}
|
||||
@@ -132,7 +151,14 @@ class PackageJsonHandler {
|
||||
const targetDeps = (this.targetPkg[fieldName] =
|
||||
this.targetPkg[fieldName] || {});
|
||||
|
||||
if (!pkgDeps) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const key of Object.keys(pkgDeps)) {
|
||||
if (this.variant === 'app' && key.startsWith('plugin-')) {
|
||||
continue;
|
||||
}
|
||||
await this.syncField(key, pkgDeps, targetDeps, fieldName);
|
||||
}
|
||||
}
|
||||
@@ -206,6 +232,7 @@ export const handlers = {
|
||||
exists: existsHandler,
|
||||
exactMatch: exactMatchHandler,
|
||||
packageJson: PackageJsonHandler.handler,
|
||||
appPackageJson: PackageJsonHandler.appHandler,
|
||||
};
|
||||
|
||||
export async function handleAllFiles(
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"extends": "@spotify/web-scripts/config/tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"target": "es5",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"esModuleInterop": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"strict": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "react",
|
||||
"incremental": false
|
||||
},
|
||||
"include": ["src"]
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
{
|
||||
"extends": "../../tsconfig.json",
|
||||
"include": ["src"],
|
||||
"compilerOptions": {}
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
module.exports = require('@spotify/web-scripts/config/prettier.config.js');
|
||||
Reference in New Issue
Block a user