vscode-dev-containers/build/vscdc

300 строки
12 KiB
JavaScript
Executable File

#!/usr/bin/env node
/*--------------------------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See https://go.microsoft.com/fwlink/?linkid=2090316 for license information.
*-------------------------------------------------------------------------------------------------------------*/
const push = require('./src/push').push;
const patch = require('./src/patch');
const package = require('./src/package').package;
const prep = require('./src/prep');
const generateComponentGovernanceManifest = require('./src/cgmanifest').generateComponentGovernanceManifest;
const configUtils = require('./src/utils/config');
const packageJson = require('../package.json');
console.log('vscode-dev-containers CLI\nCopyright (c) Microsoft Corporation. All rights reserved.\n')
require('yargs')
.command('pack', 'package dev container definitions', (yargs) => {
yargs
.options({
'release': {
describe: 'vscode-dev-containers release tag or a branch',
default: `v${packageJson.version}`
},
'registry': {
describe: 'container registry to push images to',
default: configUtils.getConfig('containerRegistry', 'docker.io')
},
'registry-path': {
describe: 'container registry path',
default: configUtils.getConfig('containerRegistryPath', 'vscode/devcontainers')
},
'stub-registry': {
describe: 'registry to add to stub',
default: configUtils.getConfig('stubRegistry',
configUtils.getConfig('containerRegistry', 'docker.io'))
},
'stub-registry-path': {
describe: 'stub registry path',
default: configUtils.getConfig('stubRegistryPath',
configUtils.getConfig('containerRegistryPath', ''))
},
'github-repo': {
describe: 'vscode-dev-containers repo name',
default: configUtils.getConfig('githubRepoName', 'microsoft/vscode-dev-containers')
},
'package-only': {
describe: 'whether to prep/build/push before packaging',
type: 'boolean',
default: false
},
'prep-and-package-only': {
describe: 'prep and package, but do not build/push',
type: 'boolean',
default: false
},
'update-latest': {
describe: 'whether to tag latest and {MAJOR}',
type: 'boolean',
default: true
},
'clean': {
describe: 'whether to clean up staging folder when done',
type: 'boolean',
default: true
},
'skip-push': {
describe: 'A space separated list of definition IDs to skip build and push.',
type: 'array',
default: []
}
})
}, packCommand)
.command('push [devcontainer]', 'push dev container images to a repository', (yargs) => {
yargs
.positional('devcontainer', {
describe: 'ID of dev container to push',
default: null
})
.options({
'release': {
describe: 'vscode-dev-containers release tag or branch',
default: `v${packageJson.version}`
},
'registry': {
describe: 'container registry to push images to',
default: configUtils.getConfig('containerRegistry', 'docker.io')
},
'registry-path': {
describe: 'container registry path',
default: configUtils.getConfig('containerRegistryPath', '')
},
'stub-registry': {
describe: 'registry to add to stub',
default: configUtils.getConfig('stubRegistry',
configUtils.getConfig('containerRegistry', 'docker.io'))
},
'stub-registry-path': {
describe: 'stub registry path',
default: configUtils.getConfig('stubRegistryPath',
configUtils.getConfig('containerRegistryPath', ''))
},
'github-repo': {
describe: 'vscode-dev-containers repo name',
default: configUtils.getConfig('githubRepoName', 'microsoft/vscode-dev-containers')
},
'update-latest': {
describe: 'whether to tag latest and {MAJOR} if pushing',
type: 'boolean',
default: true
},
'prep-only': {
describe: 'prep the containers for build/push, but do not actually do it',
type: 'boolean',
default: false
},
'push': {
describe: 'whether to push after prep/build',
type: 'boolean',
default: true
},
'page': {
describe: 'Page number (of total) to push',
type: 'integer',
default: 1
},
'page-total': {
describe: 'Total number of pages to use when parallelizing builds',
type: 'integer',
default: 1
},
'replace-images': {
describe: 'Whether to replace released images. Does not apply to dev tag.',
type: 'boolean',
default: false
},
'skip': {
describe: 'A space separated list of definition IDs to skip building and pushing.',
type: 'array',
default: []
}
})
}, pushCommand)
.command('update-script-sources <release>', 'updates all script source URLs in Dockerfiles to a tag or branch', (yargs) => {
yargs
.positional('release', {
describe: 'release tag to branch use for script URLs',
})
.options({
'github-repo': {
describe: 'vscode-dev-containers repo name',
default: configUtils.getConfig('githubRepoName', 'microsoft/vscode-dev-containers')
},
'update-sha': {
describe: 'update script SHAs to match file',
type: 'boolean',
default: true
}
})
}, updateScriptSourcesCommand)
.command('cg [devcontainer]', 'generate cgmanifest.json', (yargs) => {
yargs
.positional('devcontainer', {
describe: 'limits manifest generation to single definition',
default: null
})
.options({
'release': {
describe: 'vscode-dev-containers release tag or branch',
default: 'master'
},
'registry': {
describe: 'container registry to push images to',
default: configUtils.getConfig('containerRegistry', 'docker.io')
},
'registry-path': {
describe: 'container registry path',
default: configUtils.getConfig('containerRegistryPath', '')
},
'github-repo': {
describe: 'vscode-dev-containers repo name',
default: configUtils.getConfig('githubRepoName', 'microsoft/vscode-dev-containers')
},
'build': {
describe: 'whether to to build the image first step',
default: true
},
'prune': {
describe: 'whether to prune images between definitions',
default: false
}
})
}, cgCommand)
.command('patch', 'patch existing images', (yargs) => {
yargs
.options({
'all': {
describe: 'run all patches not already complete',
type: 'boolean',
default: false
},
'patch-path': {
describe: 'path to the folder containing the patch files',
default: '.'
},
'registry': {
describe: 'container registry to push images to',
default: configUtils.getConfig('containerRegistry', 'docker.io')
},
'registry-path': {
describe: 'container registry path',
default: configUtils.getConfig('containerRegistryPath', '')
}
})
}, patchCommand)
.command('copy-library-scripts', 'copy files from script-library folder into appropriate definitions', () => {}, copyLibraryScriptsCommand)
.demandCommand()
.help()
.argv;
function pushCommand(argv) {
push(argv.githubRepo, argv.release, argv.updateLatest, argv.registry, argv.registryPath, argv.stubRegistry,
argv.stubRegistryPath, argv.push, argv.prepOnly, argv.skip, argv.page, argv.pageTotal, argv.replaceImages, argv.devcontainer)
.catch((reason) => {
console.error(`(!) Push failed - ${reason}`);
if(reason.stack) {
console.error(` ${reason.stack}`);
}
process.exit(1);
});
}
function packCommand(argv) {
package(argv.githubRepo, argv.release, argv.updateLatest, argv.registry, argv.registryPath,
argv.stubRegistry, argv.stubRegistryPath, argv.prepAndPackageOnly, argv.packageOnly, argv.clean, argv.skipPush)
.catch((reason) => {
console.error(`(!) Packaging failed - ${reason}`);
if(reason.stack) {
console.error(` ${reason.stack}`);
}
process.exit(1);
});
}
function updateScriptSourcesCommand(argv) {
prep.updateAllScriptSourcesInRepo(argv.githubRepo, argv.release, argv.updateSha)
.catch((reason) => {
console.error(`(!) Failed to update script sources - ${reason}`);
if(reason.stack) {
console.error(` ${reason.stack}`);
}
process.exit(1);
});
}
function copyLibraryScriptsCommand() {
prep.copyLibraryScriptsForAllDefinitions()
.catch((reason) => {
console.error(`(!) Failed to copy library scripts to definitions - ${reason}`);
if(reason.stack) {
console.error(` ${reason.stack}`);
}
process.exit(1);
});
}
function cgCommand(argv) {
generateComponentGovernanceManifest(argv.githubRepo, argv.release, argv.registry, argv.registryPath, argv.build, argv.prune, argv.devcontainer)
.catch((reason) => {
console.error(`(!) Component governance manifest generation failed - ${reason}`);
if(reason.stack) {
console.error(` ${reason.stack}`);
}
process.exit(1);
});
}
function patchCommand(argv) {
if (argv.all) {
patch.patchAll(argv.registry, argv.registryPath)
.catch((reason) => {
console.error(`(!) Patching failed - ${reason}`);
if(reason.stack) {
console.error(` ${reason.stack}`);
}
process.exit(1);
});
} else {
patch.patch(argv.patchPath, argv.registry, argv.registryPath)
.catch((reason) => {
console.error(`(!) Patching failed - ${reason}`);
if(reason.stack) {
console.error(` ${reason.stack}`);
}
process.exit(1);
});
}
}