This commit is contained in:
qiaozha 2019-12-12 10:23:41 +08:00
Родитель f9658bee31
Коммит 10ae4963fc
23 изменённых файлов: 3327 добавлений и 0 удалений

73
.scripts/for-each.js Normal file
Просмотреть файл

@ -0,0 +1,73 @@
const { spawn } = require('child_process');
const { readFileSync } = require('fs');
const { resolve } = require('path');
function read(filename) {
const txt = readFileSync(filename, "utf8")
.replace(/\r/gm, "")
.replace(/\n/gm, "«")
.replace(/\/\*.*?\*\//gm, "")
.replace(/«/gm, "\n")
.replace(/\s+\/\/.*/g, "");
return JSON.parse(txt);
}
const repo = `${__dirname}/..`;
const rush = read(`${repo}/rush.json`);
const pjs = {};
function forEachProject(onEach) {
// load all the projects
for (const each of rush.projects) {
const packageName = each.packageName;
const projectFolder = resolve(`${repo}/${each.projectFolder}`);
const project = JSON.parse(readFileSync(`${projectFolder}/package.json`));
onEach(packageName, projectFolder, project);
}
}
function npmForEach(cmd) {
let count = 0;
let exitCode = 0;
const result = {};
const procs = [];
const t1 = process.uptime() * 100;
forEachProject((name, location, project) => {
// checks for the script first
if (project.scripts[cmd]) {
count++;
const proc = spawn("npm", ["--silent", "run", cmd], { cwd: location, shell: true, stdio: "inherit" });
procs.push(proc);
result[name] = {
name, location, project, proc,
};
}
});
procs.forEach(proc => proc.on("close", (code, signal) => {
count--;
exitCode += code;
if (count === 0) {
const t2 = process.uptime() * 100;
console.log('---------------------------------------------------------');
if (exitCode !== 0) {
console.log(` Done : command '${cmd}' - ${Math.floor(t2 - t1) / 100} s -- Errors ${exitCode} `)
} else {
console.log(` Done : command '${cmd}' - ${Math.floor(t2 - t1) / 100} s -- No Errors `)
}
console.log('---------------------------------------------------------');
process.exit(exitCode);
}
}));
return result;
}
module.exports.forEachProject = forEachProject;
module.exports.npm = npmForEach;
module.exports.projectCount = rush.projects.length;

128
.scripts/generate-tests.ps1 Normal file
Просмотреть файл

@ -0,0 +1,128 @@
[CmdletBinding()]
param (
[Parameter()]
[string[]]
$swaggers,
[Parameter()]
[string]
$outputRoot = $null,
[Parameter()]
[switch]
$useLocalAutorest
)
# load test names
. $PSScriptRoot/tests.ps1
if( $swaggers -ne $null) {
$azureInputs = $azureInputs |% { if( $swaggers.indexOf( $_ ) -gt -1 ) { return $_ } }
$inputs = $inputs |% { if( $swaggers.indexOf( $_ ) -gt -1 ) { return $_ } }
}
# generates the AutoRest tests into separate modules
$root = ( resolve-path "$PSScriptRoot/..").Path
if( ($outputRoot -eq $null ) -or ($outputRoot -eq '')) {
$outputRoot = ( resolve-path "$root/tests").Path
}
$null = New-Item $outputRoot -force -ItemType Directory
cd $root
# start @autorest/test-server
./powershell/node_modules/.bin/start-autorest-testserver
start-sleep 5
# source location for swagger files
$swaggerRoot = "http://localhost:3000/swagger/"
# AutoRest Choice
if( $useLocalAutorest) {
$autorest='node'
$autorestArgs = @( (resolve-path $root/../autorest), "--version:$(resolve-path $root/../autorest)" )
} else {
$autorest = (get-command autorest-beta -ea 0 ).Source
if( -not $autorest ) {
$autorest = resolve-path "$root/powershell/node_modules/.bin/autorest-beta"
}
}
# use local generator
$powershellGenerator="--use:$(resolve-path $root/powershell)"
# use local remodeler if it's here.
if( test-path $root/../autorest.remodeler/remodeler ) {
$remodeler="--use:$(resolve-path $root/../autorest.remodeler/remodeler)"
}
$success = @{}
$errors = @{}
$broken = @{}
function run-autorest($src) {
$name = $src
$src = "$name.json"
$outputFolder = "$outputRoot/$name"
$txt = "$autorest $autorestArgs $powershellGenerator $remodeler --input-file:$swaggerRoot$src --output-folder:$outputFolder --clear-output-folder --title:$name $args"
write-host -fore GREEN "`n--------------------------------------------------------`nGenerating [$name]`n--------------------------------------------------------`n"
& $autorest $autorestArgs $powershellGenerator $remodeler "--input-file:$swaggerRoot$src" "--output-folder:$outputFolder" "--clear-output-folder" "--title:$name" $args
$rc = $LastExitCode
if( $rc -gt 0 ) {
write-host -fore RED "`n--------------------------------------------------------`nFAILED GENERATION [$name]`n--------------------------------------------------------`n"
$errors[$src] = $txt
} else {
& "$outputFolder/build-module.ps1"
$rc2 = $lastExitCode
if( $rc2 -gt 0 ){
write-host -fore RED "`n--------------------------------------------------------`nFAILED COMPILATION [$name]`n--------------------------------------------------------`n"
$broken[$src] = $txt
} else {
write-host -fore GREEN "`n--------------------------------------------------------`nSUCCESS [$name]`n--------------------------------------------------------`n"
$success[$src] = $txt
}
}
}
$n = 0;
$inputs |% {
if( $n -le 99 ) {
$j = get-process java -ea 0
if( $j -eq $null ) {
exit 1;
}
run-autorest $_
}
$n = $n + 1
}
$azureInputs |% {
run-autorest $_ --azure
}
# stop @autorest/test-server
cd $root
./powershell/node_modules/.bin/stop-autorest-testserver
$success.Keys |% {
write-host -fore GREEN $_
}
$errors.Keys |% {
write-host -fore RED $_
}
$broken.Keys |% {
write-host -fore YELLOW $_
}

2
.scripts/npm-run.js Normal file
Просмотреть файл

@ -0,0 +1,2 @@
// Runs the npm run command on each project that has it.
require('./for-each').npm(process.argv[2]);

92
.scripts/run-tests.ps1 Normal file
Просмотреть файл

@ -0,0 +1,92 @@
[CmdletBinding()]
param (
[Parameter()]
[string[]]
$swaggers,
[switch]$Live,
[switch]$Record,
[switch]$Playback
)
$root = ( resolve-path "$PSScriptRoot/..").Path
$outputRoot = ( resolve-path "$root/tests").Path
if (-not (Get-Module -ListAvailable -Name pester)) {
write-host -fore:red 'install pester module before running this script'
write-host -fore:cyan 'install-module -scope currentuser -name pester -force'
exit 1;
}
. $PSScriptRoot/tests.ps1
if( $swaggers -ne $null) {
$azureInputs = $azureInputs |% { if( $swaggers.indexOf( $_ ) -gt -1 ) { return $_ } }
$inputs = $inputs |% { if( $swaggers.indexOf( $_ ) -gt -1 ) { return $_ } }
}
if( $Live -or $Record ) {
& (get-command powershell/node_modules/.bin/start-autorest-testserver).Path
}
$total = 0
$errors = @{}
$success = @{}
function run-tests($src) {
$name = $src
$outputFolder = "$outputRoot/$name"
write-host -fore GREEN "`n--------------------------------------------------------`nTesting Module [$name]`n--------------------------------------------------------`n"
& $outputFolder/test-module.ps1 -Live:$Live -Record:$record -Playback:$playback
$rc = [int]$LastExitCode
$script:total = $script:total + [int]$rc
if( $rc -gt 0 ) {
write-host -fore RED "`n--------------------------------------------------------`nFAILED Test Execution [$name]`n--------------------------------------------------------`n"
$errors[$name] = $rc
} else {
$success[$name] = $name
}
}
$inputs |% {
run-tests $_
}
$azureInputs |% {
run-tests $_
}
if( $success.Keys.Count -gt 0 ) {
$count = $success.Keys.Count
write-host "`n`n"
write-host -fore:green "Modules passing: $count"
write-host -fore:green "--------------------------------------------------------"
$success.Keys |% {
write-host -fore GREEN $_
}
}
if( $total -ne 0) {
$count = $errors.Keys.Count
write-host "`n`n"
write-host -fore:red "Failing: `n modules: " -nonewline
write-host -fore:white $count -nonewline
write-host -fore:red "`n tests: " -nonewline
write-host -fore:white $total
write-host -fore:red "--------------------------------------------------------"
$errors.Keys |% {
write-host -fore:RED " $_ : " -nonewline
write-host -fore:white $errors[$_]
}
write-host "`n`n"
write-error "Not Successful."
exit $total
}
if( $Live -or $Record ) {
& (get-command powershell/node_modules/.bin/stop-autorest-testserver).Path
}

44
.scripts/set-versions.js Normal file
Просмотреть файл

@ -0,0 +1,44 @@
const { exec } = require('child_process');
const { writeFileSync } = require('fs');
const { forEachProject, projectCount } = require('./for-each');
let count = projectCount;
function updateVersion(name, project, location, patch) {
const origJson = JSON.stringify(project, null, 2);
// update the third digit
const verInfo = project.version.split('.');
verInfo[2] = patch;
project.version = verInfo.join('.');
// write the file if it's changed
const newJson = JSON.stringify(project, null, 2);
if (origJson !== newJson) {
console.log(`Writing project '${name}' version to '${project.version}' in '${location}'`);
writeFileSync(`${location}/package.json`, newJson)
}
count--;
if (count === 0) {
// last one!
// call sync-versions
require('./sync-versions');
}
}
if (process.argv[2] === '--reset') {
forEachProject((name, location, project) => {
updateVersion(name, project, location, 0);
})
} else {
// Sets the patch version on each package.json in the project.
forEachProject((name, location, project) => {
exec(`git rev-list --parents HEAD --count --full-history .`, { cwd: location }, (o, stdout) => {
const patch = (parseInt(stdout.trim()) + (Number(project.patchOffset) || -1));
updateVersion(name, project, location, patch);
});
});
}

142
.scripts/sync-versions.js Normal file
Просмотреть файл

@ -0,0 +1,142 @@
const { readFileSync, writeFileSync } = require('fs');
function read(filename) {
const txt = readFileSync(filename, 'utf8')
.replace(/\r/gm, '')
.replace(/\n/gm, '«')
.replace(/\/\*.*?\*\//gm, '')
.replace(/«/gm, '\n')
.replace(/\s+\/\/.*/g, '');
return JSON.parse(txt);
}
const packageList = {};
const rush = read(`${__dirname}/../rush.json`);
const pjs = {};
function writeIfChanged(filename, content) {
const orig = JSON.parse(readFileSync(filename))
const origJson = JSON.stringify(orig, null, 2);
const json = JSON.stringify(content, null, 2);
if (origJson !== json) {
console.log(`Writing updated file '${filename}'`)
writeFileSync(filename, json)
return true;
}
return false;
}
function versionToInt(ver) {
let v = ver.replace(/[^\d\.]/g, '').split('.').slice(0, 3);
while (v.length < 3) {
v.unshift(0);
}
let n = 0;
for (let i = 0; i < v.length; i++) {
n = n + ((2 ** (i * 16)) * parseInt(v[v.length - 1 - i]))
}
return n;
}
function setPeerDependencies(dependencies) {
for (const dep in dependencies) {
const ref = pjs[dep];
if (ref) {
if (dependencies[dep] !== `~${ref.version}`) {
console.log(`updating peer depedency ${dep} to ~${ref.version}`);
dependencies[dep] = `~${ref.version}`;
}
}
}
}
function recordDeps(dependencies) {
for (const packageName in dependencies) {
const packageVersion = dependencies[packageName];
if (packageList[packageName]) {
// same version?
if (packageList[packageName] === packageVersion) {
continue;
}
console.log(`${packageName} has ['${packageList[packageName]}','${packageVersion}']`);
// pick the higher one
const v = versionToInt(packageVersion);
if (v === 0) {
console.error(`Unparsed version ${packageName}:${packageVersion}`);
process.exit(1);
}
const v2 = versionToInt(packageList[packageName]);
if (v > v2) {
packageList[packageName] = packageVersion;
}
} else {
packageList[packageName] = packageVersion;
}
}
}
function fixDeps(pj, dependencies) {
for (const packageName in dependencies) {
if (dependencies[packageName] !== packageList[packageName]) {
console.log(`updating ${pj}:${packageName} from '${dependencies[packageName]}' to '${packageList[packageName]}'`)
dependencies[packageName] = packageList[packageName];
}
}
}
// load all the projects
for (const each of rush.projects) {
const packageName = each.packageName;
const projectFolder = each.projectFolder;
pjs[packageName] = JSON.parse(readFileSync(`${__dirname}/../${projectFolder}/package.json`));
}
// verify that peer dependencies are the same version as they are building.
for (const pj of Object.getOwnPropertyNames(pjs)) {
const each = pjs[pj];
setPeerDependencies(each.dependencies);
setPeerDependencies(each.devDependencies);
if (each['static-link']) {
setPeerDependencies(each['static-link'].dependencies);
}
}
// now compare to see if someone has an exnternal package with different version
// than everyone else.
for (const pj of Object.getOwnPropertyNames(pjs)) {
const each = pjs[pj];
recordDeps(each.dependencies);
recordDeps(each.devDependencies);
if (each['static-link']) {
recordDeps(each['static-link'].dependencies);
}
}
for (const pj of Object.getOwnPropertyNames(pjs)) {
const each = pjs[pj];
fixDeps(pj, each.dependencies);
fixDeps(pj, each.devDependencies);
if (each['static-link']) {
fixDeps(pj, each['static-link'].dependencies);
}
}
var changed = 0;
// write out the results.
for (const each of rush.projects) {
const packageName = each.packageName;
const projectFolder = each.projectFolder;
if (writeIfChanged(`${__dirname}/../${projectFolder}/package.json`, pjs[packageName])) {
changed++;
}
}
if (changed) {
console.log(`Updated ${changed} files.`);
} else {
console.log('No changes made')
}

65
.scripts/tests.ps1 Normal file
Просмотреть файл

@ -0,0 +1,65 @@
$inputs = @(
"extensible-enums-swagger",
"paging",
"subscriptionId-apiVersion",
"url-multi-collectionFormat",
"validation"
"custom-baseUrl-more-options",
"body-number",
"body-number.quirks",
"body-boolean",
"body-boolean.quirks",
"body-byte",
"body-date",
"body-datetime",
"body-datetime-rfc1123",
"body-duration",
"body-integer",
"httpInfrastructure",
"httpInfrastructure.quirks",
"required-optional",
"body-string",
"report",
"head",
"head-exceptions",
"url",
"custom-baseUrl"
"body-array",
"body-complex",
"body-file",
"complex-model",
"body-string.quirks",
"body-dictionary"
)
$unsupported = @(
# ERROR Compiling
# P1 Error Generating
# "body-formdata-urlencoded", -- formdata is not currently supported
# "body-formdata", -- formdata is not currently supported
# "header", -- headers as enum require further development
# "additionalProperties", -- when there is already a property named additionalProperties in a class with additionalProperties, there is a collision.
# "storage", -- some problems with implementation of virtual properties
# "xml-service", -- xml not currently supported
# "xms-error-responses" -- xml not currently supported
# "parameter-flattening" -- tags has multiple types when proxies combine.
# "model-flattening", - needs directive to work around circular reference
# "lro", -- location property conflicts with Location header property.
# P1 Error compiling
)
$azureInputs = @(
"azure-special-properties", # ERROR GENERATING
"azure-parameter-grouping", # ERROR GENERATING
"azure-report", # ERROR COMPILING
"azure-resource", # ERROR COMPILING
"azure-resource-x"# ERROR COMPILING
)

Просмотреть файл

@ -0,0 +1,29 @@
$ErrorActionPreference = 'silentlycontinue'
write-host -fore green "Verifying requirements to build.`n"
write-host -fore cyan -NoNewline " Rush: "
$rush = get-command rush
if ( -not $rush ) {
write-host -fore red "NOT INSTALLED."
write-host -fore cyan " You must install 'rush' to continue:"
write-host -fore yellow ' > npm install -g "@microsoft/rush"'
write-host -fore red "`n`n`n"
exit 1
}
write-host -fore green "INSTALLED"
write-host -fore green "`nAll requirements met.`n"
write-host -fore cyan "Common rush commands:"
write-host -fore yellow ' > rush update ' -NoNewline
write-host -fore gray ' # installs package dependencies '
write-host -fore yellow ' > rush rebuild ' -NoNewline
write-host -fore gray ' # rebuilds all libraries'
write-host -fore yellow ' > rush watch ' -NoNewline
write-host -fore gray ' # continual build when files change'
write-host "`n`n`n"
exit 0

Просмотреть файл

@ -0,0 +1,33 @@
# Node.js
# Build a general Node.js project with npm.
# Add steps that analyze code, save build artifacts, deploy, and more:
# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript
trigger:
- master
pool:
vmImage: 'ubuntu-latest'
steps:
- task: NodeTool@0
inputs:
versionSpec: '10.x'
displayName: 'Install Node.js'
- script: |
npm install -g npm
npx @microsoft/rush update
npx @microsoft/rush rebuild
npx @microsoft/rush test
# install pester
pwsh -command install-module -scope currentuser -name pester -force
# generate the test modules
pwsh .scripts/generate-tests.ps1
# run the test module tests
pwsh .scripts/run-tests.ps1
displayName: 'Rush install, build and test'

25
.scripts/watch.js Normal file
Просмотреть файл

@ -0,0 +1,25 @@
var cp = require('child_process');
require('./for-each').forEachProject((packageName, projectFolder, project) => {
if (project.scripts.watch) {
console.log(`npm run watch {cwd: ${__dirname}/../${projectFolder}}`);
const proc = cp.spawn('npm', ['run', 'watch'], { cwd: projectFolder, shell: true, stdio: "inherit" });
proc.on("error", (c, s) => {
console.log(packageName);
console.error(c);
console.error(s);
});
proc.on('exit', (c, s) => {
console.log(packageName);
console.error(c);
console.error(s);
});
proc.on('message', (c, s) => {
console.log(packageName);
console.error(c);
console.error(s);
})
}
});

43
azure-pipelines.yml Normal file
Просмотреть файл

@ -0,0 +1,43 @@
# Node.js
# Build a general Node.js project with npm.
# Add steps that analyze code, save build artifacts, deploy, and more:
# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript
trigger:
- master
pool:
vmImage: 'ubuntu-latest'
steps:
- task: NodeTool@0
inputs:
versionSpec: '10.17.0'
displayName: 'Install Node.js'
- script: |
# ensure latest npm is installed
npm install -g npm
# make sure the versions are all synchronized and pull in dependencies
npx @microsoft/rush sync-versions
npx @microsoft/rush update
# set the actual package versions and update again
npx @microsoft/rush set-versions
npx @microsoft/rush sync-versions
npx @microsoft/rush update
# compile the code
npx @microsoft/rush rebuild
# build the packages
npx @microsoft/rush publish --publish --pack --include-all --tag latest
# publish the packages (tag as preview by default)
echo "//registry.npmjs.org/:_authToken=$(azure-sdk-npm-token)" > ./.npmrc
for file in common/temp/artifacts/packages/*.tgz
do
common/temp/pnpm-local/node_modules/.bin/pnpm publish $file --tag latest --access public || echo no-worries
done

12
common/config/rush/.npmrc Normal file
Просмотреть файл

@ -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,54 @@
{
"$schema": "https://developer.microsoft.com/json-schemas/rush/v5/command-line.schema.json",
"commands": [
{
"commandKind": "global",
"name": "set-versions",
"summary": "set the patch version in the package.json files",
"shellCommand": "node .scripts/set-versions.js"
},
{
"commandKind": "global",
"name": "reset-versions",
"summary": "reset the patch version in the package.json files to .0",
"shellCommand": "node .scripts/set-versions.js --reset"
},
{
"commandKind": "global",
"name": "sync-versions",
"summary": "sync versions of sibling projects",
"shellCommand": "node .scripts/sync-versions.js"
},
{
"commandKind": "global",
"name": "watch",
"summary": "run npm watch on all projects",
"shellCommand": "node .scripts/watch.js"
},
{
"commandKind": "global",
"name": "clean",
"summary": "run npm clean on all projects",
"shellCommand": "node .scripts/npm-run.js clean"
},
{
"commandKind": "global",
"name": "test",
"summary": "run all npm test",
"shellCommand": "node .scripts/npm-run.js test"
},
{
"commandKind": "global",
"name": "fix",
"summary": "run all npm fix",
"shellCommand": "node .scripts/npm-run.js eslint-fix"
},
{
"commandKind": "global",
"name": "lint",
"summary": "run all npm lint",
"shellCommand": "node .scripts/npm-run.js eslint"
}
],
"parameters": []
}

Просмотреть файл

@ -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,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,67 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See the @microsoft/rush package's LICENSE file for license information.
Object.defineProperty(exports, "__esModule", { value: true });
// THIS FILE WAS GENERATED BY A TOOL. ANY MANUAL MODIFICATIONS WILL GET OVERWRITTEN WHENEVER RUSH IS UPGRADED.
//
// This script is intended for usage in an automated build environment where the Rush command may not have
// been preinstalled, or may have an unpredictable version. This script will automatically install the version of Rush
// specified in the rush.json configuration file (if not already installed), and then pass a command-line to it.
// An example usage would be:
//
// node common/scripts/install-run-rush.js install
//
// For more information, see: https://rushjs.io/pages/maintainer/setup_new_repo/
const path = require("path");
const fs = require("fs");
const install_run_1 = require("./install-run");
const PACKAGE_NAME = '@microsoft/rush';
const RUSH_PREVIEW_VERSION = 'RUSH_PREVIEW_VERSION';
function _getRushVersion() {
const rushPreviewVersion = process.env[RUSH_PREVIEW_VERSION];
if (rushPreviewVersion !== undefined) {
console.log(`Using Rush version from environment variable ${RUSH_PREVIEW_VERSION}=${rushPreviewVersion}`);
return rushPreviewVersion;
}
const rushJsonFolder = install_run_1.findRushJsonFolder();
const rushJsonPath = path.join(rushJsonFolder, install_run_1.RUSH_JSON_FILENAME);
try {
const rushJsonContents = fs.readFileSync(rushJsonPath, 'utf-8');
// Use a regular expression to parse out the rushVersion value because rush.json supports comments,
// but JSON.parse does not and we don't want to pull in more dependencies than we need to in this script.
const rushJsonMatches = rushJsonContents.match(/\"rushVersion\"\s*\:\s*\"([0-9a-zA-Z.+\-]+)\"/);
return rushJsonMatches[1];
}
catch (e) {
throw new Error(`Unable to determine the required version of Rush from rush.json (${rushJsonFolder}). ` +
'The \'rushVersion\' field is either not assigned in rush.json or was specified ' +
'using an unexpected syntax.');
}
}
function _run() {
const [nodePath, /* Ex: /bin/node */ scriptPath, /* /repo/common/scripts/install-run-rush.js */ ...packageBinArgs /* [build, --to, myproject] */] = process.argv;
// Detect if this script was directly invoked, or if the install-run-rushx script was invokved to select the
// appropriate binary inside the rush package to run
const scriptName = path.basename(scriptPath);
const bin = scriptName.toLowerCase() === 'install-run-rushx.js' ? 'rushx' : 'rush';
if (!nodePath || !scriptPath) {
throw new Error('Unexpected exception: could not detect node path or script path');
}
if (process.argv.length < 3) {
console.log(`Usage: ${scriptName} <command> [args...]`);
if (scriptName === 'install-run-rush.js') {
console.log(`Example: ${scriptName} build --to myproject`);
}
else {
console.log(`Example: ${scriptName} custom-command`);
}
process.exit(1);
}
install_run_1.runWithErrorAndStatusCode(() => {
const version = _getRushVersion();
console.log(`The rush.json configuration requests Rush version ${version}`);
return install_run_1.installAndRun(PACKAGE_NAME, version, bin, packageBinArgs);
});
}
_run();
//# sourceMappingURL=install-run-rush.js.map

