ADF CLI fixes (#5674)

* safety checks and better path eval

* do not execute command on help

* rewrite 'update-version' command
This commit is contained in:
Denys Vuika 2020-05-06 11:18:38 +01:00 committed by GitHub
parent 2db9fb0aa9
commit 94e2e83e73
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 195 additions and 138 deletions

View File

@ -1,24 +1,47 @@
# Alfresco ADF Cli # Alfresco ADF Cli
The ADF CLI provides a set of utilities to manage your ADF projects.
## The Goal of ADF CLI
The ADF CLI manages, builds , doc and test your ADF Application projects.
## Installation ## Installation
To get started follow these instructions: To get started follow these instructions:
`` ```bash
npm install @alfresco/adf-cli -g npm install @alfresco/adf-cli -g
`` ```
To know more about any command use the -h or --help option To know more about any command use the -h or --help option:
```bash
adf-cli <command> --help
```
## Developing
Link the project as a global tool
```bash
npm link
```
Build the tool in the **develop** mode (automatically watches for changes and rebuilds the commands):
```bash
npm run develop
```
Run the tool with the `DEVELOP` environment variable:
```bash
DEVELOP=true adf-cli <command>
```
In develop mode, the CLI takes the prebuilt scripts from the dist folder.
## Commands ## Commands
|**Commands** |**Description** | | **Commands** |**Description** |
|--- |--- | |--- |--- |
|artifact-from-s3 |Get artifact from S3 | |artifact-from-s3 |Get artifact from S3 |
|artifact-to-s3 |Get artifact to S3 | |artifact-to-s3 |Get artifact to S3 |
|docker-publish |publish docker image| |docker-publish |publish docker image|
@ -26,26 +49,26 @@ To know more about any command use the -h or --help option
|kubectl-delete |delete kubectl | |kubectl-delete |delete kubectl |
|kubectl-image |This command allows you to update a specific service on the rancher env with a specifig tag | |kubectl-image |This command allows you to update a specific service on the rancher env with a specifig tag |
|npm-publish | publish on npm | |npm-publish | publish on npm |
| update-commit-sha | his command allows you to update the commit sha as part of the package.json. Your package.json must to have an existing property called "commit" | | update-commit-sha | his command allows you to update the commit sha as part of the `package.json`. Your `package.json` must to have an existing property called "commit" |
|update-version |This command allows you to update the adf dependencies and js-api with different versions Update adf libs and js-api with latest alpha| |update-version |This command allows you to update the adf dependencies and js-api with different versions Update adf libs and js-api with latest alpha|
|adf-license |Create a 3th party license file | |adf-license |Create a 3th party license file |
|adf-audit |Check the security risk dependency in your package.json | |adf-audit |Check the security risk dependency in your package.json |
## Examples ## Examples
### License Check ### License Check
Move in the folder where you have your package.json and run the command: Move in the folder where you have your `package.json` and run the command:
```bash ```bash
npm install npm install
adf-license adf-license
``` ```
### Audit Check ### Audit Check
Move in the folder where you have your package.json and run the command: Move in the folder where you have your `package.json` and run the command:
```bash ```bash
npm install npm install
@ -55,7 +78,7 @@ adf-audit
### Docker publish ### Docker publish
Move in the folder where you have your Dockerfile and run the command: Move in the folder where you have your `Dockerfile` and run the command:
```bash ```bash
adf-cli docker-publish --dockerRepo "${docker_repository}" --dockerTags "${TAGS}" --pathProject "$(pwd)" adf-cli docker-publish --dockerRepo "${docker_repository}" --dockerTags "${TAGS}" --pathProject "$(pwd)"
@ -68,7 +91,7 @@ If you want to specify a different docker registry you can run
### Kubectl update pod image ### Kubectl update pod image
This command allows you to update a specific service on the rancher env with a specifig tag This command allows you to update a specific service on the rancher env with a specific tag
```bash ```bash
adf-cli kubectl-image --clusterEnv ${clusterEnv} --clusterUrl ${clusterUrl} --username ${username} --token ${token} --deployName ${deployName} --dockerRepo ${dockerRepo} --tag ${tag} adf-cli kubectl-image --clusterEnv ${clusterEnv} --clusterUrl ${clusterUrl} --username ${username} --token ${token} --deployName ${deployName} --dockerRepo ${dockerRepo} --tag ${tag}
@ -118,8 +141,8 @@ adf-cli update-version --alpha --pathPackage "$(pwd)" --skipGnu
### Update commit sha ### Update commit sha
This command allows you to update the commit sha as part of the package.json. This command allows you to update the commit sha as part of the `package.json`.
Your package.json must to have an existing property called "commit" Your `package.json` must to have an existing property called "commit"
```bash ```bash
adf-cli update-commit-sha --pathProject "$(pwd)" adf-cli update-commit-sha --pathProject "$(pwd)"
@ -145,7 +168,8 @@ adf-cli init-aae-env --host "gateway_env" --oauth "identity_env" --identityHost
``` ```
If you want to add a new app the schema needs to be: If you want to add a new app the schema needs to be:
```
```text
TEST_APP: { TEST_APP: {
        name: 'testapp',         name: 'testapp',
        file_location: 'https://github.com/Alfresco/alfresco-ng2-components/blob/branch/e2e/resources/testapp.zip?raw=true',         file_location: 'https://github.com/Alfresco/alfresco-ng2-components/blob/branch/e2e/resources/testapp.zip?raw=true',

View File

@ -1,16 +1,30 @@
#!/usr/bin/env node #!/usr/bin/env node
// tslint:disable: adf-file-name
// tslint:disable: no-var-requires
const minimist = require('minimist'); const minimist = require('minimist');
const path = require('path'); const path = require('path');
const fs = require('fs');
const args = minimist(process.argv.slice(2), { const args = minimist(process.argv.slice(2), {
boolean: ['verbose'] boolean: ['verbose']
}); });
if (args._.length === 0) {
console.error('Error: no commands provided');
process.exit(1);
}
const scriptName = args._.shift(); const scriptName = args._.shift();
const scriptPath = path.join('../scripts', scriptName); const scriptPath = process.env.DEVELOP
? path.resolve(path.join(__dirname, '../dist/scripts', scriptName))
: path.resolve(path.join(__dirname, '../scripts', scriptName));
if (!fs.existsSync(`${scriptPath}.js`)) {
console.error(`Error: command ${scriptName} not found.`);
process.exit(1);
}
const cwd = process.cwd(); const cwd = process.cwd();
process.chdir(path.join(__dirname, '..'));
try { try {
Promise.resolve() Promise.resolve()

View File

@ -1,9 +1,17 @@
{ {
"name": "@alfresco/adf-cli", "name": "@alfresco/adf-cli",
"version": "3.5.0", "version": "3.8.0",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
"@alfresco/adf-testing": {
"version": "3.8.0",
"resolved": "https://registry.npmjs.org/@alfresco/adf-testing/-/adf-testing-3.8.0.tgz",
"integrity": "sha512-feinvQ62LLpIHca7SnCc6mRK2vhGeK8w+VCmSZlHkcf97YF+nou0JuFi/CQ6aAWWfaQtNZrm9VjXEeUUvh1s1Q==",
"requires": {
"tslib": "^1.9.0"
}
},
"@angular-devkit/core": { "@angular-devkit/core": {
"version": "7.3.9", "version": "7.3.9",
"resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.3.9.tgz", "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-7.3.9.tgz",
@ -353,6 +361,45 @@
} }
} }
}, },
"@types/events": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
"integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==",
"dev": true
},
"@types/glob": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz",
"integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==",
"dev": true,
"requires": {
"@types/events": "*",
"@types/minimatch": "*",
"@types/node": "*"
}
},
"@types/minimatch": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
"integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
"dev": true
},
"@types/node": {
"version": "13.13.4",
"resolved": "https://registry.npmjs.org/@types/node/-/node-13.13.4.tgz",
"integrity": "sha512-x26ur3dSXgv5AwKS0lNfbjpCakGIduWU1DU91Zz58ONRWrIKGunmZBNv4P7N+e27sJkiGDsw/3fT4AtsqQBrBA==",
"dev": true
},
"@types/shelljs": {
"version": "0.8.7",
"resolved": "https://registry.npmjs.org/@types/shelljs/-/shelljs-0.8.7.tgz",
"integrity": "sha512-Mg2qGjLIJIieeJ1/NjswAOY9qXDShLeh6JwpD1NZsvUvI0hxdUCNDpnBXv9YQeugKi2EHU+BqkbUE4jpY4GKmQ==",
"dev": true,
"requires": {
"@types/glob": "*",
"@types/node": "*"
}
},
"JSONStream": { "JSONStream": {
"version": "1.3.5", "version": "1.3.5",
"resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz",

View File

@ -16,8 +16,9 @@
"url": "https://github.com/Alfresco/alfresco-ng2-components/issues" "url": "https://github.com/Alfresco/alfresco-ng2-components/issues"
}, },
"scripts": { "scripts": {
"build-tsc": "tsc -p tsconfig.json", "build": "tsc -p tsconfig.json",
"dist": "rm -rf ./dist/ && npm run build-tsc && cp -R ./bin ./dist/ && cp ./package.json ./dist/" "develop": "tsc -p tsconfig.json --watch",
"dist": "rm -rf ./dist/ && npm run build && cp -R ./bin ./dist/ && cp ./package.json ./dist/"
}, },
"dependencies": { "dependencies": {
"commander": "^4.0.0", "commander": "^4.0.0",
@ -33,5 +34,8 @@
"keywords": [ "keywords": [
"alfresco-component" "alfresco-component"
], ],
"license": "Apache-2.0" "license": "Apache-2.0",
"devDependencies": {
"@types/shelljs": "^0.8.7"
}
} }

