using to rush.io
This commit is contained in:
Родитель
62125037c4
Коммит
b76c9f82cc
|
@ -0,0 +1,5 @@
|
|||
# Don't allow people to merge changes to these generated files, because the result
|
||||
# may be invalid. You need to run "rush update" again.
|
||||
shrinkwrap.yaml merge=binary
|
||||
npm-shrinkwrap.json merge=binary
|
||||
yarn.lock merge=binary
|
|
@ -0,0 +1,12 @@
|
|||
# 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
|
|
@ -0,0 +1,177 @@
|
|||
/**
|
||||
* This configuration file defines custom commands for the "rush" command-line.
|
||||
* For full documentation, please see https://rushjs.io
|
||||
*/
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/command-line.schema.json",
|
||||
|
||||
/**
|
||||
* Custom "commands" introduce new verbs for the command-line. To see the help for these
|
||||
* example commands, try "rush --help", "rush my-bulk-command --help", or
|
||||
* "rush my-global-command --help".
|
||||
*/
|
||||
"commands": [
|
||||
// {
|
||||
// /**
|
||||
// * (Required) Determines the type of custom command.
|
||||
// * Rush's "bulk" commands are invoked separately for each project. Rush will look in
|
||||
// * each project's package.json file for a "scripts" entry whose name matches the
|
||||
// * command name. By default, the command will run for every project in the repo,
|
||||
// * according to the dependency graph (similar to how "rush build" works).
|
||||
// * The set of projects can be restricted e.g. using the "--to" or "--from" parameters.
|
||||
// */
|
||||
// "commandKind": "bulk",
|
||||
//
|
||||
// /**
|
||||
// * (Required) The name that will be typed as part of the command line. This is also the name
|
||||
// * of the "scripts" hook in the project's package.json file.
|
||||
// * The name should be comprised of lower case words separated by hyphens.
|
||||
// */
|
||||
// "name": "my-bulk-command",
|
||||
//
|
||||
// /**
|
||||
// * (Required) A short summary of the custom command to be shown when printing command line
|
||||
// * help, e.g. "rush --help".
|
||||
// */
|
||||
// "summary": "Example bulk custom command",
|
||||
//
|
||||
// /**
|
||||
// * A detailed description of the command to be shown when printing command line
|
||||
// * help (e.g. "rush --help my-command").
|
||||
// * If omitted, the "summary" text will be shown instead.
|
||||
// *
|
||||
// * Whenever you introduce commands/parameters, taking a little time to write meaningful
|
||||
// * documentation can make a big difference for the developer experience in your repo.
|
||||
// */
|
||||
// "description": "This is an example custom command that runs separately for each project",
|
||||
//
|
||||
// /**
|
||||
// * (Required) If true, then this command is safe to be run in parallel, i.e. executed
|
||||
// * simultaneously for multiple projects. Similar to "rush build", regardless of parallelism
|
||||
// * projects will not start processing until their dependencies have completed processing.
|
||||
// */
|
||||
// "enableParallelism": false,
|
||||
//
|
||||
// /**
|
||||
// * Normally Rush requires that each project's package.json has a "scripts" entry matching
|
||||
// * the custom command name. To disable this check, set "ignoreMissingScript" to true;
|
||||
// * projects with a missing definition will be skipped.
|
||||
// */
|
||||
// "ignoreMissingScript": false
|
||||
// },
|
||||
//
|
||||
// {
|
||||
// /**
|
||||
// * (Required) Determines the type of custom command.
|
||||
// * Rush's "global" commands are invoked once for the entire repo.
|
||||
// */
|
||||
// "commandKind": "global",
|
||||
//
|
||||
// "name": "my-global-command",
|
||||
// "summary": "Example global custom command",
|
||||
// "description": "This is an example custom command that runs once for the entire repo",
|
||||
//
|
||||
// /**
|
||||
// * A script that will be invoked using the OS shell. The working directory will be the folder
|
||||
// * that contains rush.json. If custom parameters are associated with this command, their
|
||||
// * values will be appended to the end of this string.
|
||||
// */
|
||||
// "shellCommand": "node common/scripts/my-global-command.js"
|
||||
// }
|
||||
],
|
||||
|
||||
/**
|
||||
* Custom "parameters" introduce new parameters for specified Rush command-line commands.
|
||||
* For example, you might define a "--production" parameter for the "rush build" command.
|
||||
*/
|
||||
"parameters": [
|
||||
// {
|
||||
// /**
|
||||
// * (Required) Determines the type of custom parameter.
|
||||
// * A "flag" is a custom command-line parameter whose presence acts as an on/off switch.
|
||||
// */
|
||||
// "parameterKind": "flag",
|
||||
//
|
||||
// /**
|
||||
// * (Required) The long name of the parameter. It must be lower-case and use dash delimiters.
|
||||
// */
|
||||
// "longName": "--my-flag",
|
||||
//
|
||||
// /**
|
||||
// * An optional alternative short name for the parameter. It must be a dash followed by a single
|
||||
// * lower-case or upper-case letter, which is case-sensitive.
|
||||
// *
|
||||
// * NOTE: The Rush developers recommend that automation scripts should always use the long name
|
||||
// * to improve readability. The short name is only intended as a convenience for humans.
|
||||
// * The alphabet letters run out quickly, and are difficult to memorize, so *only* use
|
||||
// * a short name if you expect the parameter to be needed very often in everyday operations.
|
||||
// */
|
||||
// "shortName": "-m",
|
||||
//
|
||||
// /**
|
||||
// * (Required) A long description to be shown in the command-line help.
|
||||
// *
|
||||
// * Whenever you introduce commands/parameters, taking a little time to write meaningful
|
||||
// * documentation can make a big difference for the developer experience in your repo.
|
||||
// */
|
||||
// "description": "A custom flag parameter that is passed to the scripts that are invoked when building projects",
|
||||
//
|
||||
// /**
|
||||
// * (Required) A list of custom commands and/or built-in Rush commands that this parameter may
|
||||
// * be used with. The parameter will be appended to the shell command that Rush invokes.
|
||||
// */
|
||||
// "associatedCommands": [ "build", "rebuild" ]
|
||||
// },
|
||||
//
|
||||
// {
|
||||
// /**
|
||||
// * (Required) Determines the type of custom parameter.
|
||||
// * A "flag" is a custom command-line parameter whose presence acts as an on/off switch.
|
||||
// */
|
||||
// "parameterKind": "choice",
|
||||
// "longName": "--my-choice",
|
||||
// "description": "A custom choice parameter for the \"my-global-command\" custom command",
|
||||
//
|
||||
// "associatedCommands": [ "my-global-command" ],
|
||||
//
|
||||
// /**
|
||||
// * Normally if a parameter is omitted from the command line, it will not be passed
|
||||
// * to the shell command. this value will be inserted by default. Whereas if a "defaultValue"
|
||||
// * is defined, the parameter will always be passed to the shell command, and will use the
|
||||
// * default value if unspecified. The value must be one of the defined alternatives.
|
||||
// */
|
||||
// "defaultValue": "vanilla",
|
||||
//
|
||||
// /**
|
||||
// * (Required) A list of alternative argument values that can be chosen for this parameter.
|
||||
// */
|
||||
// "alternatives": [
|
||||
// {
|
||||
// /**
|
||||
// * A token that is one of the alternatives that can be used with the choice parameter,
|
||||
// * e.g. "vanilla" in "--flavor vanilla".
|
||||
// */
|
||||
// "name": "vanilla",
|
||||
//
|
||||
// /**
|
||||
// * A detailed description for the alternative that can be shown in the command-line help.
|
||||
// *
|
||||
// * Whenever you introduce commands/parameters, taking a little time to write meaningful
|
||||
// * documentation can make a big difference for the developer experience in your repo.
|
||||
// */
|
||||
// "description": "Use the vanilla flavor (the default)"
|
||||
// },
|
||||
//
|
||||
// {
|
||||
// "name": "chocolate",
|
||||
// "description": "Use the chocolate flavor"
|
||||
// },
|
||||
//
|
||||
// {
|
||||
// "name": "strawberry",
|
||||
// "description": "Use the strawberry flavor"
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
]
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
/**
|
||||
* 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"
|
||||
// ]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
"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) {
|
||||
|
||||
// // The karma types have a missing dependency on typings from the log4js package.
|
||||
// if (packageJson.name === '@types/karma') {
|
||||
// context.log('Fixed up dependencies for @types/karma');
|
||||
// packageJson.dependencies['log4js'] = '0.6.38';
|
||||
// }
|
||||
|
||||
return packageJson;
|
||||
}
|
|
@ -0,0 +1,690 @@
|
|||
dependencies:
|
||||
'@rush-temp/tasks': 'file:projects/tasks.tgz'
|
||||
'@types/mocha': 5.2.5
|
||||
'@types/node': 10.11.3
|
||||
mocha: 5.2.0
|
||||
mocha-typescript: 1.1.17
|
||||
source-map-support: 0.5.9
|
||||
typescript: 3.1.1
|
||||
packages:
|
||||
/@types/mocha/5.2.5:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha512-lAVp+Kj54ui/vLUFxsJTMtWvZraZxum3w3Nwkble2dNuV5VnPA+Mi2oGX9XYJAaIvZi3tn3cbjS/qcJXRb6Bww==
|
||||
/@types/node/10.11.3:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha512-3AvcEJAh9EMatxs+OxAlvAEs7OTy6AG94mcH1iqyVDwVVndekLxzwkWQ/Z4SDbY6GO2oyUXyWW8tQ4rENSSQVQ==
|
||||
/ansi-regex/2.1.1:
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=0.10.0'
|
||||
resolution:
|
||||
integrity: sha1-w7M6te42DYbg5ijwRorn7yfWVN8=
|
||||
/ansi-regex/3.0.0:
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=4'
|
||||
resolution:
|
||||
integrity: sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=
|
||||
/ansi-styles/3.2.1:
|
||||
dependencies:
|
||||
color-convert: 1.9.3
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=4'
|
||||
resolution:
|
||||
integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
|
||||
/balanced-match/1.0.0:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
|
||||
/brace-expansion/1.1.11:
|
||||
dependencies:
|
||||
balanced-match: 1.0.0
|
||||
concat-map: 0.0.1
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==
|
||||
/browser-stdout/1.3.1:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==
|
||||
/buffer-from/1.1.1:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
|
||||
/camelcase/4.1.0:
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=4'
|
||||
resolution:
|
||||
integrity: sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=
|
||||
/chalk/2.4.1:
|
||||
dependencies:
|
||||
ansi-styles: 3.2.1
|
||||
escape-string-regexp: 1.0.5
|
||||
supports-color: 5.5.0
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=4'
|
||||
resolution:
|
||||
integrity: sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==
|
||||
/cliui/4.1.0:
|
||||
dependencies:
|
||||
string-width: 2.1.1
|
||||
strip-ansi: 4.0.0
|
||||
wrap-ansi: 2.1.0
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==
|
||||
/code-point-at/1.1.0:
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=0.10.0'
|
||||
resolution:
|
||||
integrity: sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=
|
||||
/color-convert/1.9.3:
|
||||
dependencies:
|
||||
color-name: 1.1.3
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
|
||||
/color-name/1.1.3:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
|
||||
/commander/2.15.1:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==
|
||||
tarball: 'http://registry.npmjs.org/commander/-/commander-2.15.1.tgz'
|
||||
/concat-map/0.0.1:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
|
||||
/cross-spawn/5.1.0:
|
||||
dependencies:
|
||||
lru-cache: 4.1.3
|
||||
shebang-command: 1.2.0
|
||||
which: 1.3.1
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=
|
||||
/cross-spawn/6.0.5:
|
||||
dependencies:
|
||||
nice-try: 1.0.5
|
||||
path-key: 2.0.1
|
||||
semver: 5.5.1
|
||||
shebang-command: 1.2.0
|
||||
which: 1.3.1
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=4.8'
|
||||
resolution:
|
||||
integrity: sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==
|
||||
/debug/3.1.0:
|
||||
dependencies:
|
||||
ms: 2.0.0
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==
|
||||
/decamelize/1.2.0:
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=0.10.0'
|
||||
resolution:
|
||||
integrity: sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=
|
||||
/diff/3.5.0:
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=0.3.1'
|
||||
resolution:
|
||||
integrity: sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==
|
||||
/es6-object-assign/1.1.0:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha1-wsNYJlYkfDnqEHyx5mUrb58kUjw=
|
||||
/escape-string-regexp/1.0.5:
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=0.8.0'
|
||||
resolution:
|
||||
integrity: sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
|
||||
/execa/0.7.0:
|
||||
dependencies:
|
||||
cross-spawn: 5.1.0
|
||||
get-stream: 3.0.0
|
||||
is-stream: 1.1.0
|
||||
npm-run-path: 2.0.2
|
||||
p-finally: 1.0.0
|
||||
signal-exit: 3.0.2
|
||||
strip-eof: 1.0.0
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=4'
|
||||
resolution:
|
||||
integrity: sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=
|
||||
/find-up/2.1.0:
|
||||
dependencies:
|
||||
locate-path: 2.0.0
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=4'
|
||||
resolution:
|
||||
integrity: sha1-RdG35QbHF93UgndaK3eSCjwMV6c=
|
||||
/fs.realpath/1.0.0:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
|
||||
/get-caller-file/1.0.3:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==
|
||||
/get-stream/3.0.0:
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=4'
|
||||
resolution:
|
||||
integrity: sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=
|
||||
tarball: 'http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz'
|
||||
/glob/7.1.2:
|
||||
dependencies:
|
||||
fs.realpath: 1.0.0
|
||||
inflight: 1.0.6
|
||||
inherits: 2.0.3
|
||||
minimatch: 3.0.4
|
||||
once: 1.4.0
|
||||
path-is-absolute: 1.0.1
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==
|
||||
/glob/7.1.3:
|
||||
dependencies:
|
||||
fs.realpath: 1.0.0
|
||||
inflight: 1.0.6
|
||||
inherits: 2.0.3
|
||||
minimatch: 3.0.4
|
||||
once: 1.4.0
|
||||
path-is-absolute: 1.0.1
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==
|
||||
/growl/1.10.5:
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=4.x'
|
||||
resolution:
|
||||
integrity: sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==
|
||||
/has-flag/3.0.0:
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=4'
|
||||
resolution:
|
||||
integrity: sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
|
||||
/he/1.1.1:
|
||||
dev: false
|
||||
hasBin: true
|
||||
resolution:
|
||||
integrity: sha1-k0EP0hsAlzUVH4howvJx80J+I/0=
|
||||
/inflight/1.0.6:
|
||||
dependencies:
|
||||
once: 1.4.0
|
||||
wrappy: 1.0.2
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
|
||||
/inherits/2.0.3:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
|
||||
/interpret/1.1.0:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=
|
||||
/invert-kv/1.0.0:
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=0.10.0'
|
||||
resolution:
|
||||
integrity: sha1-EEqOSqym09jNFXqO+L+rLXo//bY=
|
||||
/is-fullwidth-code-point/1.0.0:
|
||||
dependencies:
|
||||
number-is-nan: 1.0.1
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=0.10.0'
|
||||
resolution:
|
||||
integrity: sha1-754xOG8DGn8NZDr4L95QxFfvAMs=
|
||||
/is-fullwidth-code-point/2.0.0:
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=4'
|
||||
resolution:
|
||||
integrity: sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=
|
||||
/is-stream/1.1.0:
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=0.10.0'
|
||||
resolution:
|
||||
integrity: sha1-EtSj3U5o4Lec6428hBc66A2RykQ=
|
||||
/isexe/2.0.0:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
|
||||
/lcid/1.0.0:
|
||||
dependencies:
|
||||
invert-kv: 1.0.0
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=0.10.0'
|
||||
resolution:
|
||||
integrity: sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=
|
||||
/locate-path/2.0.0:
|
||||
dependencies:
|
||||
p-locate: 2.0.0
|
||||
path-exists: 3.0.0
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=4'
|
||||
resolution:
|
||||
integrity: sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=
|
||||
/lru-cache/4.1.3:
|
||||
dependencies:
|
||||
pseudomap: 1.0.2
|
||||
yallist: 2.1.2
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==
|
||||
/mem/1.1.0:
|
||||
dependencies:
|
||||
mimic-fn: 1.2.0
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=4'
|
||||
resolution:
|
||||
integrity: sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=
|
||||
/mimic-fn/1.2.0:
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=4'
|
||||
resolution:
|
||||
integrity: sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==
|
||||
/minimatch/3.0.4:
|
||||
dependencies:
|
||||
brace-expansion: 1.1.11
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
|
||||
/minimist/0.0.8:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=
|
||||
tarball: 'http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz'
|
||||
/minimist/1.2.0:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=
|
||||
tarball: 'http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz'
|
||||
/mkdirp/0.5.1:
|
||||
dependencies:
|
||||
minimist: 0.0.8
|
||||
dev: false
|
||||
hasBin: true
|
||||
resolution:
|
||||
integrity: sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=
|
||||
tarball: 'http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz'
|
||||
/mocha-typescript/1.1.17:
|
||||
dependencies:
|
||||
'@types/mocha': 5.2.5
|
||||
chalk: 2.4.1
|
||||
cross-spawn: 6.0.5
|
||||
yargs: 11.1.0
|
||||
dev: false
|
||||
hasBin: true
|
||||
resolution:
|
||||
integrity: sha512-Ge6pCQkZumkkhxVNdAf3JxunskShgaynCb30HYD7TT1Yhog/7NW2+6w5RcRHI+nuQrCMTX6z1+qf2pD8qwCoQA==
|
||||
/mocha/5.2.0:
|
||||
dependencies:
|
||||
browser-stdout: 1.3.1
|
||||
commander: 2.15.1
|
||||
debug: 3.1.0
|
||||
diff: 3.5.0
|
||||
escape-string-regexp: 1.0.5
|
||||
glob: 7.1.2
|
||||
growl: 1.10.5
|
||||
he: 1.1.1
|
||||
minimatch: 3.0.4
|
||||
mkdirp: 0.5.1
|
||||
supports-color: 5.4.0
|
||||
dev: false
|
||||
engines:
|
||||
node: '>= 4.0.0'
|
||||
hasBin: true
|
||||
resolution:
|
||||
integrity: sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==
|
||||
/ms/2.0.0:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
|
||||
/nice-try/1.0.5:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
|
||||
/npm-run-path/2.0.2:
|
||||
dependencies:
|
||||
path-key: 2.0.1
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=4'
|
||||
resolution:
|
||||
integrity: sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=
|
||||
/number-is-nan/1.0.1:
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=0.10.0'
|
||||
resolution:
|
||||
integrity: sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=
|
||||
/once/1.4.0:
|
||||
dependencies:
|
||||
wrappy: 1.0.2
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
|
||||
/os-locale/2.1.0:
|
||||
dependencies:
|
||||
execa: 0.7.0
|
||||
lcid: 1.0.0
|
||||
mem: 1.1.0
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=4'
|
||||
resolution:
|
||||
integrity: sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==
|
||||
/p-finally/1.0.0:
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=4'
|
||||
resolution:
|
||||
integrity: sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=
|
||||
/p-limit/1.3.0:
|
||||
dependencies:
|
||||
p-try: 1.0.0
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=4'
|
||||
resolution:
|
||||
integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==
|
||||
/p-locate/2.0.0:
|
||||
dependencies:
|
||||
p-limit: 1.3.0
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=4'
|
||||
resolution:
|
||||
integrity: sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=
|
||||
/p-try/1.0.0:
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=4'
|
||||
resolution:
|
||||
integrity: sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=
|
||||
/path-exists/3.0.0:
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=4'
|
||||
resolution:
|
||||
integrity: sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=
|
||||
/path-is-absolute/1.0.1:
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=0.10.0'
|
||||
resolution:
|
||||
integrity: sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
|
||||
/path-key/2.0.1:
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=4'
|
||||
resolution:
|
||||
integrity: sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=
|
||||
/path-parse/1.0.6:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==
|
||||
/pseudomap/1.0.2:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha1-8FKijacOYYkX7wqKw0wa5aaChrM=
|
||||
/rechoir/0.6.2:
|
||||
dependencies:
|
||||
resolve: 1.8.1
|
||||
dev: false
|
||||
engines:
|
||||
node: '>= 0.10'
|
||||
resolution:
|
||||
integrity: sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=
|
||||
/require-directory/2.1.1:
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=0.10.0'
|
||||
resolution:
|
||||
integrity: sha1-jGStX9MNqxyXbiNE/+f3kqam30I=
|
||||
/require-main-filename/1.0.1:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=
|
||||
/resolve/1.8.1:
|
||||
dependencies:
|
||||
path-parse: 1.0.6
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==
|
||||
/semver/5.5.1:
|
||||
dev: false
|
||||
hasBin: true
|
||||
resolution:
|
||||
integrity: sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw==
|
||||
/set-blocking/2.0.0:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha1-BF+XgtARrppoA93TgrJDkrPYkPc=
|
||||
/shebang-command/1.2.0:
|
||||
dependencies:
|
||||
shebang-regex: 1.0.0
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=0.10.0'
|
||||
resolution:
|
||||
integrity: sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=
|
||||
/shebang-regex/1.0.0:
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=0.10.0'
|
||||
resolution:
|
||||
integrity: sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=
|
||||
/shelljs/0.7.8:
|
||||
dependencies:
|
||||
glob: 7.1.3
|
||||
interpret: 1.1.0
|
||||
rechoir: 0.6.2
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=0.11.0'
|
||||
hasBin: true
|
||||
resolution:
|
||||
integrity: sha1-3svPh0sNHl+3LhSxZKloMEjprLM=
|
||||
/shx/0.2.2:
|
||||
dependencies:
|
||||
es6-object-assign: 1.1.0
|
||||
minimist: 1.2.0
|
||||
shelljs: 0.7.8
|
||||
dev: false
|
||||
hasBin: true
|
||||
resolution:
|
||||
integrity: sha1-CjBNAgsO3xMGrYFXDoDwNG31ijk=
|
||||
/signal-exit/3.0.2:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=
|
||||
/source-map-support/0.5.9:
|
||||
dependencies:
|
||||
buffer-from: 1.1.1
|
||||
source-map: 0.6.1
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha512-gR6Rw4MvUlYy83vP0vxoVNzM6t8MUXqNuRsuBmBHQDu1Fh6X015FrLdgoDKcNdkwGubozq0P4N0Q37UyFVr1EA==
|
||||
/source-map/0.6.1:
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=0.10.0'
|
||||
resolution:
|
||||
integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
|
||||
/string-width/1.0.2:
|
||||
dependencies:
|
||||
code-point-at: 1.1.0
|
||||
is-fullwidth-code-point: 1.0.0
|
||||
strip-ansi: 3.0.1
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=0.10.0'
|
||||
resolution:
|
||||
integrity: sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=
|
||||
/string-width/2.1.1:
|
||||
dependencies:
|
||||
is-fullwidth-code-point: 2.0.0
|
||||
strip-ansi: 4.0.0
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=4'
|
||||
resolution:
|
||||
integrity: sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==
|
||||
/strip-ansi/3.0.1:
|
||||
dependencies:
|
||||
ansi-regex: 2.1.1
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=0.10.0'
|
||||
resolution:
|
||||
integrity: sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=
|
||||
tarball: 'http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz'
|
||||
/strip-ansi/4.0.0:
|
||||
dependencies:
|
||||
ansi-regex: 3.0.0
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=4'
|
||||
resolution:
|
||||
integrity: sha1-qEeQIusaw2iocTibY1JixQXuNo8=
|
||||
/strip-eof/1.0.0:
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=0.10.0'
|
||||
resolution:
|
||||
integrity: sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=
|
||||
/supports-color/5.4.0:
|
||||
dependencies:
|
||||
has-flag: 3.0.0
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=4'
|
||||
resolution:
|
||||
integrity: sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==
|
||||
/supports-color/5.5.0:
|
||||
dependencies:
|
||||
has-flag: 3.0.0
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=4'
|
||||
resolution:
|
||||
integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
|
||||
/typescript/3.1.1:
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=4.2.0'
|
||||
hasBin: true
|
||||
resolution:
|
||||
integrity: sha512-Veu0w4dTc/9wlWNf2jeRInNodKlcdLgemvPsrNpfu5Pq39sgfFjvIIgTsvUHCoLBnMhPoUA+tFxsXjU6VexVRQ==
|
||||
/which-module/2.0.0:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=
|
||||
/which/1.3.1:
|
||||
dependencies:
|
||||
isexe: 2.0.0
|
||||
dev: false
|
||||
hasBin: true
|
||||
resolution:
|
||||
integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==
|
||||
/wrap-ansi/2.1.0:
|
||||
dependencies:
|
||||
string-width: 1.0.2
|
||||
strip-ansi: 3.0.1
|
||||
dev: false
|
||||
engines:
|
||||
node: '>=0.10.0'
|
||||
resolution:
|
||||
integrity: sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=
|
||||
tarball: 'http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz'
|
||||
/wrappy/1.0.2:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
|
||||
/y18n/3.2.1:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha1-bRX7qITAhnnA136I53WegR4H+kE=
|
||||
/yallist/2.1.2:
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=
|
||||
/yargs-parser/9.0.2:
|
||||
dependencies:
|
||||
camelcase: 4.1.0
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=
|
||||
/yargs/11.1.0:
|
||||
dependencies:
|
||||
cliui: 4.1.0
|
||||
decamelize: 1.2.0
|
||||
find-up: 2.1.0
|
||||
get-caller-file: 1.0.3
|
||||
os-locale: 2.1.0
|
||||
require-directory: 2.1.1
|
||||
require-main-filename: 1.0.1
|
||||
set-blocking: 2.0.0
|
||||
string-width: 2.1.1
|
||||
which-module: 2.0.0
|
||||
y18n: 3.2.1
|
||||
yargs-parser: 9.0.2
|
||||
dev: false
|
||||
resolution:
|
||||
integrity: sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==
|
||||
tarball: 'http://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz'
|
||||
'file:projects/tasks.tgz':
|
||||
dependencies:
|
||||
'@types/mocha': 5.2.5
|
||||
'@types/node': 10.11.3
|
||||
mocha: 5.2.0
|
||||
mocha-typescript: 1.1.17
|
||||
semver: 5.5.1
|
||||
shx: 0.2.2
|
||||
source-map-support: 0.5.9
|
||||
typescript: 3.1.1
|
||||
dev: false
|
||||
name: '@rush-temp/tasks'
|
||||
resolution:
|
||||
integrity: sha512-g9hzjCvZjH9YxJc/75moXJAgS4jhT9SWmfh7VRdNeLz8glSBwYAnGO8O+UcYOuRNuoClz1ts+YvpUXYA7anN5A==
|
||||
tarball: 'file:projects/tasks.tgz'
|
||||
version: 0.0.0
|
||||
registry: 'https://registry.npmjs.org/'
|
||||
shrinkwrapMinorVersion: 9
|
||||
shrinkwrapVersion: 3
|
||||
specifiers:
|
||||
'@rush-temp/tasks': 'file:./projects/tasks.tgz'
|
||||
'@types/mocha': 5.2.5
|
||||
'@types/node': 10.11.3
|
||||
mocha: 5.2.0
|
||||
mocha-typescript: 1.1.17
|
||||
source-map-support: 0.5.9
|
||||
typescript: ^3.1.1
|
|
@ -0,0 +1,81 @@
|
|||
/**
|
||||
* This is configuration file is used for advanced publishing configurations with Rush.
|
||||
* For full documentation, please see https://rushjs.io
|
||||
*/
|
||||
|
||||
/**
|
||||
* A list of version policy definitions. A "version policy" is a custom package versioning
|
||||
* strategy that affets "rush change", "rush version", and "rush publish". The strategy applies
|
||||
* to a set of projects that are specified using the "versionPolicyName" field in rush.json.
|
||||
*/
|
||||
[
|
||||
// {
|
||||
// /**
|
||||
// * (Required) Indicates the kind of version policy being defined ("lockStepVersion" or "individualVersion").
|
||||
// *
|
||||
// * The "lockStepVersion" mode specifies that the projects will use "lock-step versioning". This
|
||||
// * strategy is appropriate for a set of packages that act as selectable components of a
|
||||
// * unified product. The entire set of packages are always published together, and always share
|
||||
// * the same NPM version number. When the packages depend on other packages in the set, the
|
||||
// * SemVer range is usually restricted to a single version.
|
||||
// */
|
||||
// "definitionName": "lockStepVersion",
|
||||
//
|
||||
// /**
|
||||
// * (Required) The name that will be used for the "versionPolicyName" field in rush.json.
|
||||
// * This name is also used command-line parameters such as "--version-policy"
|
||||
// * and "--to-version-policy".
|
||||
// */
|
||||
// "policyName": "MyBigFramework",
|
||||
//
|
||||
// /**
|
||||
// * (Required) The current version. All packages belonging to the set should have this version
|
||||
// * in the current branch. When bumping versions, Rush uses this to determine the next version.
|
||||
// * (The "version" field in package.json is NOT considered.)
|
||||
// */
|
||||
// "version": "1.0.0",
|
||||
//
|
||||
// /**
|
||||
// * (Required) The type of bump that will be performed when publishing the next release.
|
||||
// * When creating a release branch in Git, this field should be updated according to the
|
||||
// * type of release.
|
||||
// *
|
||||
// * Valid values are: "prerelease", "release", "minor", "patch", "major"
|
||||
// */
|
||||
// "nextBump": "prerelease",
|
||||
//
|
||||
// /**
|
||||
// * (Optional) If specified, all packages in the set share a common CHANGELOG.md file.
|
||||
// * This file is stored with the specified "main" project, which must be a member of the set.
|
||||
// *
|
||||
// * If this field is omitted, then a separate CHANGELOG.md file will be maintained for each
|
||||
// * package in the set.
|
||||
// */
|
||||
// "mainProject": "my-app"
|
||||
// },
|
||||
//
|
||||
// {
|
||||
// /**
|
||||
// * (Required) Indicates the kind of version policy being defined ("lockStepVersion" or "individualVersion").
|
||||
// *
|
||||
// * The "individualVersion" mode specifies that the projects will use "individual versioning".
|
||||
// * This is the typical NPM model where each package has an independent version number
|
||||
// * and CHANGELOG.md file. Although a single CI definition is responsible for publishing the
|
||||
// * packages, they otherwise don't have any special relationship. The version bumping will
|
||||
// * depend on how developers answer the "rush change" questions for each package that
|
||||
// * is changed.
|
||||
// */
|
||||
// "definitionName": "individualVersion",
|
||||
//
|
||||
// "policyName": "MyRandomLibraries",
|
||||
//
|
||||
// /**
|
||||
// * (Optional) This can be used to enforce that all packages in the set must share a common
|
||||
// * major version number, e.g. because they are from the same major release branch.
|
||||
// * It can also be used to discourage people from accidentally making "MAJOR" SemVer changes
|
||||
// * inappropriately. The minor/patch version parts will be bumped independently according
|
||||
// * to the types of changes made to each project, according to the "rush change" command.
|
||||
// */
|
||||
// "lockedMajor": 3
|
||||
// }
|
||||
]
|
|
@ -0,0 +1,51 @@
|
|||
"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';
|
||||
function getRushVersion() {
|
||||
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 */ // tslint:disable-line:no-unused-variable
|
||||
scriptPath, /* /repo/common/scripts/install-run-rush.js */ // tslint:disable-line:no-unused-variable
|
||||
...packageBinArgs /* [build, --to, myproject] */] = process.argv;
|
||||
if (process.argv.length < 3) {
|
||||
console.log('Usage: install-run-rush.js <command> [args...]');
|
||||
console.log('Example: install-run-rush.js build --to myproject');
|
||||
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, 'rush', packageBinArgs);
|
||||
});
|
||||
}
|
||||
run();
|
||||
//# sourceMappingURL=install-run-rush.js.map
|
|
@ -0,0 +1,397 @@
|
|||
"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 rimraf@2.6.2 rimraf -f project1/lib
|
||||
//
|
||||
// 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 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 };
|
||||
}
|
||||
/**
|
||||
* 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 = ensureAndJoinPath(rushCommonFolder, 'temp');
|
||||
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 _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/web-build-tools/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;
|
||||
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;
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
/**
|
||||
* As a workaround, _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.
|
||||
*
|
||||
* 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._syncNpmrc()
|
||||
*/
|
||||
function syncNpmrc(sourceNpmrcFolder, targetNpmrcFolder) {
|
||||
const sourceNpmrcPath = path.join(sourceNpmrcFolder, '.npmrc');
|
||||
const targetNpmrcPath = path.join(targetNpmrcFolder, '.npmrc');
|
||||
try {
|
||||
if (fs.existsSync(sourceNpmrcPath)) {
|
||||
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));
|
||||
}
|
||||
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
|
||||
fs.unlinkSync(targetNpmrcPath);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error(`Error syncing .npmrc file: ${e}`);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 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(rushCommonFolder, 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(rushCommonFolder, 'temp', '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 packageInstallFolder = ensureAndJoinPath(rushCommonFolder, 'temp', 'install-run', `${packageName}@${packageVersion}`);
|
||||
if (!isPackageAlreadyInstalled(packageInstallFolder)) {
|
||||
// The package isn't already installed
|
||||
cleanInstallFolder(rushCommonFolder, 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
|
||||
});
|
||||
return result.status;
|
||||
}
|
||||
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 */ // tslint:disable-line:no-unused-variable
|
||||
scriptPath, /* /repo/common/scripts/install-run-rush.js */ rawPackageSpecifier, /* rimraf@^2.0.0 */ packageBinName, /* rimraf */ ...packageBinArgs /* [-f, myproject/lib] */] = process.argv;
|
||||
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 rimraf@2.6.2 rimraf -f project1/lib');
|
||||
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
|
|
@ -0,0 +1,11 @@
|
|||
!dist/**/*
|
||||
test/
|
||||
dist/test/
|
||||
package/
|
||||
.npmignore
|
||||
tsconfig.json
|
||||
*.ts
|
||||
!*.d.ts
|
||||
*.tgz
|
||||
.vscode
|
||||
.scripts
|
|
@ -0,0 +1,59 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
export class Exception extends Error {
|
||||
constructor(message: string, public exitCode: number = 1) {
|
||||
super(message);
|
||||
Object.setPrototypeOf(this, Exception.prototype);
|
||||
}
|
||||
}
|
||||
|
||||
export class TypeException extends Exception {
|
||||
constructor(code: string, name: string, expectedType: string, instance?: any) {
|
||||
super(instance ? `${code} - '${name}' is not expected type '${expectedType}' (instance: '${instance}') .` : `${code} - '${name}' is not expected type '${expectedType}'.`, 1);
|
||||
Object.setPrototypeOf(this, TypeException.prototype);
|
||||
}
|
||||
}
|
||||
|
||||
export class OperationCanceledException extends Exception {
|
||||
constructor(message: string = "Cancelation Requested", public exitCode: number = 1) {
|
||||
super(message, exitCode);
|
||||
Object.setPrototypeOf(this, OperationCanceledException.prototype);
|
||||
}
|
||||
}
|
||||
export class OutstandingTaskAlreadyCompletedException extends Exception {
|
||||
constructor() {
|
||||
super("The OutstandingTaskAwaiter is already completed, may not Enter() again.", 1);
|
||||
Object.setPrototypeOf(this, OutstandingTaskAlreadyCompletedException.prototype);
|
||||
}
|
||||
}
|
||||
|
||||
export class OperationAbortedException extends Exception {
|
||||
constructor() {
|
||||
super("Error occurred. Exiting.", 1);
|
||||
Object.setPrototypeOf(this, OperationAbortedException.prototype);
|
||||
}
|
||||
}
|
||||
|
||||
export class AggregateException extends Exception {
|
||||
constructor(public errors: Array<any>) {
|
||||
super("Multiple Exceptions caught.", 1);
|
||||
Object.setPrototypeOf(this, AggregateException.prototype);
|
||||
}
|
||||
}
|
||||
|
||||
export class ExclusiveLockUnavailableException extends Exception {
|
||||
constructor(resource: string, timeout: number) {
|
||||
super(`Unable to acquire exclusive lock on '${resource}' before timeout ${timeout} msec.`, 1);
|
||||
Object.setPrototypeOf(this, ExclusiveLockUnavailableException.prototype);
|
||||
}
|
||||
}
|
||||
|
||||
export class SharedLockUnavailableException extends Exception {
|
||||
constructor(resource: string, timeout: number) {
|
||||
super(`Unable to acquire shared lock on '${resource}' before timeout ${timeout} msec.`, 1);
|
||||
Object.setPrototypeOf(this, SharedLockUnavailableException.prototype);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,364 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Server, ListenOptions } from 'net';
|
||||
import { ManualPromise } from "./manual-promise"
|
||||
import { Delay, When } from "./task-functions"
|
||||
import { ExclusiveLockUnavailableException, SharedLockUnavailableException } from "./exception"
|
||||
import { promisify } from "./node-promisify";
|
||||
import { tmpdir } from "os"
|
||||
import { unlink as fs_unlink, readFile as fs_readFile, writeFile as fs_writeFile } from 'fs';
|
||||
import { createHash } from 'crypto';
|
||||
|
||||
const unlink = promisify(fs_unlink);
|
||||
const readFile = promisify(fs_readFile);
|
||||
const writeFile = promisify(fs_writeFile);
|
||||
|
||||
function sanitize(input: string, replacement: string = '_') {
|
||||
const illegalCharacters = /[\/\?<>\\:\*\|":]/g;
|
||||
const controlCharacters = /[\x00-\x1f\x80-\x9f]/g;
|
||||
const reservedCharacters = /^\.+$/;
|
||||
const reservedNames = /^(con|prn|aux|nul|com[0-9]|lpt[0-9])(\..*)?$/i;
|
||||
const trailingSpaces = /[\. ]+$/;
|
||||
|
||||
return input
|
||||
.replace(illegalCharacters, replacement)
|
||||
.replace(controlCharacters, replacement)
|
||||
.replace(reservedCharacters, replacement)
|
||||
.replace(reservedNames, replacement)
|
||||
.replace(trailingSpaces, replacement);
|
||||
}
|
||||
function distill(content: any) {
|
||||
const hash = createHash('sha256').update(JSON.stringify(content)).digest();
|
||||
const port = hash.readUInt16BE(2) | 4096; // 4096+
|
||||
let host = `${(hash.readUInt16BE(4) | 0x10) + 0x7f000000}`;
|
||||
if (process.platform === "darwin") {
|
||||
host = `${0x7f000001}`;
|
||||
}
|
||||
return { port, host };
|
||||
}
|
||||
/**
|
||||
* An interface for Exclusive Locking objects.
|
||||
*/
|
||||
export interface IExclusive {
|
||||
|
||||
/**
|
||||
* Acquire an exclusive lock to the resource.
|
||||
*
|
||||
* @throws ExclusiveLockUnavailableException - if the timeout is reached before the lock can be acquired.
|
||||
* @param timeoutMS - the length of time in miliiseconds to wait for a lock.
|
||||
* @param delayMS - the length of time in milliseconds to retry the lock.
|
||||
* @returns - the release function to release the lock.
|
||||
*/
|
||||
acquire(timeoutMS?: number, delayMS?: number): Promise<() => Promise<void>>;
|
||||
}
|
||||
|
||||
/**
|
||||
* An system-wide Exclusive lock for a named resource.
|
||||
*
|
||||
* This is implemented using an exclusive named pipe.
|
||||
*/
|
||||
export class Mutex implements IExclusive {
|
||||
/*@internal*/public readonly pipe: string;
|
||||
/*@internal*/public readonly options: ListenOptions;
|
||||
/**
|
||||
*
|
||||
* @param name - the resource name to create a Mutex for. Multiple instances (across processes) using the same name are operating on the same lock.
|
||||
*/
|
||||
public constructor(private name: string) {
|
||||
if (process.platform === "win32") {
|
||||
this.pipe = `\\\\.\\pipe\\${sanitize(name)}`;
|
||||
this.options = { path: this.pipe, exclusive: true };
|
||||
} else {
|
||||
const pretendName = `${tmpdir()}/pipe_${sanitize(name)}`;
|
||||
this.options = { ...distill(pretendName), exclusive: true };
|
||||
this.pipe = `${tmpdir()}/pipe_${sanitize(name)}:${this.options.port}`;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously acquires the lock. Will wait for up {@link timeoutMS} milliseconds
|
||||
* @throws ExclusiveLockUnavailableException - if the timeout is reached before the lock can be acquired.
|
||||
* @param timeoutMS - the length of time in miliiseconds to wait for a lock.
|
||||
* @param delayMS - the length of time in milliseconds to retry the lock.
|
||||
* @returns - the release function to release the lock.
|
||||
*/
|
||||
public async acquire(timeoutMS: number = 20000, delayMS: number = 100): Promise<() => Promise<void>> {
|
||||
const fail = Date.now() + timeoutMS;
|
||||
do {
|
||||
try {
|
||||
// try to get the lock to the pipe
|
||||
const server = new Server();
|
||||
|
||||
// possible events after listen
|
||||
const completed = When(server, 'listening', 'error');
|
||||
|
||||
// listening will trigger when we've acquired the pipe handle
|
||||
server.listen(this.options);
|
||||
|
||||
// don't let this keep the process alive.
|
||||
server.unref();
|
||||
|
||||
// wait to see if we can listen to the pipe or fail trying.
|
||||
await completed;
|
||||
|
||||
// yes, we did, setup the release function
|
||||
const closedServer = new ManualPromise<void>();
|
||||
|
||||
// the release function is returned to the consumer
|
||||
return async () => {
|
||||
// ensure that releasing twice isn't harmful.
|
||||
if (!closedServer.isCompleted) {
|
||||
server.close(() => closedServer.resolve());
|
||||
await closedServer;
|
||||
}
|
||||
};
|
||||
} catch {
|
||||
// not really releavent why it failed. Pause for a moment.
|
||||
await Delay(delayMS);
|
||||
}
|
||||
// check if we're past the allowable time.
|
||||
} while (fail > Date.now())
|
||||
|
||||
// we were unable to get the lock before the timeout.
|
||||
throw new ExclusiveLockUnavailableException(this.name, timeoutMS);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A process-local exclusive lock, bound to the object instance.
|
||||
*/
|
||||
export class CriticalSection implements IExclusive {
|
||||
private promise: ManualPromise<void> | undefined;
|
||||
|
||||
/**
|
||||
* @constructor - Creates an instance of a CriticalSection
|
||||
*
|
||||
* @param name - a cosmetic name for the 'resource'. Note: multiple CriticalSection instances with the same do not offer exclusivity, it's tied to the object instance.
|
||||
*/
|
||||
public constructor(private name: string = "unnamed") {
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously acquires the lock. Will wait for up {@link timeoutMS} milliseconds
|
||||
* @throws ExclusiveLockUnavailableException - if the timeout is reached before the lock can be acquired.
|
||||
* @param timeoutMS - the length of time in miliiseconds to wait for a lock.
|
||||
* @param delayMS - unused.
|
||||
* @returns - the release function to release the lock.
|
||||
*/
|
||||
public async acquire(timeoutMS: number = 20000, delayMS: number = 100): Promise<() => Promise<void>> {
|
||||
// delayMS isn't really relavent in this case, since all aqui
|
||||
const fail = Date.now() + timeoutMS;
|
||||
|
||||
if (this.promise) {
|
||||
do {
|
||||
// wait for its release, or we use up what's left of the timeout.
|
||||
// since multiple consumers can be waiting for the promise to fulfil,
|
||||
// the previous promise holder can resolve, someone else can take it's place
|
||||
// before we get a chance to act.
|
||||
await Promise.race([this.promise, Delay(fail - Date.now())]);
|
||||
} while (this.promise && fail > Date.now())
|
||||
}
|
||||
// check to see if the promise is still around, which indicates
|
||||
// that we must have timed out.
|
||||
if (this.promise) {
|
||||
throw new ExclusiveLockUnavailableException(this.name, timeoutMS);
|
||||
}
|
||||
|
||||
// there is no outstanding promise now, we can create one
|
||||
const myPromise = new ManualPromise<void>();
|
||||
this.promise = myPromise;
|
||||
|
||||
// the release function is returned to the consumer
|
||||
return async () => {
|
||||
// ensure that releasing twice isn't harmful.
|
||||
if (!myPromise.isCompleted) {
|
||||
this.promise = undefined
|
||||
myPromise.resolve();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Offers a lock where many consumers can acquire, but an exclusive lock can only be gained if
|
||||
* the consumer is the only one who has a shared lock.
|
||||
*/
|
||||
export class SharedLock {
|
||||
private readonly exclusiveLock: Mutex;
|
||||
private readonly busyLock: Mutex;
|
||||
private readonly personalLock: Mutex;
|
||||
private readonly file: string;
|
||||
|
||||
public constructor(private name: string) {
|
||||
this.exclusiveLock = new Mutex(`${sanitize(name)}.exclusive-lock`);
|
||||
this.busyLock = new Mutex(`${sanitize(name)}.busy-lock`);
|
||||
this.personalLock = new Mutex(`${sanitize(name)}.${Math.random() * 10000}.personal-lock`);
|
||||
|
||||
this.file = `${tmpdir()}/${sanitize(name)}.lock`;
|
||||
}
|
||||
|
||||
private async readConnections(): Promise<Array<ListenOptions>> {
|
||||
// get the list of names.
|
||||
let connections = new Array<ListenOptions>();
|
||||
try {
|
||||
const list = JSON.parse(await readFile(this.file, 'utf8'));
|
||||
for (const each of list) {
|
||||
if (await this.isLocked(each)) {
|
||||
connections.push(each);
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
}
|
||||
|
||||
return connections;
|
||||
}
|
||||
|
||||
private async writeConnections(connections: Array<ListenOptions>): Promise<void> {
|
||||
// write the list of names.
|
||||
if (connections && connections.length > 0) {
|
||||
// write the list of names into the file.
|
||||
await writeFile(this.file, JSON.stringify(connections, null, 2));
|
||||
} else {
|
||||
try {
|
||||
// no names in list, file should be deleted
|
||||
await unlink(this.file)
|
||||
} catch {
|
||||
// shh!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async isLocked(options: ListenOptions): Promise<boolean> {
|
||||
const server = new Server();
|
||||
try {
|
||||
// possible events after listen
|
||||
const completed = When(server, 'listening', 'error');
|
||||
|
||||
// listening will trigger when we've acquired the pipe handle
|
||||
server.listen(options);
|
||||
|
||||
// wait to see if we can listen to the pipe or fail trying.
|
||||
await completed;
|
||||
|
||||
// the pipe opened! It's not locked
|
||||
await server.close()
|
||||
|
||||
return false;
|
||||
} catch {
|
||||
server.close();
|
||||
}
|
||||
// the pipe is locked
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously acquires a shared lock. Will wait for up {@link timeoutMS} milliseconds
|
||||
* @throws SharedLockUnavailableException - if the timeout is reached before the lock can be acquired.
|
||||
* @param timeoutMS - the length of time in miliiseconds to wait for a lock.
|
||||
* @param delayMS - the polling interval for the exclusive lock during initialization.
|
||||
* @returns - the release function to release the shared lock.
|
||||
*/
|
||||
public async acquire(timeoutMS: number = 20000, delayMS: number = 100): Promise<() => Promise<void>> {
|
||||
// ensure we're the only one that can muck with things for now.
|
||||
|
||||
const releaseBusy = await this.busyLock.acquire(timeoutMS, delayMS);
|
||||
try {
|
||||
// get our personal lock
|
||||
const releasePersonal = await this.personalLock.acquire();
|
||||
|
||||
const activeLocks = await this.readConnections();
|
||||
|
||||
activeLocks.push(this.personalLock.options);
|
||||
|
||||
await this.writeConnections(activeLocks);
|
||||
|
||||
await releaseBusy();
|
||||
|
||||
return async () => {
|
||||
// release our personal lock
|
||||
await releasePersonal();
|
||||
|
||||
// try to remove our name from the list
|
||||
try {
|
||||
const releaseBusy = await this.busyLock.acquire(timeoutMS, delayMS);
|
||||
try {
|
||||
await this.writeConnections(await this.readConnections());
|
||||
} finally {
|
||||
// regardless, release the busy lock!
|
||||
await releaseBusy();
|
||||
}
|
||||
|
||||
} catch {
|
||||
// if it fails no, worry, someone else can clean it up.
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
throw new SharedLockUnavailableException(this.name, timeoutMS);
|
||||
} finally {
|
||||
// release the busy lock!
|
||||
await releaseBusy();
|
||||
}
|
||||
}
|
||||
|
||||
public get activeLockCount(): Promise<number> {
|
||||
return (async () => {
|
||||
return (await this.readConnections()).length;
|
||||
})();
|
||||
}
|
||||
|
||||
public get isExclusiveLocked(): Promise<boolean> {
|
||||
return (async () => {
|
||||
try {
|
||||
// try to lock it
|
||||
const release = (await this.exclusive(0));
|
||||
await release();
|
||||
return false;
|
||||
} catch {
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
})();
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously acquires an exclusive lock. Will wait for up {@link timeoutMS} milliseconds
|
||||
*
|
||||
* Will only permit a lock if there are no other shared locks
|
||||
*
|
||||
* @throws ExclusibveLockUnavailableException - if the timeout is reached before the lock can be acquired.
|
||||
* @param timeoutMS - the length of time in miliiseconds to wait for a lock.
|
||||
* @param delayMS - the polling interval for the exclusive lock during initialization.
|
||||
* @returns - the release function to release the exclusive lock.
|
||||
*/
|
||||
public async exclusive(timeoutMS: number = 20000, delayMS: number = 100): Promise<() => Promise<void>> {
|
||||
|
||||
const busyRelease = await this.busyLock.acquire(timeoutMS, delayMS);
|
||||
|
||||
// ensure we're the only one that can muck with things for now.
|
||||
const exclusiveRelease = await this.exclusiveLock.acquire(timeoutMS, delayMS);
|
||||
|
||||
try {
|
||||
// make sure we're the only one who has an shared lock
|
||||
const activeLocks = await this.readConnections();
|
||||
if (activeLocks.length === 0 || (activeLocks.length === 1 && JSON.stringify(activeLocks[0]) === JSON.stringify(this.personalLock.options))) {
|
||||
return async () => {
|
||||
await exclusiveRelease();
|
||||
await busyRelease();
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
|
||||
}
|
||||
// we didn't return the exclusive Lock,
|
||||
// release it and throw...
|
||||
await exclusiveRelease();
|
||||
await busyRelease();
|
||||
|
||||
throw new ExclusiveLockUnavailableException(this.name, timeoutMS);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
export class LazyPromise<T> implements Promise<T> {
|
||||
private promise: Promise<T> | null = null;
|
||||
|
||||
public constructor(private factory: () => Promise<T>) {
|
||||
}
|
||||
|
||||
private get Value(): Promise<T> {
|
||||
if (this.promise === null) {
|
||||
this.promise = this.factory();
|
||||
}
|
||||
return this.promise;
|
||||
}
|
||||
|
||||
get [Symbol.toStringTag]() {
|
||||
return this.Value[Symbol.toStringTag];
|
||||
}
|
||||
|
||||
then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null): Promise<TResult1 | TResult2> {
|
||||
return this.Value.then(onfulfilled, onrejected);
|
||||
};
|
||||
catch<TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null): Promise<T | TResult> {
|
||||
return this.Value.catch(onrejected);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
export class Lazy<T> {
|
||||
private promise: { obj: T } | null = null;
|
||||
|
||||
public constructor(private factory: () => T) {
|
||||
}
|
||||
|
||||
public get Value(): T {
|
||||
if (this.promise === null) {
|
||||
this.promise = { obj: this.factory() };
|
||||
}
|
||||
return this.promise.obj;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
/**
|
||||
* A manually (or externally) controlled asynchronous Promise implementation
|
||||
*/
|
||||
export class ManualPromise<T> implements Promise<T> {
|
||||
/**
|
||||
* Attaches callbacks for the resolution and/or rejection of the Promise.
|
||||
* @param onfulfilled The callback to execute when the Promise is resolved.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of which ever callback is executed.
|
||||
*/
|
||||
then<TResult1 = T, TResult2 = never>(onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null | undefined, onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null | undefined): Promise<TResult1 | TResult2> {
|
||||
return this.p.then(onfulfilled, onrejected);
|
||||
}
|
||||
/**
|
||||
* Attaches a callback for only the rejection of the Promise.
|
||||
* @param onrejected The callback to execute when the Promise is rejected.
|
||||
* @returns A Promise for the completion of the callback.
|
||||
*/
|
||||
catch<TResult = never>(onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | null | undefined): Promise<T | TResult> {
|
||||
return this.p.catch(onrejected);
|
||||
}
|
||||
readonly [Symbol.toStringTag]: "Promise";
|
||||
private p: Promise<T>;
|
||||
|
||||
/**
|
||||
* A method to manually resolve the Promise.
|
||||
*/
|
||||
public resolve: (value?: T | PromiseLike<T> | undefined) => void = (v) => { };
|
||||
|
||||
/**
|
||||
* A method to manually reject the Promise
|
||||
*/
|
||||
public reject: (e: any) => void = (e) => { };
|
||||
|
||||
private state: "pending" | "resolved" | "rejected" = "pending";
|
||||
|
||||
/**
|
||||
* Returns true of the Promise has been Resolved or Rejected
|
||||
*/
|
||||
public get isCompleted(): boolean {
|
||||
return this.state !== "pending";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the Promise has been Resolved.
|
||||
*/
|
||||
public get isResolved(): boolean {
|
||||
return this.state === "resolved";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the Promise has been Rejected.
|
||||
*/
|
||||
public get isRejected(): boolean {
|
||||
return this.state === "rejected";
|
||||
}
|
||||
|
||||
public constructor() {
|
||||
this.p = new Promise<T>((r, j) => {
|
||||
this.resolve = (v: T | PromiseLike<T> | undefined) => { this.state = "resolved"; r(v); };
|
||||
this.reject = (e: any) => { this.state = "rejected"; j(e); };
|
||||
});
|
||||
}
|
||||
}
|
|
@ -0,0 +1,109 @@
|
|||
import { TypeException } from "./exception"
|
||||
import { ManualPromise } from "./manual-promise"
|
||||
import { promisify as util_promisify } from 'util'
|
||||
|
||||
const kCustomPromisifiedSymbol = Symbol('util.promisify.custom');
|
||||
const kCustomPromisifyArgsSymbol = Symbol('customPromisifyArgs');
|
||||
|
||||
declare global {
|
||||
interface ObjectConstructor {
|
||||
getOwnPropertyDescriptors(o: any): PropertyDescriptorMap;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add polyfill for Object.getOwnPropertyDescriptors
|
||||
*
|
||||
* Origin: https://github.com/tc39/proposal-object-getownpropertydescriptors
|
||||
*/
|
||||
if (!Object.hasOwnProperty('getOwnPropertyDescriptors')) {
|
||||
Object.defineProperty(
|
||||
Object,
|
||||
'getOwnPropertyDescriptors',
|
||||
{
|
||||
configurable: true,
|
||||
writable: true,
|
||||
value: function getOwnPropertyDescriptors(object: any) {
|
||||
return Reflect.ownKeys(object).reduce((descriptors, key) => {
|
||||
return Object.defineProperty(
|
||||
descriptors,
|
||||
key,
|
||||
{
|
||||
configurable: true,
|
||||
enumerable: true,
|
||||
writable: true,
|
||||
value: Object.getOwnPropertyDescriptor(object, key)
|
||||
}
|
||||
);
|
||||
}, {});
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Promisify Implementation acquired from node8 and adapted to node7/typescript
|
||||
*
|
||||
* @param original original method declaration
|
||||
*/
|
||||
function _promisify(original: any) {
|
||||
if (typeof original !== 'function')
|
||||
throw new TypeException('ERR_INVALID_ARG_TYPE', 'original', 'Function');
|
||||
|
||||
if (original[kCustomPromisifiedSymbol]) {
|
||||
const fn = original[kCustomPromisifiedSymbol];
|
||||
|
||||
if (typeof fn !== 'function') {
|
||||
throw new TypeException('ERR_INVALID_ARG_TYPE',
|
||||
'util.promisify.custom',
|
||||
'Function',
|
||||
fn);
|
||||
}
|
||||
Object.defineProperty(fn, kCustomPromisifiedSymbol, {
|
||||
value: fn, enumerable: false, writable: false, configurable: true
|
||||
});
|
||||
return fn;
|
||||
}
|
||||
|
||||
// Names to create an object from in case the callback receives multiple
|
||||
// arguments, e.g. ['stdout', 'stderr'] for child_process.exec.
|
||||
const argumentNames = original[kCustomPromisifyArgsSymbol];
|
||||
|
||||
function fn(this: any, ...args: any[]): Promise<any> {
|
||||
const promise = new ManualPromise();
|
||||
try {
|
||||
original.call(this, ...args, (err: any, ...values: any[]) => {
|
||||
if (err) {
|
||||
promise.reject(err);
|
||||
} else if (argumentNames !== undefined && values.length > 1) {
|
||||
const obj: any = {};
|
||||
for (var i = 0; i < argumentNames.length; i++)
|
||||
obj[argumentNames[i]] = values[i];
|
||||
promise.resolve(obj);
|
||||
} else {
|
||||
promise.resolve(values[0]);
|
||||
}
|
||||
});
|
||||
} catch (err) {
|
||||
promise.reject(err);
|
||||
}
|
||||
return promise;
|
||||
}
|
||||
|
||||
Object.setPrototypeOf(fn, Object.getPrototypeOf(original));
|
||||
|
||||
Object.defineProperty(fn, kCustomPromisifiedSymbol, {
|
||||
value: fn, enumerable: false, writable: false, configurable: true
|
||||
});
|
||||
return Object.defineProperties(
|
||||
fn,
|
||||
Object.getOwnPropertyDescriptors(original)
|
||||
);
|
||||
}
|
||||
|
||||
(<any>_promisify).custom = kCustomPromisifiedSymbol;
|
||||
|
||||
/**
|
||||
* Promisify implementation, will use built-in version in node if available, falls back to local implementation borrowed from node8.
|
||||
*/
|
||||
export const promisify = util_promisify || _promisify;
|
|
@ -0,0 +1,35 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { OutstandingTaskAlreadyCompletedException, AggregateException } from "./exception";
|
||||
|
||||
export class OutstandingTaskAwaiter {
|
||||
private locked: boolean = false;
|
||||
private outstandingTasks: Promise<any>[] = [];
|
||||
private errors: Array<any> = [];
|
||||
|
||||
public async Wait(): Promise<void> {
|
||||
this.locked = true;
|
||||
await Promise.all(this.outstandingTasks);
|
||||
if (this.errors.length) {
|
||||
if (this.errors.length == 1) {
|
||||
throw this.errors[0];
|
||||
}
|
||||
throw new AggregateException(this.errors);
|
||||
}
|
||||
}
|
||||
|
||||
public async Await<T>(task: Promise<T>): Promise<T> {
|
||||
if (this.locked) {
|
||||
throw new OutstandingTaskAlreadyCompletedException();
|
||||
}
|
||||
this.outstandingTasks.push(task.catch((e) => {
|
||||
console.error("Yes. errors in the await.")
|
||||
this.errors.push(e)
|
||||
}));
|
||||
|
||||
return task;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Creates a shallow copy of a given object by copying the properties to a new object
|
||||
* Note: this does not copy the method prototypes, so it's a shallow data copy only.
|
||||
*
|
||||
* @param {input} any javascript object
|
||||
* @param {filter} Array<string> of properties to filter out from the copy.
|
||||
*/
|
||||
export function shallowCopy(input: any, ...filter: Array<string>): any {
|
||||
if (!input) {
|
||||
return input;
|
||||
}
|
||||
const keys = input.Keys ? input.Keys : Object.getOwnPropertyNames(input);
|
||||
|
||||
const result: any = {};
|
||||
for (const key of keys) {
|
||||
if (filter.indexOf(key) == -1) {
|
||||
const value = input[key];
|
||||
if (value !== undefined) {
|
||||
result[key] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { EventEmitter } from "events"
|
||||
import { ManualPromise } from "./manual-promise"
|
||||
import { promisify } from "./node-promisify"
|
||||
|
||||
/**
|
||||
* Creates a promise that resolves after a delay
|
||||
*
|
||||
* @param delayMS the length of time to delay in milliseconds.
|
||||
*/
|
||||
export function Delay(delayMS: number): Promise<void> {
|
||||
return new Promise<void>(res => setTimeout(res, delayMS));
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously waits for the predicate condition to turn false, with a delay between checks
|
||||
* @param predicate - a fn that returns a boolean
|
||||
* @param delay - number of milliseconds to async delay between checks.
|
||||
*/
|
||||
export async function While(predicate: () => boolean, delay: number = 50): Promise<void> {
|
||||
while (predicate()) {
|
||||
await Delay(delay);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Asynchronously waits for the predicate condition to turn true, with a delay between checks
|
||||
* @param predicate - a fn that returns a boolean
|
||||
* @param delay - number of milliseconds to async delay between checks.
|
||||
*/
|
||||
export async function Until(predicate: () => boolean, delay: number = 50): Promise<void> {
|
||||
while (predicate()) {
|
||||
await Delay(delay);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An async wrapper for waiting for an event to trigger once
|
||||
* @param emitter - an event emitter
|
||||
* @param event - the name of the event to wait for.
|
||||
*/
|
||||
export function When<T>(emitter: EventEmitter, successEvent?: string, errorEvent?: string): Promise<T> {
|
||||
const result = new ManualPromise<T>();
|
||||
|
||||
if (errorEvent) {
|
||||
// errors after a previous completion are ignored.
|
||||
emitter.once(errorEvent, (e: any) => {
|
||||
if (!result.isCompleted) {
|
||||
result.reject(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (successEvent) {
|
||||
// success after a previous completion is ignored.
|
||||
emitter.once(successEvent, (v: T) => {
|
||||
if (!result.isCompleted) {
|
||||
result.resolve(v);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
export function Async<T>(fn: () => T, msec: number = 1): Promise<T> {
|
||||
return new Promise((r, j) => setTimeout(() => {
|
||||
try { r(fn()) } catch (E) { j(E) }
|
||||
}, msec));
|
||||
}
|
||||
|
||||
export async function Timeout<T>(p: Promise<T>, msec: number): Promise<T> {
|
||||
let enabled = false;
|
||||
const value = await Promise.race([p, Async(() => { if (enabled) throw new Error("timed out") }, msec)]);
|
||||
enabled = false;
|
||||
return value as T;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
export * from './lib/exception'
|
||||
export * from './lib/outstanding-task-awaiter'
|
||||
export * from "./lib/lazy-promise"
|
||||
export * from "./lib/lazy"
|
||||
export * from "./lib/manual-promise"
|
||||
export * from "./lib/exclusive-locks"
|
||||
export * from "./lib/task-functions"
|
||||
export * from "./lib/polyfill"
|
|
@ -0,0 +1,43 @@
|
|||
{
|
||||
"name": "@microsoft.azure/tasks",
|
||||
"version": "2.0.27",
|
||||
"description": "Async tasks, exceptions for Azure Open Source Projects",
|
||||
"engines": {
|
||||
"node": ">=7.10.0"
|
||||
},
|
||||
"main": "./dist/main.js",
|
||||
"typings": "./dist/main.d.ts",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/Azure/perks.tasks.git"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc -p .",
|
||||
"prepare": "npm run build",
|
||||
"test": "npm run build && _mocha dist/test",
|
||||
"testci": "npm run build && mocha dist/test"
|
||||
},
|
||||
"keywords": [
|
||||
"perks",
|
||||
"tasks",
|
||||
"autorest",
|
||||
"azure",
|
||||
"typescript"
|
||||
],
|
||||
"author": "Microsoft",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/Azure/perks.tasks/issues"
|
||||
},
|
||||
"homepage": "https://github.com/Azure/perks.tasks#readme",
|
||||
"readme": "https://github.com/Azure/perks.tasks/readme.md",
|
||||
"devDependencies": {
|
||||
"@types/node": "10.11.3",
|
||||
"@types/mocha": "5.2.5",
|
||||
"mocha": "5.2.0",
|
||||
"mocha-typescript": "1.1.17",
|
||||
"typescript": "^3.1.1",
|
||||
"source-map-support": "0.5.9"
|
||||
},
|
||||
"dependencies": {}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
# Project: @microsoft.azure/tasks
|
||||
|
||||
This package contains common code for the developer tools for generating Azure SDKs.
|
||||
|
||||
Including:
|
||||
- AutoRest
|
||||
|
||||
### Description
|
||||
Task and Exception support for AutoRest and related tools.
|
||||
|
||||
----
|
||||
|
||||
# Contributing
|
||||
|
||||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
|
|
@ -0,0 +1,3 @@
|
|||
import * as Mocha from 'mocha';
|
||||
|
||||
declare type MochaDone = Mocha.Done;
|
|
@ -0,0 +1,29 @@
|
|||
import { suite, test, slow, timeout, skip, only } from "mocha-typescript";
|
||||
import * as assert from "assert";
|
||||
import { While, CriticalSection, Async } from "../main";
|
||||
|
||||
// pull in source-map support for stack traces.
|
||||
require('source-map-support').install({ hookRequire: true });
|
||||
|
||||
|
||||
@suite class TestFunctions {
|
||||
@test async "Test While"() {
|
||||
let i = 10;
|
||||
await While(() => --i ? true : false);
|
||||
assert.equal(i, 0, "While should run until condition is false.")
|
||||
}
|
||||
|
||||
@test async "Async"() {
|
||||
let x = 0;
|
||||
|
||||
const done = Async(() => {
|
||||
x = 100;
|
||||
})
|
||||
|
||||
assert.equal(x, 0, "should not run async until after this point.")
|
||||
|
||||
await done;
|
||||
|
||||
assert.equal(x, 100, "it should have run it.")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
import { suite, test, slow, timeout, skip, only } from "mocha-typescript";
|
||||
import * as assert from "assert";
|
||||
|
||||
import { CriticalSection, Mutex, SharedLock, ManualPromise, Delay, Async } from "../main"
|
||||
|
||||
// pull in source-map support for stack traces.
|
||||
require('source-map-support').install({ hookRequire: true });
|
||||
|
||||
|
||||
@suite class TestLocks {
|
||||
@test async "CriticalSection"() {
|
||||
|
||||
const cs = new CriticalSection();
|
||||
|
||||
const status = new Array<string>();
|
||||
|
||||
const first = Async(async () => {
|
||||
const r = await cs.acquire();
|
||||
console.log("1. acquired");
|
||||
status.push("A");
|
||||
await Delay(200);
|
||||
console.log("2. releasing")
|
||||
status.push("B");
|
||||
await r();
|
||||
console.log("3.released")
|
||||
status.push("C");
|
||||
})
|
||||
|
||||
const second = Async(async () => {
|
||||
const r = await cs.acquire();
|
||||
console.log("4. acquired");
|
||||
status.push("D");
|
||||
await Delay(10);
|
||||
console.log("5. releasing")
|
||||
status.push("E");
|
||||
await r();
|
||||
console.log("6.released")
|
||||
status.push("F");
|
||||
|
||||
})
|
||||
|
||||
await Promise.all([first, second]);
|
||||
|
||||
assert.equal(status.join(""), "ABCDEF", "Correct Order.")
|
||||
}
|
||||
|
||||
@test async "Mutex"() {
|
||||
|
||||
const status = new Array<string>();
|
||||
|
||||
const first = Async(async () => {
|
||||
const mutex = new Mutex("garrett");
|
||||
const r = await mutex.acquire();
|
||||
console.log("1. acquired");
|
||||
status.push("A");
|
||||
await Delay(200);
|
||||
console.log("2. releasing")
|
||||
status.push("B");
|
||||
await r();
|
||||
console.log("3.released")
|
||||
status.push("C");
|
||||
})
|
||||
|
||||
const second = Async(async () => {
|
||||
try {
|
||||
const mutex = new Mutex("garrett");
|
||||
const r = await mutex.acquire();
|
||||
console.log("4. acquired");
|
||||
status.push("D");
|
||||
await Delay(10);
|
||||
console.log("5. releasing")
|
||||
status.push("E");
|
||||
await r();
|
||||
console.log("6.released")
|
||||
status.push("F");
|
||||
|
||||
} catch (E) {
|
||||
console.log(E);
|
||||
}
|
||||
}, 1)
|
||||
|
||||
await Promise.all([first, second]);
|
||||
assert.equal(status.join(""), "ABCDEF", "Correct Order.")
|
||||
}
|
||||
|
||||
@test async "SharedLock-simple"() {
|
||||
const sharedLock = new SharedLock("/tmp/testJqqE6h/install-pkguByBYI/echo-cli@1.0.8/bla/bla/bla");
|
||||
const release = await sharedLock.acquire();
|
||||
try {
|
||||
assert.equal(await sharedLock.activeLockCount, 1, "should be one active lock")
|
||||
|
||||
assert.equal(await sharedLock.isExclusiveLocked, false, "should not be exclusive");
|
||||
const ex_release = await sharedLock.exclusive();
|
||||
assert.equal(await sharedLock.isExclusiveLocked, true, "should be exclusive");
|
||||
|
||||
const anotherShared = new SharedLock("/tmp/testJqqE6h/install-pkguByBYI/echo-cli@1.0.8/bla/bla/bla");
|
||||
let success = false;
|
||||
try {
|
||||
await anotherShared.acquire(2)
|
||||
} catch {
|
||||
success = true;
|
||||
}
|
||||
assert.equal(success, true, "should not be able to get shared lock");
|
||||
|
||||
await ex_release();
|
||||
|
||||
success = false;
|
||||
try {
|
||||
await (await anotherShared.acquire(2))()
|
||||
success = true;
|
||||
} catch {
|
||||
success = false;
|
||||
}
|
||||
assert.equal(success, true, "should be able to get shared lock");
|
||||
|
||||
|
||||
} finally {
|
||||
await release();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"outDir": "dist",
|
||||
"alwaysStrict": true,
|
||||
"forceConsistentCasingInFileNames": false,
|
||||
"module": "commonjs",
|
||||
"noEmitOnError": true,
|
||||
"noImplicitAny": true,
|
||||
"noImplicitReturns": true,
|
||||
"noImplicitThis": true,
|
||||
"sourceMap": true,
|
||||
"strict": true,
|
||||
"declaration": true,
|
||||
"stripInternal": true,
|
||||
"noEmitHelpers": false,
|
||||
"target": "es2017",
|
||||
"types": [
|
||||
"node"
|
||||
],
|
||||
"lib": [
|
||||
"es2017"
|
||||
],
|
||||
"experimentalDecorators": true,
|
||||
"newLine": "LF"
|
||||
},
|
||||
"exclude": [
|
||||
"dist",
|
||||
"node_modules"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,267 @@
|
|||
/**
|
||||
* This is the main configuration file for Rush.
|
||||
* For full documentation, please see https://rushjs.io
|
||||
*/
|
||||
{
|
||||
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/rush.schema.json",
|
||||
/**
|
||||
* (Required) This specifies the version of the Rush engine to be used in this repo.
|
||||
* Rush's "version selector" feature ensures that the globally installed tool will
|
||||
* behave like this release, regardless of which version is installed globally.
|
||||
*
|
||||
* The common/scripts/install-run-rush.js automation script also uses this version.
|
||||
*
|
||||
* NOTE: If you upgrade to a new major version of Rush, you should replace the "v5"
|
||||
* path segment in the "$schema" field for all your Rush config files. This will ensure
|
||||
* correct error-underlining and tab-completion for editors such as VS Code.
|
||||
*/
|
||||
"rushVersion": "5.3.1",
|
||||
/**
|
||||
* The next field selects which package manager should be installed and determines its version.
|
||||
* Rush installs its own local copy of the package manager to ensure that your build process
|
||||
* is fully isolated from whatever tools are present in the local environment.
|
||||
*
|
||||
* Specify one of: "pnpmVersion", "npmVersion", or "yarnVersion". See the Rush documentation
|
||||
* for details about these alternatives.
|
||||
*/
|
||||
"pnpmVersion": "2.15.1",
|
||||
// "npmVersion": "4.5.0",
|
||||
// "yarnVersion": "1.9.4",
|
||||
/**
|
||||
* Options that are only used when the PNPM package manager is selected
|
||||
*/
|
||||
"pnpmOptions": {
|
||||
/**
|
||||
* If true, then Rush will add the "--strict-peer-dependencies" option when invoking PNPM.
|
||||
* This causes "rush install" to fail if there are unsatisfied peer dependencies, which is
|
||||
* an invalid state that can cause build failures or incompatible dependency versions.
|
||||
* (For historical reasons, JavaScript package managers generally do not treat this invalid
|
||||
* state as an error.)
|
||||
*
|
||||
* The default value is false to avoid legacy compatibility issues.
|
||||
* It is strongly recommended to set strictPeerDependencies=true.
|
||||
*/
|
||||
"strictPeerDependencies": true
|
||||
},
|
||||
/**
|
||||
* Older releases of the NodeJS engine may be missing features required by your system.
|
||||
* Other releases may have bugs. In particular, the "latest" version will not be a
|
||||
* Long Term Support (LTS) version and is likely to have regressions.
|
||||
*
|
||||
* Specify a SemVer range to ensure developers use a NodeJS version that is appropriate
|
||||
* for your repo.
|
||||
*/
|
||||
"nodeSupportedVersionRange": ">=8.9.4 <11.0.0",
|
||||
/**
|
||||
* If you would like the version specifiers for your dependencies to be consistent, then
|
||||
* uncomment this line. This is effectively similar to running "rush check" before any
|
||||
* of the following commands:
|
||||
*
|
||||
* rush install, rush update, rush link, rush version, rush publish
|
||||
*
|
||||
* In some cases you may want this turned on, but need to allow certain packages to use a different
|
||||
* version. In those cases, you will need to add an entry to the "allowedAlternateVersions"
|
||||
* section of the common-versions.json.
|
||||
*/
|
||||
"ensureConsistentVersions": true,
|
||||
/**
|
||||
* Large monorepos can become intimidating for newcomers if project folder paths don't follow
|
||||
* a consistent and recognizable pattern. When the system allows nested folder trees,
|
||||
* we've found that teams will often use subfolders to create islands that isolate
|
||||
* their work from others ("shipping the org"). This hinders collaboration and code sharing.
|
||||
*
|
||||
* The Rush developers recommend a "category folder" model, where buildable project folders
|
||||
* must always be exactly two levels below the repo root. The parent folder acts as the category.
|
||||
* This provides a basic facility for grouping related projects (e.g. "apps", "libaries",
|
||||
* "tools", "prototypes") while still encouraging teams to organize their projects into
|
||||
* a unified taxonomy. Limiting to 2 levels seems very restrictive at first, but if you have
|
||||
* 20 categories and 20 projects in each category, this scheme can easily accommodate hundreds
|
||||
* of projects. In practice, you will find that the folder hierarchy needs to be rebalanced
|
||||
* occasionally, but if that's painful, it's a warning sign that your development style may
|
||||
* discourage refactoring. Reorganizing the categories should be an enlightening discussion
|
||||
* that brings people together, and maybe also identifies poor coding practices (e.g. file
|
||||
* references that reach into other project's folders without using NodeJS module resolution).
|
||||
*
|
||||
* The defaults are projectFolderMinDepth=1 and projectFolderMaxDepth=2.
|
||||
*
|
||||
* To remove these restrictions, you could set projectFolderMinDepth=1
|
||||
* and set projectFolderMaxDepth to a large number.
|
||||
*/
|
||||
"projectFolderMinDepth": 2,
|
||||
"projectFolderMaxDepth": 2,
|
||||
/**
|
||||
* This feature helps you to review and approve new packages before they are introduced
|
||||
* to your monorepo. For example, you may be concerned about licensing, code quality,
|
||||
* performance, or simply accumulating too many libraries with overlapping functionality.
|
||||
* The approvals are tracked in two config files "browser-approved-packages.json"
|
||||
* and "nonbrowser-approved-packages.json". See the Rush documentation for details.
|
||||
*/
|
||||
// "approvedPackagesPolicy": {
|
||||
// /**
|
||||
// * The review categories allow you to say for example "This library is approved for usage
|
||||
// * in prototypes, but not in production code."
|
||||
// *
|
||||
// * Each project can be associated with one review category, by assigning the "reviewCategory" field
|
||||
// * in the "projects" section of rush.json. The approval is then recorded in the files
|
||||
// * "common/config/rush/browser-approved-packages.json" and "nonbrowser-approved-packages.json"
|
||||
// * which are automatically generated during "rush update".
|
||||
// *
|
||||
// * Designate categories with whatever granularity is appropriate for your review process,
|
||||
// * or you could just have a single category called "default".
|
||||
// */
|
||||
// "reviewCategories": [
|
||||
// // Some example categories:
|
||||
// "production", // projects that ship to production
|
||||
// "tools", // non-shipping projects that are part of the developer toolchain
|
||||
// "prototypes" // experiments that should mostly be ignored by the review process
|
||||
// ],
|
||||
//
|
||||
// /**
|
||||
// * A list of NPM package scopes that will be excluded from review.
|
||||
// * We recommend to exclude TypeScript typings (the "@types" scope), because
|
||||
// * if the underlying package was already approved, this would imply that the typings
|
||||
// * are also approved.
|
||||
// */
|
||||
// // "ignoredNpmScopes": [ "@types" ]
|
||||
// },
|
||||
/**
|
||||
* If you use Git as your version control system, this section has some additional
|
||||
* optional features you can use.
|
||||
*/
|
||||
"gitPolicy": {
|
||||
/**
|
||||
* Work at a big company? Tired of finding Git commits at work with unprofessional Git
|
||||
* emails such as "beer-lover@my-college.edu"? Rush can validate people's Git email address
|
||||
* before they get started.
|
||||
*
|
||||
* Define a list of regular expressions describing allowable e-mail patterns for Git commits.
|
||||
* They are case-insensitive anchored JavaScript RegExps. Example: ".*@example\.com"
|
||||
*
|
||||
* IMPORTANT: Because these are regular expressions encoded as JSON string literals,
|
||||
* RegExp escapes need two backspashes, and ordinary periods should be "\\.".
|
||||
*/
|
||||
// "allowedEmailRegExps": [
|
||||
// "[^@]+@users\\.noreply\\.github\\.com",
|
||||
// "travis@example\\.org"
|
||||
// ],
|
||||
/**
|
||||
* When Rush reports that the address is malformed, the notice can include an example
|
||||
* of a recommended email. Make sure it conforms to one of the allowedEmailRegExps
|
||||
* expressions.
|
||||
*/
|
||||
// "sampleEmail": "mrexample@users.noreply.github.com"
|
||||
},
|
||||
"repository": {
|
||||
/**
|
||||
* This setting is sometimes needed when using "rush change" with multiple Git remotes.
|
||||
* It specifies the remote url for the official Git repository. If this URL is provided,
|
||||
* "rush change" will use it to find the right remote to compare against.
|
||||
*/
|
||||
// "url": "https://github.com/Microsoft/rush-example"
|
||||
},
|
||||
/**
|
||||
* Event hooks are customized script actions that Rush executes when specific events occur
|
||||
*/
|
||||
"eventHooks": {
|
||||
/**
|
||||
* The list of shell commands to run before the Rush installation starts
|
||||
*/
|
||||
"preRushInstall": [
|
||||
// "common/scripts/pre-rush-install.js"
|
||||
],
|
||||
/**
|
||||
* The list of shell commands to run after the Rush installation finishes
|
||||
*/
|
||||
"postRushInstall": [],
|
||||
/**
|
||||
* The list of shell commands to run before the Rush build command starts
|
||||
*/
|
||||
"preRushBuild": [],
|
||||
/**
|
||||
* The list of shell commands to run after the Rush build command finishes
|
||||
*/
|
||||
"postRushBuild": []
|
||||
},
|
||||
/**
|
||||
* Rush can collect anonymous telemetry about everyday developer activity such as
|
||||
* success/failure of installs, builds, and other operations. You can use this to identify
|
||||
* problems with your toolchain or Rush itself. THIS TELEMETRY IS NOT SHARED WITH MICROSOFT.
|
||||
* It is written into JSON files in the common/temp folder. It's up to you to write scripts
|
||||
* that read these JSON files and do something with them. These scripts are typically registered
|
||||
* in the "eventHooks" section.
|
||||
*/
|
||||
"telemetryEnabled": false,
|
||||
/**
|
||||
* Allows creation of hotfix changes. This feature is experimental so it is disabled by default.
|
||||
*/
|
||||
// "hotfixChangeEnabled": false,
|
||||
/**
|
||||
* (Required) This is the inventory of projects to be managed by Rush.
|
||||
*
|
||||
* Rush does not automatically scan for projects using wildcards, for a few reasons:
|
||||
* 1. Depth-first scans are expensive, particularly when tools need to repeatedly collect the list.
|
||||
* 2. On a caching CI machine, scans can accidentally pick up files left behind from a previous build.
|
||||
* 3. It's useful to have a centralized inventory of all projects and their important metadata.
|
||||
*/
|
||||
"projects": [
|
||||
// {
|
||||
// /**
|
||||
// * The NPM package name of the project (must match package.json)
|
||||
// */
|
||||
// "packageName": "my-app",
|
||||
//
|
||||
// /**
|
||||
// * The path to the project folder, relative to the rush.json config file.
|
||||
// */
|
||||
// "projectFolder": "apps/my-app",
|
||||
//
|
||||
// /**
|
||||
// * An optional category for usage in the "browser-approved-packages.json"
|
||||
// * and "nonbrowser-approved-packages.json" files. The value must be one of the
|
||||
// * strings from the "reviewCategories" defined above.
|
||||
// */
|
||||
// "reviewCategory": "production",
|
||||
//
|
||||
// /**
|
||||
// * A list of local projects that appear as devDependencies for this project, but cannot be
|
||||
// * locally linked because it would create a cyclic dependency; instead, the last published
|
||||
// * version will be installed in the Common folder.
|
||||
// */
|
||||
// "cyclicDependencyProjects": [
|
||||
// // "my-toolchain"
|
||||
// ],
|
||||
//
|
||||
// /**
|
||||
// * If true, then this project will be ignored by the "rush check" command.
|
||||
// * The default value is false.
|
||||
// */
|
||||
// // "skipRushCheck": false,
|
||||
//
|
||||
// /**
|
||||
// * A flag indicating that changes to this project will be published to npm, which affects
|
||||
// * the Rush change and publish workflows. The default value is false.
|
||||
// * NOTE: "versionPolicyName" and "shouldPublish" are alternatives; you cannot specify them both.
|
||||
// */
|
||||
// // "shouldPublish": false,
|
||||
//
|
||||
// /**
|
||||
// * An optional version policy associated with the project. Version policies are defined
|
||||
// * in "version-policies.json" file. See the "rush publish" documentation for more info.
|
||||
// * NOTE: "versionPolicyName" and "shouldPublish" are alternatives; you cannot specify them both.
|
||||
// */
|
||||
// // "versionPolicyName": ""
|
||||
// },
|
||||
//
|
||||
{
|
||||
"packageName": "@microsoft.azure/tasks",
|
||||
"projectFolder": "libraries/tasks",
|
||||
"reviewCategory": "production"
|
||||
},
|
||||
//
|
||||
// {
|
||||
// "packageName": "my-toolchain",
|
||||
// "projectFolder": "tools/my-toolchain",
|
||||
// "reviewCategory": "tools"
|
||||
// }
|
||||
]
|
||||
}
|
Загрузка…
Ссылка в новой задаче