Просмотреть файл

@ -0,0 +1,18 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See the @microsoft/rush package's LICENSE file for license information.
Object.defineProperty(exports, "__esModule", { value: true });
// THIS FILE WAS GENERATED BY A TOOL. ANY MANUAL MODIFICATIONS WILL GET OVERWRITTEN WHENEVER RUSH IS UPGRADED.
//
// This script is intended for usage in an automated build environment where the Rush command may not have
// been preinstalled, or may have an unpredictable version. This script will automatically install the version of Rush
// specified in the rush.json configuration file (if not already installed), and then pass a command-line to the
// rushx command.
//
// An example usage would be:
//
// node common/scripts/install-run-rushx.js custom-command
//
// For more information, see: https://rushjs.io/pages/maintainer/setup_new_repo/
require("./install-run-rush");
//# sourceMappingURL=install-run-rushx.js.map

Просмотреть файл

@ -0,0 +1,418 @@
"use strict";
// Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the MIT license.
// See the @microsoft/rush package's LICENSE file for license information.
Object.defineProperty(exports, "__esModule", { value: true });
// THIS FILE WAS GENERATED BY A TOOL. ANY MANUAL MODIFICATIONS WILL GET OVERWRITTEN WHENEVER RUSH IS UPGRADED.
//
// This script is intended for usage in an automated build environment where a Node tool may not have
// been preinstalled, or may have an unpredictable version. This script will automatically install the specified
// version of the specified tool (if not already installed), and then pass a command-line to it.
// An example usage would be:
//
// node common/scripts/install-run.js qrcode@1.2.2 qrcode https://rushjs.io
//
// For more information, see: https://rushjs.io/pages/maintainer/setup_new_repo/
const childProcess = require("child_process");
const fs = require("fs");
const os = require("os");
const path = require("path");
exports.RUSH_JSON_FILENAME = 'rush.json';
const RUSH_TEMP_FOLDER_ENV_VARIABLE_NAME = 'RUSH_TEMP_FOLDER';
const INSTALLED_FLAG_FILENAME = 'installed.flag';
const NODE_MODULES_FOLDER_NAME = 'node_modules';
const PACKAGE_JSON_FILENAME = 'package.json';
/**
* Parse a package specifier (in the form of name\@version) into name and version parts.
*/
function _parsePackageSpecifier(rawPackageSpecifier) {
rawPackageSpecifier = (rawPackageSpecifier || '').trim();
const separatorIndex = rawPackageSpecifier.lastIndexOf('@');
let name;
let version = undefined;
if (separatorIndex === 0) {
// The specifier starts with a scope and doesn't have a version specified
name = rawPackageSpecifier;
}
else if (separatorIndex === -1) {
// The specifier doesn't have a version
name = rawPackageSpecifier;
}
else {
name = rawPackageSpecifier.substring(0, separatorIndex);
version = rawPackageSpecifier.substring(separatorIndex + 1);
}
if (!name) {
throw new Error(`Invalid package specifier: ${rawPackageSpecifier}`);
}
return { name, version };
}
/**
* Resolve a package specifier to a static version
*/
function _resolvePackageVersion(rushCommonFolder, { name, version }) {
if (!version) {
version = '*'; // If no version is specified, use the latest version
}
if (version.match(/^[a-zA-Z0-9\-\+\.]+$/)) {
// If the version contains only characters that we recognize to be used in static version specifiers,
// pass the version through
return version;
}
else {
// version resolves to
try {
const rushTempFolder = _getRushTempFolder(rushCommonFolder);
const sourceNpmrcFolder = path.join(rushCommonFolder, 'config', 'rush');
_syncNpmrc(sourceNpmrcFolder, rushTempFolder);
const npmPath = getNpmPath();
// This returns something that looks like:
// @microsoft/rush@3.0.0 '3.0.0'
// @microsoft/rush@3.0.1 '3.0.1'
// ...
// @microsoft/rush@3.0.20 '3.0.20'
// <blank line>
const npmVersionSpawnResult = childProcess.spawnSync(npmPath, ['view', `${name}@${version}`, 'version', '--no-update-notifier'], {
cwd: rushTempFolder,
stdio: []
});
if (npmVersionSpawnResult.status !== 0) {
throw new Error(`"npm view" returned error code ${npmVersionSpawnResult.status}`);
}
const npmViewVersionOutput = npmVersionSpawnResult.stdout.toString();
const versionLines = npmViewVersionOutput.split('\n').filter((line) => !!line);
const latestVersion = versionLines[versionLines.length - 1];
if (!latestVersion) {
throw new Error('No versions found for the specified version range.');
}
const versionMatches = latestVersion.match(/^.+\s\'(.+)\'$/);
if (!versionMatches) {
throw new Error(`Invalid npm output ${latestVersion}`);
}
return versionMatches[1];
}
catch (e) {
throw new Error(`Unable to resolve version ${version} of package ${name}: ${e}`);
}
}
}
let _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(rushTempFolder, packageInstallFolder) {
try {
const flagFile = path.resolve(packageInstallFolder, INSTALLED_FLAG_FILENAME);
if (fs.existsSync(flagFile)) {
fs.unlinkSync(flagFile);
}
const packageLockFile = path.resolve(packageInstallFolder, 'package-lock.json');
if (fs.existsSync(packageLockFile)) {
fs.unlinkSync(packageLockFile);
}
const nodeModulesFolder = path.resolve(packageInstallFolder, NODE_MODULES_FOLDER_NAME);
if (fs.existsSync(nodeModulesFolder)) {
const rushRecyclerFolder = _ensureAndJoinPath(rushTempFolder, 'rush-recycler', `install-run-${Date.now().toString()}`);
fs.renameSync(nodeModulesFolder, rushRecyclerFolder);
}
}
catch (e) {
throw new Error(`Error cleaning the package install folder (${packageInstallFolder}): ${e}`);
}
}
function _createPackageJson(packageInstallFolder, name, version) {
try {
const packageJsonContents = {
'name': 'ci-rush',
'version': '0.0.0',
'dependencies': {
[name]: version
},
'description': 'DON\'T WARN',
'repository': 'DON\'T WARN',
'license': 'MIT'
};
const packageJsonPath = path.join(packageInstallFolder, PACKAGE_JSON_FILENAME);
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJsonContents, undefined, 2));
}
catch (e) {
throw new Error(`Unable to create package.json: ${e}`);
}
}
/**
* Run "npm install" in the package install folder.
*/
function _installPackage(packageInstallFolder, name, version) {
try {
console.log(`Installing ${name}...`);
const npmPath = getNpmPath();
const result = childProcess.spawnSync(npmPath, ['install'], {
stdio: 'inherit',
cwd: packageInstallFolder,
env: process.env
});
if (result.status !== 0) {
throw new Error('"npm install" encountered an error');
}
console.log(`Successfully installed ${name}@${version}`);
}
catch (e) {
throw new Error(`Unable to install package: ${e}`);
}
}
/**
* Get the ".bin" path for the package.
*/
function _getBinPath(packageInstallFolder, binName) {
const binFolderPath = path.resolve(packageInstallFolder, NODE_MODULES_FOLDER_NAME, '.bin');
const resolvedBinName = (os.platform() === 'win32') ? `${binName}.cmd` : binName;
return path.resolve(binFolderPath, resolvedBinName);
}
/**
* Write a flag file to the package's install directory, signifying that the install was successful.
*/
function _writeFlagFile(packageInstallFolder) {
try {
const flagFilePath = path.join(packageInstallFolder, INSTALLED_FLAG_FILENAME);
fs.writeFileSync(flagFilePath, process.version);
}
catch (e) {
throw new Error(`Unable to create installed.flag file in ${packageInstallFolder}`);
}
}
function _getRushTempFolder(rushCommonFolder) {
const rushTempFolder = process.env[RUSH_TEMP_FOLDER_ENV_VARIABLE_NAME];
if (rushTempFolder !== undefined) {
_ensureFolder(rushTempFolder);
return rushTempFolder;
}
else {
return _ensureAndJoinPath(rushCommonFolder, 'temp');
}
}
function _ensureFolder(folderPath) {
if (!fs.existsSync(folderPath)) {
const parentDir = path.dirname(folderPath);
_ensureFolder(parentDir);
fs.mkdirSync(folderPath);
}
}
function installAndRun(packageName, packageVersion, packageBinName, packageBinArgs) {
const rushJsonFolder = findRushJsonFolder();
const rushCommonFolder = path.join(rushJsonFolder, 'common');
const rushTempFolder = _getRushTempFolder(rushCommonFolder);
const packageInstallFolder = _ensureAndJoinPath(rushTempFolder, 'install-run', `${packageName}@${packageVersion}`);
if (!_isPackageAlreadyInstalled(packageInstallFolder)) {
// The package isn't already installed
_cleanInstallFolder(rushTempFolder, packageInstallFolder);
const sourceNpmrcFolder = path.join(rushCommonFolder, 'config', 'rush');
_syncNpmrc(sourceNpmrcFolder, packageInstallFolder);
_createPackageJson(packageInstallFolder, packageName, packageVersion);
_installPackage(packageInstallFolder, packageName, packageVersion);
_writeFlagFile(packageInstallFolder);
}
const statusMessage = `Invoking "${packageBinName} ${packageBinArgs.join(' ')}"`;
const statusMessageLine = new Array(statusMessage.length + 1).join('-');
console.log(os.EOL + statusMessage + os.EOL + statusMessageLine + os.EOL);
const binPath = _getBinPath(packageInstallFolder, packageBinName);
const result = childProcess.spawnSync(binPath, packageBinArgs, {
stdio: 'inherit',
cwd: process.cwd(),
env: process.env
});
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 */ scriptPath, /* /repo/common/scripts/install-run-rush.js */ rawPackageSpecifier, /* qrcode@^1.2.0 */ packageBinName, /* qrcode */ ...packageBinArgs /* [-f, myproject/lib] */] = process.argv;
if (!nodePath) {
throw new Error('Unexpected exception: could not detect node path');
}
if (path.basename(scriptPath).toLowerCase() !== 'install-run.js') {
// If install-run.js wasn't directly invoked, don't execute the rest of this function. Return control
// to the script that (presumably) imported this file
return;
}
if (process.argv.length < 4) {
console.log('Usage: install-run.js <package>@<version> <command> [args...]');
console.log('Example: install-run.js qrcode@1.2.2 qrcode https://rushjs.io');
process.exit(1);
}
runWithErrorAndStatusCode(() => {
const rushJsonFolder = findRushJsonFolder();
const rushCommonFolder = _ensureAndJoinPath(rushJsonFolder, 'common');
const packageSpecifier = _parsePackageSpecifier(rawPackageSpecifier);
const name = packageSpecifier.name;
const version = _resolvePackageVersion(rushCommonFolder, packageSpecifier);
if (packageSpecifier.version !== version) {
console.log(`Resolved to ${name}@${version}`);
}
return installAndRun(name, version, packageBinName, packageBinArgs);
});
}
_run();
//# sourceMappingURL=install-run.js.map