View File

@ -52,6 +52,7 @@ function main() {
if (process.argv.includes('-h') || process.argv.includes('--help')) { if (process.argv.includes('-h') || process.argv.includes('--help')) {
program.outputHelp(); program.outputHelp();
return;
} }
if (!program.artifact || program.artifact === '' || !program.output || program.output === '') { if (!program.artifact || program.artifact === '' || !program.output || program.output === '') {

View File

@ -48,6 +48,7 @@ function main() {
if (process.argv.includes('-h') || process.argv.includes('--help')) { if (process.argv.includes('-h') || process.argv.includes('--help')) {
program.outputHelp(); program.outputHelp();
return;
} }
if (!program.artifact || program.artifact === '' || !program.output || program.output === '') { if (!program.artifact || program.artifact === '' || !program.output || program.output === '') {

View File

@ -83,6 +83,7 @@ function main(args) {
if (process.argv.includes('-h') || process.argv.includes('--help')) { if (process.argv.includes('-h') || process.argv.includes('--help')) {
program.outputHelp(); program.outputHelp();
return;
} }
if (args.loginCheck === true) { if (args.loginCheck === true) {

View File

@ -302,6 +302,7 @@ async function main(args: ConfigArgs) {
if (process.argv.includes('-h') || process.argv.includes('--help')) { if (process.argv.includes('-h') || process.argv.includes('--help')) {
program.outputHelp(); program.outputHelp();
return;
} }
await initConfiguration(args); await initConfiguration(args);

View File

@ -278,6 +278,7 @@ async function main(args) {
if (process.argv.includes('-h') || process.argv.includes('--help')) { if (process.argv.includes('-h') || process.argv.includes('--help')) {
program.outputHelp(); program.outputHelp();
return;
} }
const configModeler = getAlfrescoJsApiInstance(args); const configModeler = getAlfrescoJsApiInstance(args);

View File

@ -77,6 +77,7 @@ function main(args) {
if (process.argv.includes('-h') || process.argv.includes('--help')) { if (process.argv.includes('-h') || process.argv.includes('--help')) {
program.outputHelp(); program.outputHelp();
return;
} }
if (args.label !== undefined) { if (args.label !== undefined) {

View File

@ -92,6 +92,7 @@ function main(args) {
if (process.argv.includes('-h') || process.argv.includes('--help')) { if (process.argv.includes('-h') || process.argv.includes('--help')) {
program.outputHelp(); program.outputHelp();
return;
} }
if (args.installCheck === true) { if (args.installCheck === true) {

View File

@ -115,6 +115,7 @@ async function main(args) {
if (process.argv.includes('-h') || process.argv.includes('--help')) { if (process.argv.includes('-h') || process.argv.includes('--help')) {
program.outputHelp(); program.outputHelp();
return;
} }
for (let i = 0; i < projects.length; i++) { for (let i = 0; i < projects.length; i++) {

View File

@ -66,6 +66,7 @@ function main(args) {
if (process.argv.includes('-h') || process.argv.includes('--help')) { if (process.argv.includes('-h') || process.argv.includes('--help')) {
program.outputHelp(); program.outputHelp();
return;
} }
const sha = getSha(args); const sha = getSha(args);

View File

@ -17,9 +17,10 @@
* limitations under the License. * limitations under the License.
*/ */
import { exec } from './exec';
import * as program from 'commander'; import * as program from 'commander';
import { logger } from './logger'; import * as path from 'path';
import * as fs from 'fs';
import * as shell from 'shelljs';
export interface UpdateArgs { export interface UpdateArgs {
pathPackage: string; pathPackage: string;
@ -28,140 +29,98 @@ export interface UpdateArgs {
beta?: boolean; beta?: boolean;
version: string; version: string;
vjs: string; vjs: string;
skipGnu: boolean;
} }
const ALPHA = 'alpha'; export interface PackageInfo {
const BETA = 'beta'; dependencies?: string[];
const LATEST = 'latest'; devDependencies?: string[];
const ADF_LIBS_PREFIX = '\"@alfresco/adf-[^"]*\":';
const JS_API_DEPENDENCY = '@alfresco/js-api';
let projects = [''];
function latestPerform(args: UpdateArgs) {
tagPerform(args, LATEST);
} }
function versionPerform(args: UpdateArgs) { function parseAlfrescoLibs(workingDir: string): PackageInfo {
updateLibsVersionPerform(args.pathPackage, args.version, args.skipGnu); const packagePath = path.resolve(path.join(workingDir, 'package.json'));
let dependencies: string[] = [];
let devDependencies: string[] = [];
if (fs.existsSync(packagePath)) {
const json = require(packagePath);
const isAlfrescoLib = (key: string) => key.startsWith('@alfresco');
dependencies = Object.keys((json.dependencies || [])).filter(isAlfrescoLib);
devDependencies = Object.keys((json.devDependencies || [])).filter(isAlfrescoLib);
}
return {
dependencies,
devDependencies
};
} }
function versionJsPerform(args: UpdateArgs) { function formatNpmCommand(deps: string[], tag: string): string {
updateJsAPIVersionPerform(args.pathPackage, args.vjs, args.skipGnu); return [
'npm i -E',
deps.map(name => `${name}@${tag}`).join(' ')
].join(' ');
} }
function alphaPerform(args: UpdateArgs) { function runNpmCommand(command: string, workingDir: string) {
tagPerform(args, ALPHA); if (shell.exec(command, { cwd: workingDir }).code !== 0) {
} shell.echo('Error running NPM command');
shell.exit(1);
function betaPerform(args: UpdateArgs) {
tagPerform(args, BETA);
}
function findADFLibsDependencies(args: UpdateArgs) {
const prjs: any = [];
const result = exec('grep', [`${ADF_LIBS_PREFIX}`, `${args.pathPackage}/package.json`], {}).trim();
const res = result.replace(/,\s*$/, '').split(',');
res.forEach( (dependecy) => {
const dep = dependecy.split(':');
const depName = dep[0].trim();
prjs.push(depName.replace(/"/g, ''));
});
return prjs;
}
function getLatestVersionFromNpm(tag: string, project: string): string {
logger.info(`====== Auto find latest ${tag} version of ${project}`);
const latestVersion = exec('npm', ['view', `${project}@${tag}`, `version`], {}).trim();
logger.info(`====== version lib ${latestVersion} =====`);
return latestVersion;
}
function updateLibsVersionPerform(path: string, version: string, skipGnu = false) {
logger.info('Perform libs version...');
projects.forEach( (project) => {
logger.info(`apply version ${version} on ${project} ...`);
project = project.replace('/', '\\/');
replaceVersionPerform(project, version, path, skipGnu);
});
}
function updateJsAPIVersionPerform(path: string, version: string, skipGnu = false) {
logger.info('Perform js-api version...');
logger.info(`apply version ${version} on ${JS_API_DEPENDENCY} ...`);
const project = JS_API_DEPENDENCY.replace('/', '\\/');
replaceVersionPerform(project, version, path, skipGnu);
}
function replaceVersionPerform(project: string, version: string, path: string, skipGnu = false) {
const rule = `s/\"${project}\": \".*\"/\"${project}\": \"${version}\"/g`;
if (skipGnu) {
exec('sed', ['-i', '', `${rule}`, `${path}/package.json`], {}).trim();
} else {
exec('sed', ['-i', `${rule}`, `${path}/package.json`], {}).trim();
} }
} }
function tagPerform(args: UpdateArgs, tag: string) { function updateLibs(pkg: PackageInfo, tag: string, workingDir: string) {
logger.info(`Perform ${tag} update...`); if (pkg.dependencies && pkg.dependencies.length > 0) {
tagLibPerform(args, tag); runNpmCommand(
tagJsPerform(args, tag); formatNpmCommand(pkg.dependencies, tag),
workingDir
);
}
if (pkg.devDependencies && pkg.devDependencies.length > 0) {
runNpmCommand(
formatNpmCommand(pkg.devDependencies, tag) + ' -D',
workingDir
);
}
} }
function tagLibPerform(args: UpdateArgs, tag: string) { function parseTag(args: UpdateArgs): string {
const libVersion = getLatestVersionFromNpm(tag, '@alfresco/adf-extensions'); if (args.alpha) {
updateLibsVersionPerform(args.pathPackage, libVersion, args.skipGnu); return 'alpha';
}
if (args.beta) {
return 'beta';
}
return args.version || 'latest';
} }
function tagJsPerform(args: UpdateArgs, tag: string) { export default function main(args: UpdateArgs, workingDir: string) {
const jsApiVersion = getLatestVersionFromNpm(tag, JS_API_DEPENDENCY);
updateJsAPIVersionPerform(args.pathPackage, jsApiVersion, args.skipGnu);
}
export default function (args: UpdateArgs) {
main(args);
}
function main(args) {
program program
.version('0.1.0', '-vers')
.description('This command allows you to update the adf dependencies and js-api with different versions\n\n' + .description('This command allows you to update the adf dependencies and js-api with different versions\n\n' +
'Update adf libs and js-api with latest alpha\n\n' + 'Update adf libs and js-api with latest alpha\n\n' +
'adf-cli update-version --alpha --pathPackage "$(pwd)"') 'adf-cli update-version --alpha')
.option('--pathPackage [type]', 'pathPackage') .option('--pathPackage [dir]', 'Directory that contains package.json file', 'current directory')
.option('--alpha [type]', 'use alpha') .option('--alpha', 'use alpha')
.option('--beta [type]', 'use beta') .option('--beta', 'use beta')
.option('--version [type]', 'use version') .option('--version [tag]', 'use specific version can be also alpha/beta/latest', 'latest')
.option('--vjs [type]', 'vjs use version js api') .option('--vjs [tag]', 'Upgrade only JS-API to a specific version')
.option('--skipGnu [type]', 'skipGnu')
.parse(process.argv); .parse(process.argv);
if (process.argv.includes('-h') || process.argv.includes('--help')) { if (process.argv.includes('-h') || process.argv.includes('--help')) {
program.outputHelp(); program.outputHelp();
return;
} }
projects = findADFLibsDependencies(args); workingDir = args.pathPackage || workingDir;
if (args.version) { const tag = args.vjs || parseTag(args);
versionPerform(args); const pkg = args.vjs
} ? { dependencies: ['@alfresco/js-api'] }
: parseAlfrescoLibs(workingDir);
if (args.vjs) {
versionJsPerform(args);
}
if (args.latest === true) {
latestPerform(args);
}
if (args.alpha === true) {
alphaPerform(args);
}
if (args.beta === true) {
betaPerform(args);
}
updateLibs(pkg, tag, workingDir);
} }