Remove now unused rush configuration
This commit is contained in:
@@ -1,28 +0,0 @@
|
|||||||
This directory contains content from https://github.com/microsoft/rushstack,
|
|
||||||
used under the MIT license as follows.
|
|
||||||
See https://github.com/microsoft/rushstack/blob/master/stack/rush-stack/LICENSE.
|
|
||||||
|
|
||||||
@microsoft/rush-stack
|
|
||||||
|
|
||||||
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
||||||
|
|
||||||
MIT License
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
|
||||||
a copy of this software and associated documentation files (the
|
|
||||||
"Software"), to deal in the Software without restriction, including
|
|
||||||
without limitation the rights to use, copy, modify, merge, publish,
|
|
||||||
distribute, sublicense, and/or sell copies of the Software, and to
|
|
||||||
permit persons to whom the Software is furnished to do so, subject to
|
|
||||||
the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be
|
|
||||||
included in all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
||||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
||||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
||||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
|
||||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
|
||||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
# Rush uses this file to configure the package registry, regardless of whether the
|
|
||||||
# package manager is PNPM, NPM, or Yarn. Prior to invoking the package manager,
|
|
||||||
# Rush will always copy this file to the folder where installation is performed.
|
|
||||||
# When NPM is the package manager, Rush works around NPM's processing of
|
|
||||||
# undefined environment variables by deleting any lines that reference undefined
|
|
||||||
# environment variables.
|
|
||||||
#
|
|
||||||
# DO NOT SPECIFY AUTHENTICATION CREDENTIALS IN THIS FILE. It should only be used
|
|
||||||
# to configure registry sources.
|
|
||||||
|
|
||||||
registry=https://registry.npmjs.org/
|
|
||||||
always-auth=false
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
/**
|
|
||||||
* This configuration file defines custom commands for the "rush" command-line.
|
|
||||||
* For full documentation, please see https://rushjs.io/pages/configs/command_line_json/
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/command-line.schema.json",
|
|
||||||
"commands": [
|
|
||||||
{
|
|
||||||
"commandKind": "bulk",
|
|
||||||
"name": "format",
|
|
||||||
"summary": "Reformat source code in all projects",
|
|
||||||
"description": "Runs the `format` npm task in each project, if present.",
|
|
||||||
"safeForSimultaneousRushProcesses": false,
|
|
||||||
"enableParallelism": true,
|
|
||||||
"ignoreDependencyOrder": true,
|
|
||||||
"ignoreMissingScript": true,
|
|
||||||
"allowWarningsInSuccessfulBuild": false
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"parameters": [
|
|
||||||
{
|
|
||||||
"parameterKind": "flag",
|
|
||||||
"longName": "--release",
|
|
||||||
"shortName": "-r",
|
|
||||||
"description": "Perform a release build",
|
|
||||||
"associatedCommands": [
|
|
||||||
"build",
|
|
||||||
"rebuild"
|
|
||||||
],
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
/**
|
|
||||||
* This configuration file specifies NPM dependency version selections that affect all projects
|
|
||||||
* in a Rush repo. For full documentation, please see https://rushjs.io
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/common-versions.schema.json",
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A table that specifies a "preferred version" for a dependency package. The "preferred version"
|
|
||||||
* is typically used to hold an indirect dependency back to a specific version, however generally
|
|
||||||
* it can be any SemVer range specifier (e.g. "~1.2.3"), and it will narrow any (compatible)
|
|
||||||
* SemVer range specifier. See the Rush documentation for details about this feature.
|
|
||||||
*/
|
|
||||||
"preferredVersions": {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When someone asks for "^1.0.0" make sure they get "1.2.3" when working in this repo,
|
|
||||||
* instead of the latest version.
|
|
||||||
*/
|
|
||||||
// "some-library": "1.2.3"
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The "rush check" command can be used to enforce that every project in the repo must specify
|
|
||||||
* the same SemVer range for a given dependency. However, sometimes exceptions are needed.
|
|
||||||
* The allowedAlternativeVersions table allows you to list other SemVer ranges that will be
|
|
||||||
* accepted by "rush check" for a given dependency.
|
|
||||||
*
|
|
||||||
* IMPORTANT: THIS TABLE IS FOR *ADDITIONAL* VERSION RANGES THAT ARE ALTERNATIVES TO THE
|
|
||||||
* USUAL VERSION (WHICH IS INFERRED BY LOOKING AT ALL PROJECTS IN THE REPO).
|
|
||||||
* This design avoids unnecessary churn in this file.
|
|
||||||
*/
|
|
||||||
"allowedAlternativeVersions": {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For example, allow some projects to use an older TypeScript compiler
|
|
||||||
* (in addition to whatever "usual" version is being used by other projects in the repo):
|
|
||||||
*/
|
|
||||||
// "typescript": [
|
|
||||||
// "~2.4.0"
|
|
||||||
// ]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
8167
common/config/rush/pnpm-lock.yaml
generated
8167
common/config/rush/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -1,32 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When using the PNPM package manager, you can use pnpmfile.js to workaround
|
|
||||||
* dependencies that have mistakes in their package.json file. (This feature is
|
|
||||||
* functionally similar to Yarn's "resolutions".)
|
|
||||||
*
|
|
||||||
* For details, see the PNPM documentation:
|
|
||||||
* https://pnpm.js.org/docs/en/hooks.html
|
|
||||||
*
|
|
||||||
* IMPORTANT: SINCE THIS FILE CONTAINS EXECUTABLE CODE, MODIFYING IT IS LIKELY
|
|
||||||
* TO INVALIDATE ANY CACHED DEPENDENCY ANALYSIS. We recommend to run "rush update --full"
|
|
||||||
* after any modification to pnpmfile.js.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
module.exports = {
|
|
||||||
hooks: {
|
|
||||||
readPackage
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This hook is invoked during installation before a package's dependencies
|
|
||||||
* are selected.
|
|
||||||
* The `packageJson` parameter is the deserialized package.json
|
|
||||||
* contents for the package that is about to be installed.
|
|
||||||
* The `context` parameter provides a log() function.
|
|
||||||
* The return value is the updated object.
|
|
||||||
*/
|
|
||||||
function readPackage(packageJson, context) {
|
|
||||||
return packageJson;
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
/**
|
|
||||||
* This is configuration file is used for advanced publishing configurations with Rush.
|
|
||||||
* For full documentation, please see https://rushjs.io/pages/configs/version_policies_json/
|
|
||||||
*/
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"definitionName": "individualVersion",
|
|
||||||
"policyName": "utilities"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
|
||||||
// See the @microsoft/rush package's LICENSE file for license information.
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
// THIS FILE WAS GENERATED BY A TOOL. ANY MANUAL MODIFICATIONS WILL GET OVERWRITTEN WHENEVER RUSH IS UPGRADED.
|
|
||||||
//
|
|
||||||
// This script is intended for usage in an automated build environment where the Rush command may not have
|
|
||||||
// been preinstalled, or may have an unpredictable version. This script will automatically install the version of Rush
|
|
||||||
// specified in the rush.json configuration file (if not already installed), and then pass a command-line to it.
|
|
||||||
// An example usage would be:
|
|
||||||
//
|
|
||||||
// node common/scripts/install-run-rush.js install
|
|
||||||
//
|
|
||||||
// For more information, see: https://rushjs.io/pages/maintainer/setup_new_repo/
|
|
||||||
const path = require("path");
|
|
||||||
const fs = require("fs");
|
|
||||||
const install_run_1 = require("./install-run");
|
|
||||||
const PACKAGE_NAME = '@microsoft/rush';
|
|
||||||
const RUSH_PREVIEW_VERSION = 'RUSH_PREVIEW_VERSION';
|
|
||||||
function _getRushVersion() {
|
|
||||||
const rushPreviewVersion = process.env[RUSH_PREVIEW_VERSION];
|
|
||||||
if (rushPreviewVersion !== undefined) {
|
|
||||||
console.log(`Using Rush version from environment variable ${RUSH_PREVIEW_VERSION}=${rushPreviewVersion}`);
|
|
||||||
return rushPreviewVersion;
|
|
||||||
}
|
|
||||||
const rushJsonFolder = install_run_1.findRushJsonFolder();
|
|
||||||
const rushJsonPath = path.join(rushJsonFolder, install_run_1.RUSH_JSON_FILENAME);
|
|
||||||
try {
|
|
||||||
const rushJsonContents = fs.readFileSync(rushJsonPath, 'utf-8');
|
|
||||||
// Use a regular expression to parse out the rushVersion value because rush.json supports comments,
|
|
||||||
// but JSON.parse does not and we don't want to pull in more dependencies than we need to in this script.
|
|
||||||
const rushJsonMatches = rushJsonContents.match(/\"rushVersion\"\s*\:\s*\"([0-9a-zA-Z.+\-]+)\"/);
|
|
||||||
return rushJsonMatches[1];
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
throw new Error(`Unable to determine the required version of Rush from rush.json (${rushJsonFolder}). ` +
|
|
||||||
'The \'rushVersion\' field is either not assigned in rush.json or was specified ' +
|
|
||||||
'using an unexpected syntax.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function _run() {
|
|
||||||
const [nodePath, /* Ex: /bin/node */ scriptPath, /* /repo/common/scripts/install-run-rush.js */ ...packageBinArgs /* [build, --to, myproject] */] = process.argv;
|
|
||||||
// Detect if this script was directly invoked, or if the install-run-rushx script was invokved to select the
|
|
||||||
// appropriate binary inside the rush package to run
|
|
||||||
const scriptName = path.basename(scriptPath);
|
|
||||||
const bin = scriptName.toLowerCase() === 'install-run-rushx.js' ? 'rushx' : 'rush';
|
|
||||||
if (!nodePath || !scriptPath) {
|
|
||||||
throw new Error('Unexpected exception: could not detect node path or script path');
|
|
||||||
}
|
|
||||||
if (process.argv.length < 3) {
|
|
||||||
console.log(`Usage: ${scriptName} <command> [args...]`);
|
|
||||||
if (scriptName === 'install-run-rush.js') {
|
|
||||||
console.log(`Example: ${scriptName} build --to myproject`);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
console.log(`Example: ${scriptName} custom-command`);
|
|
||||||
}
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
install_run_1.runWithErrorAndStatusCode(() => {
|
|
||||||
const version = _getRushVersion();
|
|
||||||
console.log(`The rush.json configuration requests Rush version ${version}`);
|
|
||||||
return install_run_1.installAndRun(PACKAGE_NAME, version, bin, packageBinArgs);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
_run();
|
|
||||||
//# sourceMappingURL=install-run-rush.js.map
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
|
||||||
// See the @microsoft/rush package's LICENSE file for license information.
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
// THIS FILE WAS GENERATED BY A TOOL. ANY MANUAL MODIFICATIONS WILL GET OVERWRITTEN WHENEVER RUSH IS UPGRADED.
|
|
||||||
//
|
|
||||||
// This script is intended for usage in an automated build environment where the Rush command may not have
|
|
||||||
// been preinstalled, or may have an unpredictable version. This script will automatically install the version of Rush
|
|
||||||
// specified in the rush.json configuration file (if not already installed), and then pass a command-line to the
|
|
||||||
// rushx command.
|
|
||||||
//
|
|
||||||
// An example usage would be:
|
|
||||||
//
|
|
||||||
// node common/scripts/install-run-rushx.js custom-command
|
|
||||||
//
|
|
||||||
// For more information, see: https://rushjs.io/pages/maintainer/setup_new_repo/
|
|
||||||
require("./install-run-rush");
|
|
||||||
//# sourceMappingURL=install-run-rushx.js.map
|
|
||||||
@@ -1,433 +0,0 @@
|
|||||||
"use strict";
|
|
||||||
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
|
|
||||||
// See the @microsoft/rush package's LICENSE file for license information.
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
// THIS FILE WAS GENERATED BY A TOOL. ANY MANUAL MODIFICATIONS WILL GET OVERWRITTEN WHENEVER RUSH IS UPGRADED.
|
|
||||||
//
|
|
||||||
// This script is intended for usage in an automated build environment where a Node tool may not have
|
|
||||||
// been preinstalled, or may have an unpredictable version. This script will automatically install the specified
|
|
||||||
// version of the specified tool (if not already installed), and then pass a command-line to it.
|
|
||||||
// An example usage would be:
|
|
||||||
//
|
|
||||||
// node common/scripts/install-run.js qrcode@1.2.2 qrcode https://rushjs.io
|
|
||||||
//
|
|
||||||
// For more information, see: https://rushjs.io/pages/maintainer/setup_new_repo/
|
|
||||||
const childProcess = require("child_process");
|
|
||||||
const fs = require("fs");
|
|
||||||
const os = require("os");
|
|
||||||
const path = require("path");
|
|
||||||
exports.RUSH_JSON_FILENAME = 'rush.json';
|
|
||||||
const RUSH_TEMP_FOLDER_ENV_VARIABLE_NAME = 'RUSH_TEMP_FOLDER';
|
|
||||||
const INSTALLED_FLAG_FILENAME = 'installed.flag';
|
|
||||||
const NODE_MODULES_FOLDER_NAME = 'node_modules';
|
|
||||||
const PACKAGE_JSON_FILENAME = 'package.json';
|
|
||||||
/**
|
|
||||||
* Parse a package specifier (in the form of name\@version) into name and version parts.
|
|
||||||
*/
|
|
||||||
function _parsePackageSpecifier(rawPackageSpecifier) {
|
|
||||||
rawPackageSpecifier = (rawPackageSpecifier || '').trim();
|
|
||||||
const separatorIndex = rawPackageSpecifier.lastIndexOf('@');
|
|
||||||
let name;
|
|
||||||
let version = undefined;
|
|
||||||
if (separatorIndex === 0) {
|
|
||||||
// The specifier starts with a scope and doesn't have a version specified
|
|
||||||
name = rawPackageSpecifier;
|
|
||||||
}
|
|
||||||
else if (separatorIndex === -1) {
|
|
||||||
// The specifier doesn't have a version
|
|
||||||
name = rawPackageSpecifier;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
name = rawPackageSpecifier.substring(0, separatorIndex);
|
|
||||||
version = rawPackageSpecifier.substring(separatorIndex + 1);
|
|
||||||
}
|
|
||||||
if (!name) {
|
|
||||||
throw new Error(`Invalid package specifier: ${rawPackageSpecifier}`);
|
|
||||||
}
|
|
||||||
return { name, version };
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* As a workaround, copyAndTrimNpmrcFile() copies the .npmrc file to the target folder, and also trims
|
|
||||||
* unusable lines from the .npmrc file.
|
|
||||||
*
|
|
||||||
* Why are we trimming the .npmrc lines? NPM allows environment variables to be specified in
|
|
||||||
* the .npmrc file to provide different authentication tokens for different registry.
|
|
||||||
* However, if the environment variable is undefined, it expands to an empty string, which
|
|
||||||
* produces a valid-looking mapping with an invalid URL that causes an error. Instead,
|
|
||||||
* we'd prefer to skip that line and continue looking in other places such as the user's
|
|
||||||
* home directory.
|
|
||||||
*
|
|
||||||
* IMPORTANT: THIS CODE SHOULD BE KEPT UP TO DATE WITH Utilities._copyNpmrcFile()
|
|
||||||
*/
|
|
||||||
function _copyAndTrimNpmrcFile(sourceNpmrcPath, targetNpmrcPath) {
|
|
||||||
console.log(`Copying ${sourceNpmrcPath} --> ${targetNpmrcPath}`); // Verbose
|
|
||||||
let npmrcFileLines = fs.readFileSync(sourceNpmrcPath).toString().split('\n');
|
|
||||||
npmrcFileLines = npmrcFileLines.map((line) => (line || '').trim());
|
|
||||||
const resultLines = [];
|
|
||||||
// Trim out lines that reference environment variables that aren't defined
|
|
||||||
for (const line of npmrcFileLines) {
|
|
||||||
// This finds environment variable tokens that look like "${VAR_NAME}"
|
|
||||||
const regex = /\$\{([^\}]+)\}/g;
|
|
||||||
const environmentVariables = line.match(regex);
|
|
||||||
let lineShouldBeTrimmed = false;
|
|
||||||
if (environmentVariables) {
|
|
||||||
for (const token of environmentVariables) {
|
|
||||||
// Remove the leading "${" and the trailing "}" from the token
|
|
||||||
const environmentVariableName = token.substring(2, token.length - 1);
|
|
||||||
if (!process.env[environmentVariableName]) {
|
|
||||||
lineShouldBeTrimmed = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (lineShouldBeTrimmed) {
|
|
||||||
// Example output:
|
|
||||||
// "; MISSING ENVIRONMENT VARIABLE: //my-registry.com/npm/:_authToken=${MY_AUTH_TOKEN}"
|
|
||||||
resultLines.push('; MISSING ENVIRONMENT VARIABLE: ' + line);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
resultLines.push(line);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fs.writeFileSync(targetNpmrcPath, resultLines.join(os.EOL));
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* syncNpmrc() copies the .npmrc file to the target folder, and also trims unusable lines from the .npmrc file.
|
|
||||||
* If the source .npmrc file not exist, then syncNpmrc() will delete an .npmrc that is found in the target folder.
|
|
||||||
*
|
|
||||||
* IMPORTANT: THIS CODE SHOULD BE KEPT UP TO DATE WITH Utilities._syncNpmrc()
|
|
||||||
*/
|
|
||||||
function _syncNpmrc(sourceNpmrcFolder, targetNpmrcFolder, useNpmrcPublish) {
|
|
||||||
const sourceNpmrcPath = path.join(sourceNpmrcFolder, !useNpmrcPublish ? '.npmrc' : '.npmrc-publish');
|
|
||||||
const targetNpmrcPath = path.join(targetNpmrcFolder, '.npmrc');
|
|
||||||
try {
|
|
||||||
if (fs.existsSync(sourceNpmrcPath)) {
|
|
||||||
_copyAndTrimNpmrcFile(sourceNpmrcPath, targetNpmrcPath);
|
|
||||||
}
|
|
||||||
else if (fs.existsSync(targetNpmrcPath)) {
|
|
||||||
// If the source .npmrc doesn't exist and there is one in the target, delete the one in the target
|
|
||||||
console.log(`Deleting ${targetNpmrcPath}`); // Verbose
|
|
||||||
fs.unlinkSync(targetNpmrcPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
throw new Error(`Error syncing .npmrc file: ${e}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let _npmPath = undefined;
|
|
||||||
/**
|
|
||||||
* Get the absolute path to the npm executable
|
|
||||||
*/
|
|
||||||
function getNpmPath() {
|
|
||||||
if (!_npmPath) {
|
|
||||||
try {
|
|
||||||
if (os.platform() === 'win32') {
|
|
||||||
// We're on Windows
|
|
||||||
const whereOutput = childProcess.execSync('where npm', { stdio: [] }).toString();
|
|
||||||
const lines = whereOutput.split(os.EOL).filter((line) => !!line);
|
|
||||||
// take the last result, we are looking for a .cmd command
|
|
||||||
// see https://github.com/microsoft/rushstack/issues/759
|
|
||||||
_npmPath = lines[lines.length - 1];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// We aren't on Windows - assume we're on *NIX or Darwin
|
|
||||||
_npmPath = childProcess.execSync('which npm', { stdio: [] }).toString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
throw new Error(`Unable to determine the path to the NPM tool: ${e}`);
|
|
||||||
}
|
|
||||||
_npmPath = _npmPath.trim();
|
|
||||||
if (!fs.existsSync(_npmPath)) {
|
|
||||||
throw new Error('The NPM executable does not exist');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return _npmPath;
|
|
||||||
}
|
|
||||||
exports.getNpmPath = getNpmPath;
|
|
||||||
function _ensureFolder(folderPath) {
|
|
||||||
if (!fs.existsSync(folderPath)) {
|
|
||||||
const parentDir = path.dirname(folderPath);
|
|
||||||
_ensureFolder(parentDir);
|
|
||||||
fs.mkdirSync(folderPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Create missing directories under the specified base directory, and return the resolved directory.
|
|
||||||
*
|
|
||||||
* Does not support "." or ".." path segments.
|
|
||||||
* Assumes the baseFolder exists.
|
|
||||||
*/
|
|
||||||
function _ensureAndJoinPath(baseFolder, ...pathSegments) {
|
|
||||||
let joinedPath = baseFolder;
|
|
||||||
try {
|
|
||||||
for (let pathSegment of pathSegments) {
|
|
||||||
pathSegment = pathSegment.replace(/[\\\/]/g, '+');
|
|
||||||
joinedPath = path.join(joinedPath, pathSegment);
|
|
||||||
if (!fs.existsSync(joinedPath)) {
|
|
||||||
fs.mkdirSync(joinedPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
throw new Error(`Error building local installation folder (${path.join(baseFolder, ...pathSegments)}): ${e}`);
|
|
||||||
}
|
|
||||||
return joinedPath;
|
|
||||||
}
|
|
||||||
function _getRushTempFolder(rushCommonFolder) {
|
|
||||||
const rushTempFolder = process.env[RUSH_TEMP_FOLDER_ENV_VARIABLE_NAME];
|
|
||||||
if (rushTempFolder !== undefined) {
|
|
||||||
_ensureFolder(rushTempFolder);
|
|
||||||
return rushTempFolder;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return _ensureAndJoinPath(rushCommonFolder, 'temp');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Resolve a package specifier to a static version
|
|
||||||
*/
|
|
||||||
function _resolvePackageVersion(rushCommonFolder, { name, version }) {
|
|
||||||
if (!version) {
|
|
||||||
version = '*'; // If no version is specified, use the latest version
|
|
||||||
}
|
|
||||||
if (version.match(/^[a-zA-Z0-9\-\+\.]+$/)) {
|
|
||||||
// If the version contains only characters that we recognize to be used in static version specifiers,
|
|
||||||
// pass the version through
|
|
||||||
return version;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// version resolves to
|
|
||||||
try {
|
|
||||||
const rushTempFolder = _getRushTempFolder(rushCommonFolder);
|
|
||||||
const sourceNpmrcFolder = path.join(rushCommonFolder, 'config', 'rush');
|
|
||||||
_syncNpmrc(sourceNpmrcFolder, rushTempFolder);
|
|
||||||
const npmPath = getNpmPath();
|
|
||||||
// This returns something that looks like:
|
|
||||||
// @microsoft/rush@3.0.0 '3.0.0'
|
|
||||||
// @microsoft/rush@3.0.1 '3.0.1'
|
|
||||||
// ...
|
|
||||||
// @microsoft/rush@3.0.20 '3.0.20'
|
|
||||||
// <blank line>
|
|
||||||
const npmVersionSpawnResult = childProcess.spawnSync(npmPath, ['view', `${name}@${version}`, 'version', '--no-update-notifier'], {
|
|
||||||
cwd: rushTempFolder,
|
|
||||||
stdio: []
|
|
||||||
});
|
|
||||||
if (npmVersionSpawnResult.status !== 0) {
|
|
||||||
throw new Error(`"npm view" returned error code ${npmVersionSpawnResult.status}`);
|
|
||||||
}
|
|
||||||
const npmViewVersionOutput = npmVersionSpawnResult.stdout.toString();
|
|
||||||
const versionLines = npmViewVersionOutput.split('\n').filter((line) => !!line);
|
|
||||||
const latestVersion = versionLines[versionLines.length - 1];
|
|
||||||
if (!latestVersion) {
|
|
||||||
throw new Error('No versions found for the specified version range.');
|
|
||||||
}
|
|
||||||
const versionMatches = latestVersion.match(/^.+\s\'(.+)\'$/);
|
|
||||||
if (!versionMatches) {
|
|
||||||
throw new Error(`Invalid npm output ${latestVersion}`);
|
|
||||||
}
|
|
||||||
return versionMatches[1];
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
throw new Error(`Unable to resolve version ${version} of package ${name}: ${e}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let _rushJsonFolder;
|
|
||||||
/**
|
|
||||||
* Find the absolute path to the folder containing rush.json
|
|
||||||
*/
|
|
||||||
function findRushJsonFolder() {
|
|
||||||
if (!_rushJsonFolder) {
|
|
||||||
let basePath = __dirname;
|
|
||||||
let tempPath = __dirname;
|
|
||||||
do {
|
|
||||||
const testRushJsonPath = path.join(basePath, exports.RUSH_JSON_FILENAME);
|
|
||||||
if (fs.existsSync(testRushJsonPath)) {
|
|
||||||
_rushJsonFolder = basePath;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
basePath = tempPath;
|
|
||||||
}
|
|
||||||
} while (basePath !== (tempPath = path.dirname(basePath))); // Exit the loop when we hit the disk root
|
|
||||||
if (!_rushJsonFolder) {
|
|
||||||
throw new Error('Unable to find rush.json.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return _rushJsonFolder;
|
|
||||||
}
|
|
||||||
exports.findRushJsonFolder = findRushJsonFolder;
|
|
||||||
/**
|
|
||||||
* Detects if the package in the specified directory is installed
|
|
||||||
*/
|
|
||||||
function _isPackageAlreadyInstalled(packageInstallFolder) {
|
|
||||||
try {
|
|
||||||
const flagFilePath = path.join(packageInstallFolder, INSTALLED_FLAG_FILENAME);
|
|
||||||
if (!fs.existsSync(flagFilePath)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
const fileContents = fs.readFileSync(flagFilePath).toString();
|
|
||||||
return fileContents.trim() === process.version;
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Removes the following files and directories under the specified folder path:
|
|
||||||
* - installed.flag
|
|
||||||
* -
|
|
||||||
* - node_modules
|
|
||||||
*/
|
|
||||||
function _cleanInstallFolder(rushTempFolder, packageInstallFolder) {
|
|
||||||
try {
|
|
||||||
const flagFile = path.resolve(packageInstallFolder, INSTALLED_FLAG_FILENAME);
|
|
||||||
if (fs.existsSync(flagFile)) {
|
|
||||||
fs.unlinkSync(flagFile);
|
|
||||||
}
|
|
||||||
const packageLockFile = path.resolve(packageInstallFolder, 'package-lock.json');
|
|
||||||
if (fs.existsSync(packageLockFile)) {
|
|
||||||
fs.unlinkSync(packageLockFile);
|
|
||||||
}
|
|
||||||
const nodeModulesFolder = path.resolve(packageInstallFolder, NODE_MODULES_FOLDER_NAME);
|
|
||||||
if (fs.existsSync(nodeModulesFolder)) {
|
|
||||||
const rushRecyclerFolder = _ensureAndJoinPath(rushTempFolder, 'rush-recycler', `install-run-${Date.now().toString()}`);
|
|
||||||
fs.renameSync(nodeModulesFolder, rushRecyclerFolder);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
throw new Error(`Error cleaning the package install folder (${packageInstallFolder}): ${e}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function _createPackageJson(packageInstallFolder, name, version) {
|
|
||||||
try {
|
|
||||||
const packageJsonContents = {
|
|
||||||
'name': 'ci-rush',
|
|
||||||
'version': '0.0.0',
|
|
||||||
'dependencies': {
|
|
||||||
[name]: version
|
|
||||||
},
|
|
||||||
'description': 'DON\'T WARN',
|
|
||||||
'repository': 'DON\'T WARN',
|
|
||||||
'license': 'MIT'
|
|
||||||
};
|
|
||||||
const packageJsonPath = path.join(packageInstallFolder, PACKAGE_JSON_FILENAME);
|
|
||||||
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJsonContents, undefined, 2));
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
throw new Error(`Unable to create package.json: ${e}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Run "npm install" in the package install folder.
|
|
||||||
*/
|
|
||||||
function _installPackage(packageInstallFolder, name, version) {
|
|
||||||
try {
|
|
||||||
console.log(`Installing ${name}...`);
|
|
||||||
const npmPath = getNpmPath();
|
|
||||||
const result = childProcess.spawnSync(npmPath, ['install'], {
|
|
||||||
stdio: 'inherit',
|
|
||||||
cwd: packageInstallFolder,
|
|
||||||
env: process.env
|
|
||||||
});
|
|
||||||
if (result.status !== 0) {
|
|
||||||
throw new Error('"npm install" encountered an error');
|
|
||||||
}
|
|
||||||
console.log(`Successfully installed ${name}@${version}`);
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
throw new Error(`Unable to install package: ${e}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Get the ".bin" path for the package.
|
|
||||||
*/
|
|
||||||
function _getBinPath(packageInstallFolder, binName) {
|
|
||||||
const binFolderPath = path.resolve(packageInstallFolder, NODE_MODULES_FOLDER_NAME, '.bin');
|
|
||||||
const resolvedBinName = (os.platform() === 'win32') ? `${binName}.cmd` : binName;
|
|
||||||
return path.resolve(binFolderPath, resolvedBinName);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Write a flag file to the package's install directory, signifying that the install was successful.
|
|
||||||
*/
|
|
||||||
function _writeFlagFile(packageInstallFolder) {
|
|
||||||
try {
|
|
||||||
const flagFilePath = path.join(packageInstallFolder, INSTALLED_FLAG_FILENAME);
|
|
||||||
fs.writeFileSync(flagFilePath, process.version);
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
throw new Error(`Unable to create installed.flag file in ${packageInstallFolder}`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function installAndRun(packageName, packageVersion, packageBinName, packageBinArgs) {
|
|
||||||
const rushJsonFolder = findRushJsonFolder();
|
|
||||||
const rushCommonFolder = path.join(rushJsonFolder, 'common');
|
|
||||||
const rushTempFolder = _getRushTempFolder(rushCommonFolder);
|
|
||||||
const packageInstallFolder = _ensureAndJoinPath(rushTempFolder, 'install-run', `${packageName}@${packageVersion}`);
|
|
||||||
if (!_isPackageAlreadyInstalled(packageInstallFolder)) {
|
|
||||||
// The package isn't already installed
|
|
||||||
_cleanInstallFolder(rushTempFolder, packageInstallFolder);
|
|
||||||
const sourceNpmrcFolder = path.join(rushCommonFolder, 'config', 'rush');
|
|
||||||
_syncNpmrc(sourceNpmrcFolder, packageInstallFolder);
|
|
||||||
_createPackageJson(packageInstallFolder, packageName, packageVersion);
|
|
||||||
_installPackage(packageInstallFolder, packageName, packageVersion);
|
|
||||||
_writeFlagFile(packageInstallFolder);
|
|
||||||
}
|
|
||||||
const statusMessage = `Invoking "${packageBinName} ${packageBinArgs.join(' ')}"`;
|
|
||||||
const statusMessageLine = new Array(statusMessage.length + 1).join('-');
|
|
||||||
console.log(os.EOL + statusMessage + os.EOL + statusMessageLine + os.EOL);
|
|
||||||
const binPath = _getBinPath(packageInstallFolder, packageBinName);
|
|
||||||
const result = childProcess.spawnSync(binPath, packageBinArgs, {
|
|
||||||
stdio: 'inherit',
|
|
||||||
cwd: process.cwd(),
|
|
||||||
env: process.env
|
|
||||||
});
|
|
||||||
if (result.status !== null) {
|
|
||||||
return result.status;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw result.error || new Error('An unknown error occurred.');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.installAndRun = installAndRun;
|
|
||||||
function runWithErrorAndStatusCode(fn) {
|
|
||||||
process.exitCode = 1;
|
|
||||||
try {
|
|
||||||
const exitCode = fn();
|
|
||||||
process.exitCode = exitCode;
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
console.error(os.EOL + os.EOL + e.toString() + os.EOL + os.EOL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.runWithErrorAndStatusCode = runWithErrorAndStatusCode;
|
|
||||||
function _run() {
|
|
||||||
const [nodePath, /* Ex: /bin/node */ scriptPath, /* /repo/common/scripts/install-run-rush.js */ rawPackageSpecifier, /* qrcode@^1.2.0 */ packageBinName, /* qrcode */ ...packageBinArgs /* [-f, myproject/lib] */] = process.argv;
|
|
||||||
if (!nodePath) {
|
|
||||||
throw new Error('Unexpected exception: could not detect node path');
|
|
||||||
}
|
|
||||||
if (path.basename(scriptPath).toLowerCase() !== 'install-run.js') {
|
|
||||||
// If install-run.js wasn't directly invoked, don't execute the rest of this function. Return control
|
|
||||||
// to the script that (presumably) imported this file
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (process.argv.length < 4) {
|
|
||||||
console.log('Usage: install-run.js <package>@<version> <command> [args...]');
|
|
||||||
console.log('Example: install-run.js qrcode@1.2.2 qrcode https://rushjs.io');
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
runWithErrorAndStatusCode(() => {
|
|
||||||
const rushJsonFolder = findRushJsonFolder();
|
|
||||||
const rushCommonFolder = _ensureAndJoinPath(rushJsonFolder, 'common');
|
|
||||||
const packageSpecifier = _parsePackageSpecifier(rawPackageSpecifier);
|
|
||||||
const name = packageSpecifier.name;
|
|
||||||
const version = _resolvePackageVersion(rushCommonFolder, packageSpecifier);
|
|
||||||
if (packageSpecifier.version !== version) {
|
|
||||||
console.log(`Resolved to ${name}@${version}`);
|
|
||||||
}
|
|
||||||
return installAndRun(name, version, packageBinName, packageBinArgs);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
_run();
|
|
||||||
//# sourceMappingURL=install-run.js.map
|
|
||||||
@@ -1,166 +0,0 @@
|
|||||||
import * as fs from 'fs-extra';
|
|
||||||
import * as glob from 'glob-promise';
|
|
||||||
import * as jsonc from 'jsonc-parser';
|
|
||||||
import { Shrinkwrap, ShrinkwrapPackage } from './pnpm';
|
|
||||||
import * as path from 'path';
|
|
||||||
import { IPackageJson } from '@microsoft/node-core-library';
|
|
||||||
import { RushConfiguration } from '@microsoft/rush-lib';
|
|
||||||
import * as yaml from 'js-yaml';
|
|
||||||
|
|
||||||
export interface PackageJsonWithFiles extends IPackageJson {
|
|
||||||
files?: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
interface PackageInfo {
|
|
||||||
path: string;
|
|
||||||
dependencies: Map<string, string>;
|
|
||||||
config: PackageJsonWithFiles;
|
|
||||||
isLocal: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
const peerDependencyVersionPattern = /^\/((?:@(?:[^\/]+)\/)?[^\/]+)\/([^\/]+)\//;
|
|
||||||
|
|
||||||
export class RushContext {
|
|
||||||
private shrinkwrap?: Shrinkwrap;
|
|
||||||
private shrinkwrapPackages?: Map<string, ShrinkwrapPackage>;
|
|
||||||
private readonly packageStore: string;
|
|
||||||
|
|
||||||
constructor(public readonly rushConfig: RushConfiguration) {
|
|
||||||
this.packageStore = path.join(rushConfig.pnpmStoreFolder, '2');
|
|
||||||
}
|
|
||||||
|
|
||||||
private async findPackageInRepository(name: string, version: string): Promise<string> {
|
|
||||||
// Packages may be pulled from multiple registries, each of which has its own directory in the
|
|
||||||
// pnpm store. Search for the package name in any of these directories. We use `*.*` to match
|
|
||||||
// the directory name to avoid searching the `local` directory, which does not represent a
|
|
||||||
// package registry.
|
|
||||||
const results = await glob(`*.*/${name}/${version}/package`, {
|
|
||||||
absolute: true,
|
|
||||||
cwd: this.packageStore
|
|
||||||
});
|
|
||||||
if (results.length === 0) {
|
|
||||||
throw new Error(`Package '${name}:${version}' not found in package repository.`);
|
|
||||||
}
|
|
||||||
else if (results.length > 1) {
|
|
||||||
throw new Error(`Multiple copies of package '${name}:${version}' found in package repository.`);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return results[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private getRushProjectPath(name: string): string | undefined {
|
|
||||||
const project = this.rushConfig.getProjectByName(name);
|
|
||||||
if (project) {
|
|
||||||
return project.projectFolder;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async getShrinkwrap(): Promise<Shrinkwrap> {
|
|
||||||
if (!this.shrinkwrap) {
|
|
||||||
this.shrinkwrap = yaml.safeLoad(await fs.readFile(this.rushConfig.getCommittedShrinkwrapFilename(), 'utf8'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.shrinkwrap!;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async getShrinkwrapPackage(name: string, version: string): Promise<ShrinkwrapPackage> {
|
|
||||||
const shrinkwrap = await this.getShrinkwrap();
|
|
||||||
|
|
||||||
if (!this.shrinkwrapPackages) {
|
|
||||||
this.shrinkwrapPackages = new Map<string, ShrinkwrapPackage>();
|
|
||||||
for (const name in shrinkwrap.packages) {
|
|
||||||
const pkg = shrinkwrap.packages[name];
|
|
||||||
let packageKey: string;
|
|
||||||
if (pkg.name) {
|
|
||||||
packageKey = makePackageKey(pkg.name, pkg.version!);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
packageKey = name;
|
|
||||||
}
|
|
||||||
this.shrinkwrapPackages.set(packageKey, pkg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const packageKey = makePackageKey(name, version);
|
|
||||||
const shrinkwrapPackage = this.shrinkwrapPackages.get(packageKey);
|
|
||||||
if (!shrinkwrapPackage) {
|
|
||||||
throw new Error(`Package '${packageKey}' not found in shrinkwrap file.`);
|
|
||||||
}
|
|
||||||
return shrinkwrapPackage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async getPackageInfo(name: string, version: string): Promise<PackageInfo> {
|
|
||||||
let pkg: ShrinkwrapPackage;
|
|
||||||
const rushProject = this.rushConfig.getProjectByName(name);
|
|
||||||
let packagePath: string;
|
|
||||||
let config: PackageJsonWithFiles;
|
|
||||||
if (rushProject) {
|
|
||||||
packagePath = rushProject.projectFolder;
|
|
||||||
pkg = await this.getShrinkwrapPackage(rushProject.tempProjectName, '0.0.0');
|
|
||||||
config = rushProject.packageJson;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
pkg = await this.getShrinkwrapPackage(name, version);
|
|
||||||
// Ensure a proper version number. pnpm uses syntax like 3.4.0_glob@7.1.6 for peer dependencies
|
|
||||||
version = version.split('_')[0];
|
|
||||||
packagePath = await this.findPackageInRepository(name, version);
|
|
||||||
packagePath = await fs.realpath(packagePath);
|
|
||||||
config = jsonc.parse(await fs.readFile(path.join(packagePath, 'package.json'), 'utf8'));
|
|
||||||
}
|
|
||||||
|
|
||||||
const dependencies = new Map<string, string>();
|
|
||||||
if (config.dependencies) {
|
|
||||||
for (const dependencyName in config.dependencies) {
|
|
||||||
let dependencyVersion: string;
|
|
||||||
if (await this.getRushProjectPath(dependencyName)) {
|
|
||||||
dependencyVersion = '0.0.0';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
dependencyVersion = pkg.dependencies![dependencyName];
|
|
||||||
if (!dependencyVersion) {
|
|
||||||
throw new Error(`Package '${name}' depends on unresolved package '${dependencyName}'.`);
|
|
||||||
}
|
|
||||||
if (dependencyVersion.startsWith('/')) {
|
|
||||||
// This is a package with a peer dependency. We need to extract the actual package
|
|
||||||
// version.
|
|
||||||
const match = dependencyVersion.match(peerDependencyVersionPattern);
|
|
||||||
if (match) {
|
|
||||||
if (match[1] !== dependencyName) {
|
|
||||||
throw new Error(`Mismatch between package name '${dependencyName}' and peer dependency specifier '${dependencyVersion}'.`);
|
|
||||||
}
|
|
||||||
dependencyVersion = match[2];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new Error(`Invalid peer dependency specifier '${dependencyVersion}'.`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies.set(dependencyName, dependencyVersion);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
path: packagePath,
|
|
||||||
dependencies: dependencies,
|
|
||||||
config: config,
|
|
||||||
isLocal: rushProject !== undefined
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function makePackageKey(name: string, version: string): string {
|
|
||||||
return `/${name}/${version}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getRushContext(startingFolder?: string): Promise<RushContext> {
|
|
||||||
const rushConfig = RushConfiguration.loadFromDefaultLocation({
|
|
||||||
startingFolder: startingFolder
|
|
||||||
});
|
|
||||||
|
|
||||||
return new RushContext(rushConfig);
|
|
||||||
}
|
|
||||||
39
rush.json
39
rush.json
@@ -1,39 +0,0 @@
|
|||||||
/**
|
|
||||||
* This is the main configuration file for Rush.
|
|
||||||
* For full documentation, please see https://rushjs.io/pages/configs/rush_json/
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/rush.schema.json",
|
|
||||||
"rushVersion": "5.20.0",
|
|
||||||
"pnpmVersion": "4.8.0",
|
|
||||||
"pnpmOptions": {
|
|
||||||
"strictPeerDependencies": true
|
|
||||||
},
|
|
||||||
"nodeSupportedVersionRange": ">=10.13.0 <15.0.0",
|
|
||||||
"suppressNodeLtsWarning": true,
|
|
||||||
"ensureConsistentVersions": true,
|
|
||||||
"projectFolderMinDepth": 2,
|
|
||||||
"projectFolderMaxDepth": 2,
|
|
||||||
"gitPolicy": {},
|
|
||||||
"repository": {
|
|
||||||
"url": "https://github.com/github/vscode-codeql.git"
|
|
||||||
},
|
|
||||||
"eventHooks": {
|
|
||||||
"preRushInstall": [],
|
|
||||||
"postRushInstall": [],
|
|
||||||
"preRushBuild": [],
|
|
||||||
"postRushBuild": []
|
|
||||||
},
|
|
||||||
"variants": [],
|
|
||||||
"projects": [
|
|
||||||
{
|
|
||||||
"packageName": "@github/codeql-gulp-tasks",
|
|
||||||
"projectFolder": "tools/build-tasks",
|
|
||||||
"versionPolicyName": "utilities"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"packageName": "vscode-codeql",
|
|
||||||
"projectFolder": "extensions/ql-vscode"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@github/codeql-gulp-tasks",
|
|
||||||
"entries": [
|
|
||||||
{
|
|
||||||
"version": "0.0.4",
|
|
||||||
"tag": "@github/codeql-gulp-tasks_v0.0.4",
|
|
||||||
"date": "Tue, 09 Jun 2020 13:58:46 GMT",
|
|
||||||
"comments": {
|
|
||||||
"patch": [
|
|
||||||
{
|
|
||||||
"comment": "Support packages from multiple registries when packaging an extension."
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "0.0.3",
|
|
||||||
"tag": "@github/codeql-build-tasks_v0.0.3",
|
|
||||||
"date": "Sat, 06 Jun 2020 06:54:45 GMT",
|
|
||||||
"comments": {
|
|
||||||
"patch": [
|
|
||||||
{
|
|
||||||
"comment": "Added missing dependency on `glob`"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"version": "0.0.2",
|
|
||||||
"tag": "@github/codeql-build-tasks_v0.0.2",
|
|
||||||
"date": "Fri, 05 Jun 2020 21:52:18 GMT",
|
|
||||||
"comments": {
|
|
||||||
"patch": [
|
|
||||||
{
|
|
||||||
"comment": "Initial configuration for publishing"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
# Change Log - @github/codeql-gulp-tasks
|
|
||||||
|
|
||||||
This log was last generated on Tue, 09 Jun 2020 13:58:46 GMT and should not be manually modified.
|
|
||||||
|
|
||||||
## 0.0.4
|
|
||||||
Tue, 09 Jun 2020 13:58:46 GMT
|
|
||||||
|
|
||||||
### Patches
|
|
||||||
|
|
||||||
- Support packages from multiple registries when packaging an extension.
|
|
||||||
|
|
||||||
## 0.0.3
|
|
||||||
Sat, 06 Jun 2020 06:54:45 GMT
|
|
||||||
|
|
||||||
### Patches
|
|
||||||
|
|
||||||
- Added missing dependency on `glob`
|
|
||||||
|
|
||||||
## 0.0.2
|
|
||||||
Fri, 05 Jun 2020 21:52:18 GMT
|
|
||||||
|
|
||||||
### Patches
|
|
||||||
|
|
||||||
- Initial configuration for publishing
|
|
||||||
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
require('ts-node').register({});
|
|
||||||
const { compileTypeScript, watchTypeScript } = require('../src/index');
|
|
||||||
|
|
||||||
exports.default = compileTypeScript;
|
|
||||||
exports.watchTypeScript = watchTypeScript;
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "@github/codeql-gulp-tasks",
|
|
||||||
"description": "Internal Gulp tasks",
|
|
||||||
"author": "GitHub",
|
|
||||||
"private": false,
|
|
||||||
"version": "0.0.4",
|
|
||||||
"publisher": "GitHub",
|
|
||||||
"repository": {
|
|
||||||
"type": "git",
|
|
||||||
"url": "https://github.com/github/codeql-coreql-team.git"
|
|
||||||
},
|
|
||||||
"publishConfig": {
|
|
||||||
"registry": "https://npm.pkg.github.com/"
|
|
||||||
},
|
|
||||||
"main": "./out/index",
|
|
||||||
"scripts": {
|
|
||||||
"build": "gulp",
|
|
||||||
"format": "tsfmt -r"
|
|
||||||
},
|
|
||||||
"dependencies": {
|
|
||||||
"@microsoft/node-core-library": "~3.13.0",
|
|
||||||
"@microsoft/rush-lib": "~5.20.0",
|
|
||||||
"ansi-colors": "^4.0.1",
|
|
||||||
"child-process-promise": "^2.2.1",
|
|
||||||
"fs-extra": "^8.1.0",
|
|
||||||
"glob": "^7.1.4",
|
|
||||||
"glob-promise": "^3.4.0",
|
|
||||||
"gulp": "^4.0.2",
|
|
||||||
"gulp-sourcemaps": "^2.6.5",
|
|
||||||
"gulp-typescript": "^5.0.1",
|
|
||||||
"js-yaml": "^3.12.0",
|
|
||||||
"jsonc-parser": "~2.1.0",
|
|
||||||
"npm-packlist": "~1.4.4",
|
|
||||||
"plugin-error": "^1.0.1",
|
|
||||||
"through2": "^3.0.1",
|
|
||||||
"vinyl": "^2.2.0"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@types/child-process-promise": "^2.2.1",
|
|
||||||
"@types/fs-extra": "^8.0.0",
|
|
||||||
"@types/gulp": "^4.0.6",
|
|
||||||
"@types/js-yaml": "~3.12.1",
|
|
||||||
"@types/node": "^12.0.8",
|
|
||||||
"@types/npm-packlist": "~1.1.1",
|
|
||||||
"@types/through2": "~2.0.34",
|
|
||||||
"@types/vinyl": "~2.0.3",
|
|
||||||
"typescript": "^3.7.2",
|
|
||||||
"typescript-formatter": "^7.2.2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,204 +0,0 @@
|
|||||||
import * as fs from 'fs-extra';
|
|
||||||
import * as jsonc from 'jsonc-parser';
|
|
||||||
import { IPackageJson } from '@microsoft/node-core-library';
|
|
||||||
import * as path from 'path';
|
|
||||||
import { getRushContext, RushContext } from './rush';
|
|
||||||
import * as packlist from 'npm-packlist';
|
|
||||||
import * as glob from 'glob-promise';
|
|
||||||
import * as cpp from 'child-process-promise';
|
|
||||||
|
|
||||||
interface IPackageInfo {
|
|
||||||
name: string;
|
|
||||||
version: string;
|
|
||||||
sourcePath: string;
|
|
||||||
files: string[];
|
|
||||||
dependencies: IPackageInfo[];
|
|
||||||
isRoot?: boolean;
|
|
||||||
copied?: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function copyPackage(packageFiles: IPackageInfo, destPath: string): Promise<void> {
|
|
||||||
for (const file of packageFiles.files) {
|
|
||||||
const sourceFilePath = path.resolve(packageFiles.sourcePath, file);
|
|
||||||
const destFilePath = path.resolve(destPath, file);
|
|
||||||
if (packageFiles.isRoot && (file === 'package.json')) {
|
|
||||||
// For non-release builds, we tweak the version number of the extension to add a prerelease
|
|
||||||
// suffix. Rather than just copying `package.json`, we'll parse the original copy, update the
|
|
||||||
// `version` property, and write it out to the new location.
|
|
||||||
const packageJson = jsonc.parse((await fs.readFile(sourceFilePath)).toString());
|
|
||||||
packageJson.version = packageFiles.version;
|
|
||||||
await fs.writeFile(destFilePath, JSON.stringify(packageJson));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
await fs.copy(sourceFilePath, destFilePath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface DeployedPackage {
|
|
||||||
distPath: string;
|
|
||||||
name: string;
|
|
||||||
version: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
class PackageMap {
|
|
||||||
private map = new Map<string, Map<string, IPackageInfo>>();
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public getPackageInfo(name: string, version: string): IPackageInfo | undefined {
|
|
||||||
const versionMap = this.map.get(name);
|
|
||||||
if (versionMap === undefined) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
return versionMap.get(version);
|
|
||||||
}
|
|
||||||
|
|
||||||
public addPackageInfo(pkg: IPackageInfo): void {
|
|
||||||
if (this.getPackageInfo(pkg.name, pkg.version)) {
|
|
||||||
throw new Error(`Attempt to add duplicate package '${pkg.name}@${pkg.version}'.`);
|
|
||||||
}
|
|
||||||
|
|
||||||
let versionMap = this.map.get(pkg.name);
|
|
||||||
if (versionMap === undefined) {
|
|
||||||
versionMap = new Map<string, IPackageInfo>();
|
|
||||||
this.map.set(pkg.name, versionMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
versionMap.set(pkg.version, pkg);
|
|
||||||
}
|
|
||||||
|
|
||||||
public hasMultipleVersions(name: string): boolean {
|
|
||||||
return this.map.get(name)!.size > 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async function collectPackages(context: RushContext, name: string, version: string,
|
|
||||||
pkgs: PackageMap): Promise<IPackageInfo> {
|
|
||||||
|
|
||||||
let pkg = pkgs.getPackageInfo(name, version);
|
|
||||||
if (!pkg) {
|
|
||||||
const info = await context.getPackageInfo(name, version);
|
|
||||||
|
|
||||||
let files: string[];
|
|
||||||
if (info.isLocal) {
|
|
||||||
// For local packages, use `packlist` to get the list of files that npm would have packed
|
|
||||||
// into the tarball.
|
|
||||||
files = packlist.sync({ path: info.path });
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// For non-local packages, just copy everything.
|
|
||||||
files = await glob('**/*', {
|
|
||||||
nodir: true,
|
|
||||||
cwd: info.path
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
pkg = {
|
|
||||||
name: name,
|
|
||||||
version: version,
|
|
||||||
sourcePath: info.path,
|
|
||||||
files: files,
|
|
||||||
dependencies: []
|
|
||||||
};
|
|
||||||
|
|
||||||
pkgs.addPackageInfo(pkg);
|
|
||||||
|
|
||||||
for (const dependencyName of info.dependencies.keys()) {
|
|
||||||
const dependencyVersion = info.dependencies.get(dependencyName)!;
|
|
||||||
|
|
||||||
const dependencyPackage = await collectPackages(context, dependencyName, dependencyVersion, pkgs);
|
|
||||||
pkg.dependencies.push(dependencyPackage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return pkg;
|
|
||||||
}
|
|
||||||
|
|
||||||
async function copyPackageAndModules(pkg: IPackageInfo, pkgs: PackageMap, destPath: string,
|
|
||||||
rootNodeModulesPath: string): Promise<void> {
|
|
||||||
|
|
||||||
let destPackagePath: string;
|
|
||||||
if (pkgs.hasMultipleVersions(pkg.name) || pkg.isRoot) {
|
|
||||||
// Copy as a nested package, and let `npm dedupe` fix it up later if possible.
|
|
||||||
destPackagePath = path.join(destPath, pkg.name);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
// Copy to the root `node_modules` directory.
|
|
||||||
if (pkg.copied) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
pkg.copied = true;
|
|
||||||
destPackagePath = path.join(rootNodeModulesPath, pkg.name);
|
|
||||||
}
|
|
||||||
|
|
||||||
await copyPackage(pkg, destPackagePath);
|
|
||||||
const nodeModulesPath = path.join(destPackagePath, 'node_modules');
|
|
||||||
for (const dependencyPkg of pkg.dependencies) {
|
|
||||||
await copyPackageAndModules(dependencyPkg, pkgs, nodeModulesPath, rootNodeModulesPath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function deployPackage(packageJsonPath: string): Promise<DeployedPackage> {
|
|
||||||
try {
|
|
||||||
const context = await getRushContext(path.dirname(packageJsonPath));
|
|
||||||
|
|
||||||
const rootPackage: IPackageJson = jsonc.parse(await fs.readFile(packageJsonPath, 'utf8'));
|
|
||||||
|
|
||||||
// Default to development build; use flag --release to indicate release build.
|
|
||||||
const isDevBuild = !process.argv.includes('--release');
|
|
||||||
const distDir = path.join(context.rushConfig.rushJsonFolder, 'dist');
|
|
||||||
await fs.mkdirs(distDir);
|
|
||||||
|
|
||||||
if (isDevBuild) {
|
|
||||||
// NOTE: rootPackage.name had better not have any regex metacharacters
|
|
||||||
const oldDevBuildPattern = new RegExp('^' + rootPackage.name + '[^/]+-dev[0-9.]+\\.vsix$');
|
|
||||||
// Dev package filenames are of the form
|
|
||||||
// vscode-codeql-0.0.1-dev.2019.9.27.19.55.20.vsix
|
|
||||||
(await fs.readdir(distDir)).filter(name => name.match(oldDevBuildPattern)).map(build => {
|
|
||||||
console.log(`Deleting old dev build ${build}...`);
|
|
||||||
fs.unlinkSync(path.join(distDir, build));
|
|
||||||
});
|
|
||||||
const now = new Date();
|
|
||||||
rootPackage.version = rootPackage.version +
|
|
||||||
`-dev.${now.getUTCFullYear()}.${now.getUTCMonth() + 1}.${now.getUTCDate()}` +
|
|
||||||
`.${now.getUTCHours()}.${now.getUTCMinutes()}.${now.getUTCSeconds()}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
const distPath = path.join(distDir, rootPackage.name);
|
|
||||||
await fs.remove(distPath);
|
|
||||||
await fs.mkdirs(distPath);
|
|
||||||
|
|
||||||
console.log(`Gathering transitive dependencies of package '${rootPackage.name}'...`);
|
|
||||||
const pkgs = new PackageMap();
|
|
||||||
const rootPkg = await collectPackages(context, rootPackage.name, rootPackage.version, pkgs);
|
|
||||||
rootPkg.isRoot = true;
|
|
||||||
|
|
||||||
console.log(`Copying package '${rootPackage.name}' and its dependencies to '${distPath}'...`);
|
|
||||||
await copyPackageAndModules(rootPkg, pkgs, path.dirname(distPath), path.join(distPath, 'node_modules'));
|
|
||||||
await fs.copy(path.resolve(rootPkg.sourcePath, ".vscodeignore"), path.resolve(distPath, ".vscodeignore"));
|
|
||||||
|
|
||||||
console.log(`Deduplicating dependencies of package '${rootPackage.name}'...`);
|
|
||||||
// We create a temporary `package-lock.json` file just to prevent `npm ls` from printing out the
|
|
||||||
// message that it created a package-lock.json.
|
|
||||||
const packageLockPath = path.join(distPath, 'package-lock.json');
|
|
||||||
await fs.writeFile(packageLockPath, '{}');
|
|
||||||
await cpp.spawn('npm', ['dedupe'], {
|
|
||||||
cwd: distPath,
|
|
||||||
stdio: 'inherit'
|
|
||||||
});
|
|
||||||
await fs.unlink(packageLockPath);
|
|
||||||
|
|
||||||
return {
|
|
||||||
distPath: distPath,
|
|
||||||
name: rootPackage.name,
|
|
||||||
version: rootPackage.version
|
|
||||||
};
|
|
||||||
}
|
|
||||||
catch (e) {
|
|
||||||
console.error(e);
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
export * from './package';
|
|
||||||
export * from './textmate';
|
|
||||||
export * from './typescript';
|
|
||||||
export * from './tests';
|
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
import * as path from 'path';
|
|
||||||
import { deployPackage } from './deploy';
|
|
||||||
import * as child_process from 'child-process-promise';
|
|
||||||
|
|
||||||
export async function packageExtension(): Promise<void> {
|
|
||||||
const deployedPackage = await deployPackage(path.resolve('package.json'));
|
|
||||||
console.log(`Packaging extension '${deployedPackage.name}@${deployedPackage.version}'...`);
|
|
||||||
const args = [
|
|
||||||
'package',
|
|
||||||
'--out', path.resolve(deployedPackage.distPath, '..', `${deployedPackage.name}-${deployedPackage.version}.vsix`)
|
|
||||||
];
|
|
||||||
const proc = child_process.spawn('vsce', args, {
|
|
||||||
cwd: deployedPackage.distPath
|
|
||||||
});
|
|
||||||
proc.childProcess.stdout!.on('data', (data) => {
|
|
||||||
console.log(data.toString());
|
|
||||||
});
|
|
||||||
proc.childProcess.stderr!.on('data', (data) => {
|
|
||||||
console.error(data.toString());
|
|
||||||
});
|
|
||||||
|
|
||||||
await proc;
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
export interface PackageDependencies {
|
|
||||||
[key: string]: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ShrinkwrapPackage {
|
|
||||||
dependencies?: PackageDependencies;
|
|
||||||
dev?: boolean;
|
|
||||||
name?: string;
|
|
||||||
version?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Shrinkwrap {
|
|
||||||
dependencies: PackageDependencies;
|
|
||||||
packages: {
|
|
||||||
[key: string]: ShrinkwrapPackage;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,166 +0,0 @@
|
|||||||
import * as fs from 'fs-extra';
|
|
||||||
import * as glob from 'glob-promise';
|
|
||||||
import * as jsonc from 'jsonc-parser';
|
|
||||||
import { Shrinkwrap, ShrinkwrapPackage } from './pnpm';
|
|
||||||
import * as path from 'path';
|
|
||||||
import { IPackageJson } from '@microsoft/node-core-library';
|
|
||||||
import { RushConfiguration } from '@microsoft/rush-lib';
|
|
||||||
import * as yaml from 'js-yaml';
|
|
||||||
|
|
||||||
export interface IPackageJsonWithFiles extends IPackageJson {
|
|
||||||
files?: string[]
|
|
||||||
}
|
|
||||||
|
|
||||||
interface PackageInfo {
|
|
||||||
path: string;
|
|
||||||
dependencies: Map<string, string>;
|
|
||||||
config: IPackageJsonWithFiles;
|
|
||||||
isLocal: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
const peerDependencyVersionPattern = /^\/((?:@(?:[^\/]+)\/)?[^\/]+)\/([^\/]+)\//;
|
|
||||||
|
|
||||||
export class RushContext {
|
|
||||||
private shrinkwrap?: Shrinkwrap;
|
|
||||||
private shrinkwrapPackages?: Map<string, ShrinkwrapPackage>;
|
|
||||||
private readonly packageStore: string;
|
|
||||||
|
|
||||||
constructor(public readonly rushConfig: RushConfiguration) {
|
|
||||||
this.packageStore = path.join(rushConfig.pnpmStoreFolder, '2');
|
|
||||||
}
|
|
||||||
|
|
||||||
private async findPackageInRepository(name: string, version: string): Promise<string> {
|
|
||||||
// Packages may be pulled from multiple registries, each of which has its own directory in the
|
|
||||||
// pnpm store. Search for the package name in any of these directories. We use `*.*` to match
|
|
||||||
// the directory name to avoid searching the `local` directory, which does not represent a
|
|
||||||
// package registry.
|
|
||||||
const results = await glob(`*.*/${name}/${version}/package`, {
|
|
||||||
absolute: true,
|
|
||||||
cwd: this.packageStore
|
|
||||||
});
|
|
||||||
if (results.length === 0) {
|
|
||||||
throw new Error(`Package '${name}:${version}' not found in package repository.`);
|
|
||||||
}
|
|
||||||
else if (results.length > 1) {
|
|
||||||
throw new Error(`Multiple copies of package '${name}:${version}' found in package repository.`);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return results[0];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private getRushProjectPath(name: string): string | undefined {
|
|
||||||
const project = this.rushConfig.getProjectByName(name);
|
|
||||||
if (project) {
|
|
||||||
return project.projectFolder;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private async getShrinkwrap(): Promise<Shrinkwrap> {
|
|
||||||
if (!this.shrinkwrap) {
|
|
||||||
this.shrinkwrap = yaml.safeLoad(await fs.readFile(this.rushConfig.getCommittedShrinkwrapFilename(), 'utf8'));
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.shrinkwrap!;
|
|
||||||
}
|
|
||||||
|
|
||||||
private async getShrinkwrapPackage(name: string, version: string): Promise<ShrinkwrapPackage> {
|
|
||||||
const shrinkwrap = await this.getShrinkwrap();
|
|
||||||
|
|
||||||
if (!this.shrinkwrapPackages) {
|
|
||||||
this.shrinkwrapPackages = new Map<string, ShrinkwrapPackage>();
|
|
||||||
for (const name in shrinkwrap.packages) {
|
|
||||||
const pkg = shrinkwrap.packages[name];
|
|
||||||
let packageKey: string;
|
|
||||||
if (pkg.name) {
|
|
||||||
packageKey = makePackageKey(pkg.name, pkg.version!);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
packageKey = name;
|
|
||||||
}
|
|
||||||
this.shrinkwrapPackages.set(packageKey, pkg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const packageKey = makePackageKey(name, version);
|
|
||||||
const shrinkwrapPackage = this.shrinkwrapPackages.get(packageKey);
|
|
||||||
if (!shrinkwrapPackage) {
|
|
||||||
throw new Error(`Package '${packageKey}' not found in shrinkwrap file.`);
|
|
||||||
}
|
|
||||||
return shrinkwrapPackage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public async getPackageInfo(name: string, version: string): Promise<PackageInfo> {
|
|
||||||
let pkg: ShrinkwrapPackage;
|
|
||||||
const rushProject = this.rushConfig.getProjectByName(name);
|
|
||||||
let packagePath: string;
|
|
||||||
let config: IPackageJsonWithFiles;
|
|
||||||
if (rushProject) {
|
|
||||||
packagePath = rushProject.projectFolder;
|
|
||||||
pkg = await this.getShrinkwrapPackage(rushProject.tempProjectName, '0.0.0');
|
|
||||||
config = rushProject.packageJson;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
pkg = await this.getShrinkwrapPackage(name, version);
|
|
||||||
// Ensure a proper version number. pnpm uses syntax like 3.4.0_glob@7.1.6 for peer dependencies
|
|
||||||
version = version.split('_')[0];
|
|
||||||
packagePath = await this.findPackageInRepository(name, version);
|
|
||||||
packagePath = await fs.realpath(packagePath);
|
|
||||||
config = jsonc.parse(await fs.readFile(path.join(packagePath, 'package.json'), 'utf8'));
|
|
||||||
}
|
|
||||||
|
|
||||||
const dependencies = new Map<string, string>();
|
|
||||||
if (config.dependencies) {
|
|
||||||
for (const dependencyName in config.dependencies) {
|
|
||||||
let dependencyVersion: string;
|
|
||||||
if (await this.getRushProjectPath(dependencyName)) {
|
|
||||||
dependencyVersion = '0.0.0';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
dependencyVersion = pkg.dependencies![dependencyName];
|
|
||||||
if (!dependencyVersion) {
|
|
||||||
throw new Error(`Package '${name}' depends on unresolved package '${dependencyName}'.`);
|
|
||||||
}
|
|
||||||
if (dependencyVersion.startsWith('/')) {
|
|
||||||
// This is a package with a peer dependency. We need to extract the actual package
|
|
||||||
// version.
|
|
||||||
const match = dependencyVersion.match(peerDependencyVersionPattern);
|
|
||||||
if (match) {
|
|
||||||
if (match[1] !== dependencyName) {
|
|
||||||
throw new Error(`Mismatch between package name '${dependencyName}' and peer dependency specifier '${dependencyVersion}'.`);
|
|
||||||
}
|
|
||||||
dependencyVersion = match[2];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new Error(`Invalid peer dependency specifier '${dependencyVersion}'.`);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies.set(dependencyName, dependencyVersion);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
path: packagePath,
|
|
||||||
dependencies: dependencies,
|
|
||||||
config: config,
|
|
||||||
isLocal: rushProject !== undefined
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function makePackageKey(name: string, version: string): string {
|
|
||||||
return `/${name}/${version}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getRushContext(startingFolder?: string): Promise<RushContext> {
|
|
||||||
const rushConfig = RushConfiguration.loadFromDefaultLocation({
|
|
||||||
startingFolder: startingFolder
|
|
||||||
});
|
|
||||||
|
|
||||||
return new RushContext(rushConfig);
|
|
||||||
}
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
import * as gulp from 'gulp';
|
|
||||||
|
|
||||||
export function copyTestData() {
|
|
||||||
return gulp.src('src/vscode-tests/no-workspace/data/**/*')
|
|
||||||
.pipe(gulp.dest('out/vscode-tests/no-workspace/data'));
|
|
||||||
}
|
|
||||||
@@ -1,245 +0,0 @@
|
|||||||
import * as gulp from 'gulp';
|
|
||||||
import * as js_yaml from 'js-yaml';
|
|
||||||
import * as through from 'through2';
|
|
||||||
import * as PluginError from 'plugin-error';
|
|
||||||
import * as Vinyl from 'vinyl';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Replaces all rule references with the match pattern of the referenced rule.
|
|
||||||
*
|
|
||||||
* @param value Original regex containing rule references.
|
|
||||||
* @param replacements Map from rule name to match text.
|
|
||||||
* @returns The new regex after replacement.
|
|
||||||
*/
|
|
||||||
function replaceReferencesWithStrings(value: string, replacements: Map<string, string>): string {
|
|
||||||
let result = value;
|
|
||||||
while (true) {
|
|
||||||
const original = result;
|
|
||||||
for (const key of replacements.keys()) {
|
|
||||||
result = result.replace(`(?#${key})`, `(?:${replacements.get(key)})`);
|
|
||||||
}
|
|
||||||
if (result === original) {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gather all macro definitions from the document.
|
|
||||||
*
|
|
||||||
* @param yaml The root of the YAML document.
|
|
||||||
* @returns A map from macro name to replacement text.
|
|
||||||
*/
|
|
||||||
function gatherMacros(yaml: any): Map<string, string> {
|
|
||||||
const macros = new Map<string, string>();
|
|
||||||
for (var key in yaml.macros) {
|
|
||||||
macros.set(key, yaml.macros[key]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return macros;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the match text to be substituted wherever the specified rule is referenced in a regular
|
|
||||||
* expression.
|
|
||||||
*
|
|
||||||
* @param rule The rule whose match text is to be retrieved.
|
|
||||||
* @returns The match text for the rule. This is either the value of the rule's `match` property,
|
|
||||||
* or the disjunction of the match text of all of the other rules `include`d by this rule.
|
|
||||||
*/
|
|
||||||
function getNodeMatchText(rule: any): string {
|
|
||||||
if (rule.match !== undefined) {
|
|
||||||
// For a match string, just use that string as the replacement.
|
|
||||||
return rule.match;
|
|
||||||
}
|
|
||||||
else if (rule.patterns !== undefined) {
|
|
||||||
const patterns: string[] = [];
|
|
||||||
// For a list of patterns, use the disjunction of those patterns.
|
|
||||||
for (var patternIndex in rule.patterns) {
|
|
||||||
const pattern = rule.patterns[patternIndex];
|
|
||||||
if (pattern.include !== null) {
|
|
||||||
patterns.push('(?' + pattern.include + ')');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return '(?:' + patterns.join('|') + ')';
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates a map from rule name to match text.
|
|
||||||
*
|
|
||||||
* @param yaml The root of the YAML document.
|
|
||||||
* @returns A map whose keys are the names of rules, and whose values are the corresponding match
|
|
||||||
* text of each rule.
|
|
||||||
*/
|
|
||||||
function gatherMatchTextForRules(yaml: any): Map<string, string> {
|
|
||||||
const replacements = new Map<string, string>();
|
|
||||||
for (var key in yaml.repository) {
|
|
||||||
const node = yaml.repository[key];
|
|
||||||
replacements.set(key, getNodeMatchText(node));
|
|
||||||
}
|
|
||||||
|
|
||||||
return replacements;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invoke the specified callback function on each rule definition in the file.
|
|
||||||
*
|
|
||||||
* @param yaml The root of the YAML document.
|
|
||||||
* @param action Callback to invoke on each rule.
|
|
||||||
*/
|
|
||||||
function visitAllRulesInFile(yaml: any, action: (rule: any) => void) {
|
|
||||||
visitAllRulesInRuleMap(yaml.patterns, action);
|
|
||||||
visitAllRulesInRuleMap(yaml.repository, action);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invoke the specified callback function on each rule definition in a map or array of rules.
|
|
||||||
* For rules that have a `patterns` element defined child rules, the children are included in the
|
|
||||||
* visitation.
|
|
||||||
*
|
|
||||||
* @param ruleMap The map or array of rules to visit.
|
|
||||||
* @param action Callback to invoke on each rule.
|
|
||||||
*/
|
|
||||||
function visitAllRulesInRuleMap(ruleMap: any, action: (rule: any) => void) {
|
|
||||||
for (var key in ruleMap) {
|
|
||||||
const rule = ruleMap[key];
|
|
||||||
if ((typeof rule) === 'object') {
|
|
||||||
action(rule);
|
|
||||||
if (rule.patterns !== undefined) {
|
|
||||||
visitAllRulesInRuleMap(rule.patterns, action);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Invoke the specified transformation on all match patterns in the specified rule.
|
|
||||||
*
|
|
||||||
* @param rule The rule whose matches are to be transformed.
|
|
||||||
* @param action The transformation to make on each match pattern.
|
|
||||||
*/
|
|
||||||
function visitAllMatchesInRule(rule: any, action: (match: any) => any) {
|
|
||||||
for (var key in rule) {
|
|
||||||
switch (key) {
|
|
||||||
case 'begin':
|
|
||||||
case 'end':
|
|
||||||
case 'match':
|
|
||||||
case 'while':
|
|
||||||
rule[key] = action(rule[key]);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Replace any usage of the specified `beginPattern` or `endPattern` property with the equivalent
|
|
||||||
* `begin`/`beginCaptures` or `end`/`endCaptures` properties.
|
|
||||||
*
|
|
||||||
* @param rule Rule to be transformed.
|
|
||||||
* @param key Base key of the property to be transformed.
|
|
||||||
*/
|
|
||||||
function expandPatternMatchProperties(rule: any, key: 'begin' | 'end') {
|
|
||||||
const patternKey = key + 'Pattern';
|
|
||||||
const capturesKey = key + 'Captures';
|
|
||||||
const pattern = rule[patternKey];
|
|
||||||
if (pattern !== undefined) {
|
|
||||||
const patterns: string[] = Array.isArray(pattern) ? pattern : [pattern];
|
|
||||||
rule[key] = patterns.map(p => `((?${p}))`).join('|');
|
|
||||||
const captures: { [index: string]: any } = {};
|
|
||||||
for (const patternIndex in patterns) {
|
|
||||||
captures[(Number(patternIndex) + 1).toString()] = {
|
|
||||||
patterns: [
|
|
||||||
{
|
|
||||||
include: patterns[patternIndex]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
rule[capturesKey] = captures;
|
|
||||||
rule[patternKey] = undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Transform the specified document to produce a TextMate grammar.
|
|
||||||
*
|
|
||||||
* @param yaml The root of the YAML document.
|
|
||||||
*/
|
|
||||||
function transformFile(yaml: any) {
|
|
||||||
const macros = gatherMacros(yaml);
|
|
||||||
visitAllRulesInFile(yaml, (rule) => {
|
|
||||||
expandPatternMatchProperties(rule, 'begin');
|
|
||||||
expandPatternMatchProperties(rule, 'end');
|
|
||||||
});
|
|
||||||
|
|
||||||
// Expand macros in matches.
|
|
||||||
visitAllRulesInFile(yaml, (rule) => {
|
|
||||||
visitAllMatchesInRule(rule, (match) => {
|
|
||||||
if ((typeof match) === 'object') {
|
|
||||||
for (var key in match) {
|
|
||||||
return macros.get(key)!.replace('(?#)', `(?:${match[key]})`);
|
|
||||||
}
|
|
||||||
throw new Error("No key in macro map.")
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return match;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
yaml.macros = undefined;
|
|
||||||
|
|
||||||
const replacements = gatherMatchTextForRules(yaml);
|
|
||||||
// Expand references in matches.
|
|
||||||
visitAllRulesInFile(yaml, (rule) => {
|
|
||||||
visitAllMatchesInRule(rule, (match) => {
|
|
||||||
return replaceReferencesWithStrings(match, replacements);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
if (yaml.regexOptions !== undefined) {
|
|
||||||
const regexOptions = '(?' + yaml.regexOptions + ')';
|
|
||||||
visitAllRulesInFile(yaml, (rule) => {
|
|
||||||
visitAllMatchesInRule(rule, (match) => {
|
|
||||||
return regexOptions + match;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
yaml.regexOptions = undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function transpileTextMateGrammar() {
|
|
||||||
return through.obj((file: Vinyl, _encoding: string, callback: Function): void => {
|
|
||||||
if (file.isNull()) {
|
|
||||||
callback(null, file);
|
|
||||||
}
|
|
||||||
else if (file.isBuffer()) {
|
|
||||||
const buf: Buffer = file.contents;
|
|
||||||
const yamlText: string = buf.toString('utf8');
|
|
||||||
const jsonData: any = js_yaml.safeLoad(yamlText);
|
|
||||||
transformFile(jsonData);
|
|
||||||
|
|
||||||
file.contents = Buffer.from(JSON.stringify(jsonData, null, 2), 'utf8');
|
|
||||||
file.extname = '.json';
|
|
||||||
callback(null, file);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
callback('error', new PluginError('transpileTextMateGrammar', 'Format not supported.'));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function compileTextMateGrammar() {
|
|
||||||
return gulp.src('syntaxes/*.tmLanguage.yml')
|
|
||||||
.pipe(transpileTextMateGrammar())
|
|
||||||
.pipe(gulp.dest('out/syntaxes'));
|
|
||||||
}
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
import * as colors from 'ansi-colors';
|
|
||||||
import * as gulp from 'gulp';
|
|
||||||
import * as path from 'path';
|
|
||||||
import * as sourcemaps from 'gulp-sourcemaps';
|
|
||||||
import * as ts from 'gulp-typescript';
|
|
||||||
import { RushConfiguration } from '@microsoft/rush-lib';
|
|
||||||
|
|
||||||
function goodReporter(): ts.reporter.Reporter {
|
|
||||||
return {
|
|
||||||
error: (error, typescript) => {
|
|
||||||
if (error.tsFile) {
|
|
||||||
console.log('[' + colors.gray('gulp-typescript') + '] ' + colors.red(error.fullFilename
|
|
||||||
+ '(' + (error.startPosition!.line + 1) + ',' + error.startPosition!.character + '): ')
|
|
||||||
+ 'error TS' + error.diagnostic.code + ': ' + typescript.flattenDiagnosticMessageText(error.diagnostic.messageText, '\n'));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
console.log(error.message);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const tsProject = ts.createProject('tsconfig.json');
|
|
||||||
|
|
||||||
export function compileTypeScript() {
|
|
||||||
// Find this project's relative directory. Rush already knows this, so just ask.
|
|
||||||
const packageDir = path.resolve('.');
|
|
||||||
const rushConfig = RushConfiguration.loadFromDefaultLocation({
|
|
||||||
startingFolder: packageDir
|
|
||||||
});
|
|
||||||
const project = rushConfig.tryGetProjectForPath(packageDir);
|
|
||||||
if (!project) {
|
|
||||||
console.error(`Unable to find project for '${packageDir}' in 'rush.json'.`);
|
|
||||||
throw Error();
|
|
||||||
}
|
|
||||||
|
|
||||||
//REVIEW: Better way to detect deployable projects?
|
|
||||||
// Since extension .js files are deployed to 'dist/<package>/out', and libraries are deployed to
|
|
||||||
// 'dist/<app package>/node_modules/<package>/out'.
|
|
||||||
const pathToRoot = (path.dirname(project.projectRelativeFolder) === 'extensions') ?
|
|
||||||
'../../..' : '../../../../..';
|
|
||||||
|
|
||||||
return tsProject.src()
|
|
||||||
.pipe(sourcemaps.init())
|
|
||||||
.pipe(tsProject(goodReporter()))
|
|
||||||
.pipe(sourcemaps.mapSources((sourcePath, _file) => {
|
|
||||||
// The source path is kind of odd, because it's relative to the `tsconfig.json` file in the
|
|
||||||
// `typescript-config` package, which lives in the `node_modules` directory of the package
|
|
||||||
// that is being built. It starts out as something like '../../../src/foo.ts', and we need to
|
|
||||||
// strip out the leading '../../../'.
|
|
||||||
return path.join('a/b/c', sourcePath);
|
|
||||||
}))
|
|
||||||
.pipe(sourcemaps.write('.', {
|
|
||||||
includeContent: false,
|
|
||||||
sourceRoot: path.join(pathToRoot, project.projectRelativeFolder)
|
|
||||||
}))
|
|
||||||
.pipe(gulp.dest('out'));
|
|
||||||
}
|
|
||||||
|
|
||||||
export function watchTypeScript() {
|
|
||||||
gulp.watch('src/**/*.ts', compileTypeScript);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Copy CSS files for the results view into the output directory. */
|
|
||||||
export function copyViewCss() {
|
|
||||||
return gulp.src('src/view/*.css')
|
|
||||||
.pipe(gulp.dest('out'));
|
|
||||||
}
|
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
{
|
|
||||||
"compilerOptions": {
|
|
||||||
"declaration": true,
|
|
||||||
"module": "commonjs",
|
|
||||||
"target": "es2017",
|
|
||||||
"outDir": "out",
|
|
||||||
"lib": [
|
|
||||||
"es6"
|
|
||||||
],
|
|
||||||
"moduleResolution": "node",
|
|
||||||
"sourceMap": true,
|
|
||||||
"rootDir": "src",
|
|
||||||
"strictNullChecks": true,
|
|
||||||
"noFallthroughCasesInSwitch": true,
|
|
||||||
"preserveWatchOutput": true,
|
|
||||||
"newLine": "lf",
|
|
||||||
"noImplicitReturns": true,
|
|
||||||
"experimentalDecorators": true,
|
|
||||||
"noUnusedLocals": true,
|
|
||||||
"noUnusedParameters": true
|
|
||||||
},
|
|
||||||
"include": [
|
|
||||||
"src/**/*.ts"
|
|
||||||
],
|
|
||||||
"exclude": [
|
|
||||||
"node_modules",
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{}
|
|
||||||
Reference in New Issue
Block a user