1690
package-lock.json сгенерированный Normal file

Разница между файлами не показана из-за своего большого размера Загрузить разницу

46
package.json Normal file
Просмотреть файл

@ -0,0 +1,46 @@
{
"name": "@autorest/cli.common",
"version": "1.0.0",
"description": "Autorest Azure Cli Common Module",
"main": "dist/index.js",
"engines": {
"node": ">=10.12.0"
},
"scripts": {
"start": "node dist/index.js",
"debug": "node --max_old_space_size=4096 --inspect-brk ./dist/index.js",
"eslint-fix": "eslint . --fix --ext .ts",
"eslint": "eslint . --ext .ts",
"build": "tsc -p .",
"start-testserver": "./node_modules/.bin/start-autorest-testserver",
"stop-testserver": "./node_modules/.bin/stop-autorest-testserver",
"watch": "tsc -p . --watch",
"prepare": "npm run build",
"test": "npm run build && mocha dist/test",
"clean": "ver > nul 2>&1 nul && npm run --silent clean-cmd || npm run --silent clean-bash",
"clean-cmd": "if exist dist rmdir /s /q dist && exit 0 || exit 0 ",
"clean-bash": "rm nul && rm -rf dist && exit 0 || exit 0"
},
"repository": {
"type": "git",
"url": "git+https://github.com/Azure/autorest.cli.common.git"
},
"keywords": [
"autorest",
"extension"
],
"author": "Microsoft Corporation",
"license": "MIT",
"devDependencies": {
"@types/node": "10.17.0",
"eslint": "~5.4.0",
"node-yaml": "^3.2.0"
},
"dependencies": {
"@azure-tools/autorest-extension-base": "~3.1.0",
"node-yaml": "^3.2.0"
},
"files": [
"dist"
]
}

104
rush.json Normal file
Просмотреть файл

@ -0,0 +1,104 @@
/**
* 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.12.0",
/**
* 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",
/**
* 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",
"ensureConsistentVersions": true,
"projectFolderMinDepth": 1,
"projectFolderMaxDepth": 2,
"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,
"projects": [
{
"packageName": "@autorest/cli.common",
"projectFolder": ".",
"reviewCategory": "production",
"shouldPublish": true
}
]
}

101
src/index.ts Normal file
Просмотреть файл

@ -0,0 +1,101 @@
import { AutoRestExtension, Channel } from '@azure-tools/autorest-extension-base';
import * as yaml from "node-yaml";
export type LogCallback = (message: string) => void;
export type FileCallback = (path: string, rows: string[]) => void;
const extension = new AutoRestExtension();
export enum ArtifactType
{
ArtifactTypeAzureAzModule,
ArtifactTypeAzureAzExtension,
}
extension.Add("cli-common", async autoRestApi => {
let log = await autoRestApi.GetValue("log");
function Info(s: string)
{
if (log)
{
autoRestApi.Message({
Channel: Channel.Information,
Text: s
});
}
}
function Error(s: string)
{
autoRestApi.Message({
Channel: Channel.Error,
Text: s
});
}
try
{
// read files offered to this plugin
const inputFileUris = await autoRestApi.ListInputs();
const inputFiles: string[] = await Promise.all(inputFileUris.map(uri => autoRestApi.ReadFile(uri)));
let artifactType: ArtifactType;
let writeIntermediate: boolean = false;
// namespace is the only obligatory option
// we will derive default "package-name" and "root-name" from it
const namespace = await autoRestApi.GetValue("namespace");
if (!namespace)
{
Error("\"namespace\" is not defined, please add readme.az.md file to the specification.");
return;
}
// package name and group name can be guessed from namespace
let packageName = await autoRestApi.GetValue("package-name") || namespace.replace(/\./g, '-');
let cliCommonName = await autoRestApi.GetValue("group-name") || await autoRestApi.GetValue("cli-common-name") || packageName.split('-').pop();
let tag = await autoRestApi.GetValue("tag");
Info(tag);
// Handle generation type parameter
if (await autoRestApi.GetValue("cli-common"))
{
Info("GENERATION: --cli-common");
artifactType = (await autoRestApi.GetValue("extension")) ? ArtifactType.ArtifactTypeAzureAzExtension : ArtifactType.ArtifactTypeAzureAzModule;
}
for (let iff of inputFiles)
{
//-------------------------------------------------------------------------------------------------------------------------
//
// PARSE INPUT MODEL
//
//-------------------------------------------------------------------------------------------------------------------------
let swagger = JSON.parse(iff);
//-------------------------------------------------------------------------------------------------------------------------
//
// WRITE INTERMEDIATE FILE IF --intermediate OPTION WAS SPECIFIED
//
//-------------------------------------------------------------------------------------------------------------------------
if (writeIntermediate)
{
autoRestApi.WriteFile("intermediate/" + cliCommonName + "-input.yml", yaml.dump(swagger));
}
}
}
catch (e)
{
Error(e.message + " -- " + JSON.stringify(e.stack));
}
});
extension.Run();

17
tsconfig.json Normal file
Просмотреть файл

@ -0,0 +1,17 @@
{
"compilerOptions": {
"lib": [
"es2016",
"dom"
],
"outDir": "dist",
"module": "commonjs",
"types": [
"node"
],
"target": "es2016"
},
"include": [
"src"
]
}