2017-04-18 18:18:22 +03:00
/ *
* Copyright ( c ) Microsoft Corporation . All rights reserved .
* Licensed under the MIT License . See License . txt in the project root for
* license information .
* /
2016-02-28 06:30:26 +03:00
2017-03-18 21:43:33 +03:00
const gulp = require ( 'gulp' ) ;
const args = require ( 'yargs' ) . argv ;
const colors = require ( 'colors' ) ;
const fs = require ( 'fs' ) ;
const util = require ( 'util' ) ;
const path = require ( 'path' ) ;
2017-03-25 22:15:52 +03:00
const glob = require ( 'glob' ) ;
2017-03-18 21:43:33 +03:00
const execSync = require ( 'child_process' ) . execSync ;
2018-03-29 20:40:21 +03:00
const jsonStableStringify = require ( 'json-stable-stringify' ) ;
2016-02-28 06:30:26 +03:00
2017-08-26 04:53:43 +03:00
var mappings = require ( './codegen_mappings.json' ) ;
2016-02-28 06:30:26 +03:00
2017-08-26 04:53:43 +03:00
const defaultAutoRestVersion = '1.2.2' ;
2016-03-01 10:11:50 +03:00
var usingAutoRestVersion ;
2018-03-22 20:21:42 +03:00
const specRoot = args [ 'spec-root' ] || 'https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification' ;
2017-03-18 21:43:33 +03:00
const project = args [ 'project' ] ;
2018-03-20 22:49:27 +03:00
const use = args [ 'use' ] ;
2016-03-01 10:11:50 +03:00
var modeler = 'Swagger' ;
2017-09-29 21:41:15 +03:00
const regexForExcludedServices = /\/(intune|documentdbManagement|insightsManagement|insights|search)\//i ;
2016-03-01 05:32:11 +03:00
2017-03-18 21:43:33 +03:00
function getAutorestVersion ( version ) {
if ( ! version ) version = 'latest' ;
let getVersion , execHelp ;
let result = true ;
2016-03-01 10:11:50 +03:00
try {
2017-09-26 01:43:58 +03:00
let getVersionCmd = ` autorest ` ;
2017-03-18 21:43:33 +03:00
let execHelpCmd = ` autorest --help ` ;
console . log ( getVersionCmd ) ;
getVersion = execSync ( getVersionCmd , { encoding : 'utf8' } ) ;
//console.debug(getVersion);
console . log ( execHelpCmd ) ;
execHelp = execSync ( execHelpCmd , { encoding : 'utf8' } ) ;
//console.debug(execHelp);
2016-03-01 10:11:50 +03:00
} catch ( err ) {
2017-03-18 21:43:33 +03:00
result = false ;
console . log ( ` An error occurred while getting the " ${ version } " of autorest and executing "autorest --help": \n ${ util . inspect ( err , { depth : null } )}. ` ) ;
2016-03-01 10:11:50 +03:00
}
2017-03-18 21:43:33 +03:00
return result ;
2016-03-01 10:11:50 +03:00
}
2017-03-25 22:59:14 +03:00
function deleteFolderRecursive ( path ) {
if ( fs . existsSync ( path ) ) {
fs . readdirSync ( path ) . forEach ( function ( file , index ) {
2018-03-22 20:21:42 +03:00
var curPath = path + '/' + file ;
2017-03-25 22:59:14 +03:00
if ( fs . lstatSync ( curPath ) . isDirectory ( ) ) { // recurse
deleteFolderRecursive ( curPath ) ;
} else { // delete file
fs . unlinkSync ( curPath ) ;
}
2016-03-01 10:11:50 +03:00
} ) ;
2017-03-25 22:59:14 +03:00
fs . rmdirSync ( path ) ;
2016-03-01 10:11:50 +03:00
}
2018-03-22 20:21:42 +03:00
}
2017-03-25 22:59:14 +03:00
2017-03-25 22:15:52 +03:00
function clearProjectBeforeGenerating ( projectDir ) {
let modelsDir = ` ${ projectDir } /models ` ;
let operationsDir = ` ${ projectDir } /operations ` ;
2017-03-26 05:50:52 +03:00
let clientTypedefFile = path . basename ( glob . sync ( ` ${ projectDir } /*.d.ts ` ) [ 0 ] || '' ) ;
2017-03-25 22:15:52 +03:00
let clientJSFile = ` ${ clientTypedefFile . split ( '.' ) [ 0 ] } .js ` ;
let directoriesToBeDeleted = [ modelsDir , operationsDir ] ;
let filesToBeDeleted = [ clientTypedefFile , clientJSFile ] ;
directoriesToBeDeleted . forEach ( ( dir ) => {
if ( fs . existsSync ( dir ) ) {
2017-03-25 22:59:14 +03:00
deleteFolderRecursive ( dir ) ;
2017-03-25 22:15:52 +03:00
}
} ) ;
filesToBeDeleted . forEach ( ( file ) => {
if ( fs . existsSync ( file ) ) {
fs . unlinkSync ( file ) ;
}
} ) ;
return ;
2016-03-01 10:11:50 +03:00
}
2017-08-26 04:53:43 +03:00
function generateProject ( projectObj , specRoot , autoRestVersion ) {
let specPath = specRoot + '/' + projectObj . source ;
2018-03-22 20:21:42 +03:00
let isInputJson = projectObj . source . endsWith ( 'json' ) ;
2017-03-18 21:43:33 +03:00
let result ;
2017-08-26 04:53:43 +03:00
const azureTemplate = 'Azure.NodeJs' ;
2018-03-22 20:00:23 +03:00
let language = azureTemplate ;
2016-03-01 05:32:11 +03:00
//servicefabric wants to generate using generic NodeJS.
2017-08-26 04:53:43 +03:00
if ( projectObj . language && projectObj . language . match ( /^NodeJS$/ig ) !== null ) {
language = projectObj . language ;
2016-03-01 10:11:50 +03:00
}
2017-08-26 04:53:43 +03:00
let packageName = projectObj . packageName ;
2017-09-28 02:32:53 +03:00
console . log ( ` \n >>>>>>>>>>>>>>>>>>>Start: " ${ packageName } " >>>>>>>>>>>>>>>>>>>>>>>>> ` ) ;
2018-03-20 22:49:27 +03:00
let outputDir = ` ${ _ _dirname } /lib/services/ ${ projectObj . dir } ` ;
let cmd = 'autorest' ;
2017-09-28 02:32:53 +03:00
if ( projectObj . batchGeneration ) {
2018-03-20 22:49:27 +03:00
cmd += ` --nodejs-sdks-folder= ${ outputDir } ` ;
2017-09-28 02:32:53 +03:00
} else {
2018-03-20 22:49:27 +03:00
cmd += ` --nodejs.output-folder= ${ outputDir } ` ;
2017-09-28 02:32:53 +03:00
}
2018-03-22 20:14:42 +03:00
cmd += ` --package-name= ${ packageName } ` ;
let packageVersion = projectObj . packageVersion ;
if ( packageVersion ) {
cmd += ` --package-version= ${ packageVersion } ` ;
}
cmd += ` --nodejs --license-header=MICROSOFT_MIT_NO_VERSION ` ;
2017-08-26 04:53:43 +03:00
// if using azure template, pass in azure-arm argument. otherwise, get the generic template by not passing in anything.
if ( language === azureTemplate ) cmd += ' --azure-arm ' ;
if ( isInputJson ) {
2018-03-20 22:49:27 +03:00
cmd += ` --input-file= ${ specPath } ` ;
2017-08-26 04:53:43 +03:00
}
else {
2018-03-20 22:49:27 +03:00
cmd += ` ${ specPath } ` ;
}
if ( use ) {
cmd += ` --use= ${ use } ` ;
2017-08-26 04:53:43 +03:00
}
2018-03-23 00:49:59 +03:00
if ( projectObj . generatePackageJson ) {
cmd += ` --nodejs.generate-package-json=true ` ;
}
if ( projectObj . generateReadmeMd ) {
cmd += ` --nodejs.generate-readme-md=true ` ;
2018-03-21 01:55:21 +03:00
}
2018-03-23 23:00:10 +03:00
if ( projectObj . generateLicenseTxt ) {
cmd += ` --nodejs.generate-license-txt=true ` ;
}
2017-08-26 04:53:43 +03:00
if ( projectObj . ft !== null && projectObj . ft !== undefined ) cmd += ' --payload-flattening-threshold=' + projectObj . ft ;
if ( projectObj . clientName !== null && projectObj . clientName !== undefined ) cmd += ' --override-client-name=' + projectObj . clientName ;
2017-09-28 02:32:53 +03:00
if ( projectObj . tag !== null && projectObj . tag !== undefined ) cmd += ` --tag= ${ projectObj . tag } ` ;
2017-08-26 04:53:43 +03:00
if ( projectObj . args !== undefined ) {
2018-03-20 22:49:27 +03:00
cmd += ` ${ args } ` ;
2016-02-28 06:30:26 +03:00
}
2017-03-18 21:43:33 +03:00
try {
2017-09-28 02:32:53 +03:00
//console.log(`Cleaning the output directory: "${outputDir}".`);
//clearProjectBeforeGenerating(outputDir);
2017-03-18 21:43:33 +03:00
console . log ( 'Executing command:' ) ;
console . log ( '------------------------------------------------------------' ) ;
console . log ( cmd ) ;
console . log ( '------------------------------------------------------------' ) ;
result = execSync ( cmd , { encoding : 'utf8' } ) ;
console . log ( 'Output:' ) ;
console . log ( result ) ;
} catch ( err ) {
console . log ( 'Error:' ) ;
2017-09-28 02:32:53 +03:00
console . log ( ` An error occurred while generating client for package: " ${ packageName } ": \n ${ err . stderr } ` ) ;
2017-03-18 21:43:33 +03:00
}
2017-09-28 02:32:53 +03:00
console . log ( ` >>>>>>>>>>>>>>>>>>>>>End: " ${ packageName } " >>>>>>>>>>>>>>>>>>>>>>>>> \n ` ) ;
2017-03-18 21:43:33 +03:00
return ;
}
function installAutorest ( ) {
let installation ;
let isSuccessful = true ;
let autorestAlreadyInstalled = true ;
try {
execSync ( ` autorest --help ` ) ;
} catch ( error ) {
autorestAlreadyInstalled = false ;
}
try {
if ( ! autorestAlreadyInstalled ) {
console . log ( 'Looks like autorest is not installed on your machine. Installing autorest . . .' ) ;
let installCmd = 'npm install -g autorest' ;
console . log ( installCmd ) ;
installation = execSync ( installCmd , { encoding : 'utf8' } ) ;
//console.debug('installation');
}
isSuccessful = getAutorestVersion ( ) ;
} catch ( err ) {
isSuccessful = false ;
console . log ( ` An error occurred while installing autorest via npm: \n ${ util . inspect ( err , { depth : null } )}. ` ) ;
}
return isSuccessful ;
}
2017-08-26 04:53:43 +03:00
function codegen ( projectObj , index ) {
2017-09-28 02:32:53 +03:00
let versionSuccessfullyFound = true ;
2017-08-26 04:53:43 +03:00
let usingAutoRestVersion = defaultAutoRestVersion ;
function checkAutorestVersion ( actualProj ) {
if ( actualProj . autoRestVersion ) {
usingAutoRestVersion = actualProj . autoRestVersion ;
}
if ( index === 0 ) {
versionSuccessfullyFound = getAutorestVersion ( usingAutoRestVersion ) ;
if ( ! versionSuccessfullyFound ) {
process . exit ( 1 ) ;
}
}
2017-03-18 21:43:33 +03:00
}
2017-08-26 04:53:43 +03:00
function iterateProject ( proj , specRoot , usingAutoRestVersion ) {
2018-03-22 20:21:42 +03:00
for ( const key in proj ) {
2017-08-26 04:53:43 +03:00
if ( proj [ key ] [ 'packageName' ] ) {
if ( ! versionSuccessfullyFound ) {
checkAutorestVersion ( proj [ key ] , index ) ;
}
generateProject ( proj [ key ] , specRoot , usingAutoRestVersion ) ;
} else {
iterateProject ( proj [ key ] , specRoot , usingAutoRestVersion ) ;
}
2017-03-18 21:43:33 +03:00
}
}
2017-08-26 04:53:43 +03:00
return iterateProject ( projectObj , specRoot , usingAutoRestVersion ) ;
2016-03-01 05:32:11 +03:00
}
2016-02-28 06:30:26 +03:00
2017-03-18 21:43:33 +03:00
gulp . task ( 'default' , function ( ) {
2018-03-22 20:21:42 +03:00
console . log ( 'Usage: gulp codegen [--spec-root <swagger specs root>] [--use <autorest.nodejs root> [--project <project name>]\n' ) ;
console . log ( '--spec-root' ) ;
console . log ( '\tRoot location of Swagger API specs, default value is \"https://raw.githubusercontent.com/Azure/azure-rest-api-specs/master/specification\"' ) ;
console . log ( '--use' ) ;
console . log ( '\tRoot location of autorest.nodejs repository. If this is not specified, then the latest install generator for NodeJS will be used.' ) ;
console . log ( '--project\n\tProject to regenerate, default is all. List of available project names:' ) ;
2017-03-18 21:43:33 +03:00
Object . keys ( mappings ) . forEach ( function ( i ) {
console . log ( '\t' + i . magenta ) ;
2016-02-28 06:30:26 +03:00
} ) ;
} ) ;
2017-04-03 21:00:32 +03:00
//This task is used to generate libraries based on the mappings specified above.
2017-03-18 21:43:33 +03:00
gulp . task ( 'codegen' , function ( cb ) {
2017-06-30 21:17:03 +03:00
if ( project === undefined ) {
let arr = Object . keys ( mappings ) ;
for ( let i = 0 ; i < arr . length ; i ++ ) {
2017-09-28 02:32:53 +03:00
codegen ( mappings [ arr [ i ] ] , i ) ;
2016-02-28 06:30:26 +03:00
}
2017-03-18 21:43:33 +03:00
} else {
2017-06-30 21:17:03 +03:00
if ( mappings [ project ] === undefined ) {
console . error ( 'Invalid project name "' + project + '"!' ) ;
process . exit ( 1 ) ;
}
2017-08-26 04:53:43 +03:00
codegen ( mappings [ project ] , null ) ;
2017-03-18 21:43:33 +03:00
}
2017-04-02 00:47:59 +03:00
} ) ;
2017-04-03 21:00:32 +03:00
//This task validates that the entry in "main" and "types" in package.json points to a file that exists on the disk.
// for best results run on mac or linux. Windows is case insenstive for file paths. Hence it will not catch those issues.
//If not tested this will cause "module not found" errors for customers when they try to use the package.
2017-04-02 00:47:59 +03:00
gulp . task ( 'validate-each-packagejson' , ( cb ) => {
2017-12-29 03:38:48 +03:00
let packagePaths = glob . sync ( path . join ( _ _dirname , '/lib/services' , '/**/package.json' ) , { ignore : '**/node_modules/**' } ) ;
2017-04-02 00:47:59 +03:00
packagePaths . forEach ( ( packagePath ) => {
const package = require ( packagePath ) ;
//console.log(package);
2017-12-29 03:38:48 +03:00
if ( ! package . name . startsWith ( 'azure-asm-' ) ) {
2017-04-02 00:47:59 +03:00
console . log ( ` Validating package: ${ package . name } ` ) ;
if ( package . main ) {
let mainPath = path . resolve ( path . dirname ( packagePath ) , package . main ) ;
if ( ! fs . existsSync ( mainPath ) ) console . log ( ` \t > ${ mainPath } does not exist. ` ) ;
} else {
console . log ( ` \t >Could not find "main" entry in package.json for ${ packagePath } . ` ) ;
}
if ( package . types ) {
let typesPath = path . resolve ( path . dirname ( packagePath ) , package . types ) ;
if ( ! fs . existsSync ( typesPath ) ) console . log ( ` \t > ${ typesPath } does not exist. ` ) ;
} else {
console . log ( ` \t >Could not find "types" entry in package.json for ${ packagePath } . ` ) ;
}
}
} ) ;
} ) ;
2017-04-03 21:00:32 +03:00
//This task updates the dependencies in package.json to the relative service libraries inside lib/services directory.
2017-04-02 00:47:59 +03:00
gulp . task ( 'update-deps-rollup' , ( cb ) => {
2017-11-13 01:34:13 +03:00
let packagePaths = glob . sync ( path . join ( _ _dirname , './lib/services' , '/**/package.json' ) ) . filter ( ( packagePath ) => {
2017-09-29 21:41:15 +03:00
return packagePath . match ( regexForExcludedServices ) === null ;
2017-09-29 01:48:38 +03:00
} ) ;
2017-04-02 00:47:59 +03:00
let rollupPackage = require ( './package.json' ) ;
let rollupDependencies = rollupPackage . dependencies ;
rollupDependencies [ 'ms-rest' ] = './runtime/ms-rest' ;
rollupDependencies [ 'ms-rest-azure' ] = './runtime/ms-rest-azure' ;
packagePaths . forEach ( ( packagePath ) => {
const package = require ( packagePath ) ;
//console.log(package);
2018-03-22 20:21:42 +03:00
let packageName = package . name ;
const packageDir = path . dirname ( packagePath ) ;
2017-04-02 00:47:59 +03:00
if ( rollupDependencies [ packageName ] ) {
rollupDependencies [ packageName ] = packageDir ;
} else {
console . log ( ` Could not find ${ packageName } as a dependecy in rollup package.json file.. ` ) ;
2016-02-28 06:30:26 +03:00
}
} ) ;
2017-04-03 21:00:32 +03:00
fs . writeFileSync ( './package.json' , JSON . stringify ( rollupPackage , null , 2 ) , { 'encoding' : 'utf8' } ) ;
} ) ;
//This task ensures that all the exposed createSomeClient() methods, can correctly instantiate clients. By doing this we test,
//that the "main" entry in package.json points to a file at the correct location. We test the signature of the client constructor
//is as expected. As of now HD Isnight is expected to fail as it is still using the Hyak generator. Once it moves to Autorest, it should
2017-09-28 06:01:40 +03:00
//not fail. Before executing this task, execute `gulp update-deps-rollup`, `rm -rf node_modules` and `npm install` so that the changes inside the sdks in lib/services
//are installed inside the node_modules folder.
2017-04-03 21:00:32 +03:00
gulp . task ( 'test-create-rollup' , ( cb ) => {
const azure = require ( './lib/azure' ) ;
2018-03-22 20:21:42 +03:00
const keys = Object . keys ( azure ) . filter ( ( key ) => { return key . startsWith ( 'create' ) && ! key . startsWith ( 'createASM' ) && key . endsWith ( 'Client' ) && key !== 'createSchedulerClient' ; } ) ;
2017-04-03 21:00:32 +03:00
//console.dir(keys);
//console.log(keys.length);
const creds = { signRequest : { } } ;
const subId = '1234556' ;
keys . forEach ( ( key ) => {
console . log ( key ) ;
const Client = azure [ key ] ;
var c ;
try {
if ( key === 'createKeyVaultClient' || key === 'createSubscriptionManagementClient' ||
key === 'createDataLakeAnalyticsJobManagementClient' || key === 'createDataLakeStoreFileSystemManagementClient' ||
key === 'createDataLakeAnalyticsCatalogManagementClient' ) {
c = new Client ( creds ) ;
2017-09-28 06:01:40 +03:00
} else if ( key === 'createServiceFabricClient' ) {
c = new Client ( ) ;
2017-04-03 21:00:32 +03:00
} else {
c = new Client ( creds , subId ) ;
}
//console.dir(Object.keys(c));
} catch ( err ) {
console . dir ( err ) ;
}
} ) ;
2017-04-18 18:18:22 +03:00
} ) ;
2017-08-26 04:53:43 +03:00
// This task updates the codegen_mappings.json file in sync with the azure-rest-api-specs public repo.
gulp . task ( 'sync-mappings-with-repo' , ( cb ) => {
2018-03-16 21:02:55 +03:00
if ( ! specRoot ) {
2018-03-16 23:53:32 +03:00
return cb ( new Error ( 'Please provide --spec-root <Absolute path to the specification folder in your local clone of the azure-rest-api-specs repository.>' ) ) ;
2017-08-26 04:53:43 +03:00
}
2018-03-16 21:02:55 +03:00
const dirs = fs . readdirSync ( specRoot ) . filter ( f => fs . statSync ( ` ${ specRoot } / ${ f } ` ) . isDirectory ( ) ) ;
2017-08-26 04:53:43 +03:00
let newlyAdded = [ ] ;
2017-09-26 01:43:58 +03:00
let originalProjectCount = Object . keys ( mappings ) . length ;
2018-03-20 22:49:27 +03:00
const resourceProvidersToIgnore = [ 'azsadmin' , 'common-types' , 'databricks' , 'intune' , 'timeseriesinsights' ] ;
2018-03-16 23:53:32 +03:00
const resourceProviderDataPlanesToIgnore = [ 'applicationinsights' , 'operationalinsights' ] ;
2018-03-23 23:00:10 +03:00
function createDescriptor ( ) {
return {
'packageVersion' : '1.0.0-preview' ,
'generatePackageJson' : true ,
'generateReadmeMd' : true ,
'generateLicenseTxt' : true
} ;
}
function createManagementDescriptor ( resourceProviderName ) {
const descriptor = createDescriptor ( ) ;
descriptor . packageName = ` azure-arm- ${ resourceProviderName . toLowerCase ( ) } ` ;
descriptor . dir = ` ${ resourceProviderName } Management/lib ` ;
descriptor . source = ` ${ resourceProviderName } /resource-manager/readme.md ` ;
return descriptor ;
}
function createDataplaneDescriptor ( resourceProviderName ) {
const descriptor = createDescriptor ( ) ;
descriptor . packageName = ` azure- ${ resourceProviderName . toLowerCase ( ) } ` ;
descriptor . dir = ` ${ resourceProviderName } /lib ` ;
descriptor . source = ` ${ resourceProviderName } /data-plane/readme.md ` ;
return descriptor ;
}
2017-08-26 04:53:43 +03:00
for ( let rp of dirs ) {
2018-03-16 23:53:32 +03:00
if ( resourceProvidersToIgnore . indexOf ( rp . toLowerCase ( ) ) === - 1 ) {
let rm = ` ${ specRoot } / ${ rp } /resource-manager ` ;
let dp = ` ${ specRoot } / ${ rp } /data-plane ` ;
if ( ! mappings [ rp ] ) {
mappings [ rp ] = { } ;
if ( fs . existsSync ( rm ) ) {
2018-03-23 23:00:10 +03:00
mappings [ rp ] [ 'resource-manager' ] = createManagementDescriptor ( rp ) ;
2018-03-16 23:53:32 +03:00
newlyAdded . push ( ` ${ rp } ['resource-manager'] ` ) ;
console . log ( ` Updating RP: ${ rp } , "resource-manager". ` ) ;
console . dir ( mappings [ rp ] [ 'resource-manager' ] , { depth : null , colors : true } ) ;
2017-08-26 04:53:43 +03:00
}
2018-03-16 23:53:32 +03:00
if ( resourceProviderDataPlanesToIgnore . indexOf ( rp . toLowerCase ( ) ) === - 1 ) {
if ( fs . existsSync ( dp ) ) {
2018-03-23 23:00:10 +03:00
mappings [ rp ] [ 'data-plane' ] = createDataplaneDescriptor ( rp ) ;
2018-03-16 23:53:32 +03:00
newlyAdded . push ( ` ${ rp } ['data-plane'] ` ) ;
console . log ( ` Updating RP: ${ rp } , "data-plane". ` ) ;
console . dir ( mappings [ rp ] [ 'data-plane' ] , { depth : null , colors : true } ) ;
2018-03-16 21:02:55 +03:00
}
2017-08-26 04:53:43 +03:00
}
2018-03-16 23:53:32 +03:00
} else {
if ( fs . existsSync ( rm ) && ! mappings [ rp ] [ 'resource-manager' ] ) {
2018-03-23 23:00:10 +03:00
mappings [ rp ] [ 'resource-manager' ] = createManagementDescriptor ( rp ) ;
2018-03-16 23:53:32 +03:00
newlyAdded . push ( ` ${ rp } ['resource-manager'] ` ) ;
console . log ( ` Updating RP: ${ rp } , "resource-manager". ` ) ;
console . dir ( mappings [ rp ] [ 'resource-manager' ] , { depth : null , colors : true } ) ;
2017-08-26 04:53:43 +03:00
}
2018-03-16 23:53:32 +03:00
if ( resourceProviderDataPlanesToIgnore . indexOf ( rp . toLowerCase ( ) ) === - 1 ) {
if ( fs . existsSync ( dp ) && ! mappings [ rp ] [ 'data-plane' ] ) {
2018-03-23 23:00:10 +03:00
mappings [ rp ] [ 'data-plane' ] = createDataplaneDescriptor ( rp ) ;
2018-03-16 23:53:32 +03:00
newlyAdded . push ( ` ${ rp } ['data-plane'] ` ) ;
console . log ( ` Updating RP: ${ rp } , "data-plane". ` ) ;
console . dir ( mappings [ rp ] [ 'data-plane' ] , { depth : null , colors : true } ) ;
2018-03-16 21:02:55 +03:00
}
2017-08-26 04:53:43 +03:00
}
}
}
}
if ( ! newlyAdded . length ) {
console . log ( '\n\n> Mappings in ./codegen_mappings.json are already in sync...' ) ;
} else {
console . log ( ` \n \n > Basic properties like "packageName", "dir" and "source" have been added to ` +
` the newly added projects " ${ newlyAdded . join ( ) } " in the mappings. \n \n > Please ensure that other properties ` +
` like: "ft", "clientName", etc. are correctly added as deemed necessary. \n \n > If the specs repo had multiple ` +
` specs in data-plane or resource-manager (for example: "datalake-analytics.data-plane" has "catalog" ` +
2018-03-22 20:21:42 +03:00
` and "job" in it), then please update the project mappings yourself. ` ) ;
2017-08-26 04:53:43 +03:00
}
2017-09-26 01:43:58 +03:00
console . log ( ` \n \n >>>>> Total projects in the mappings before sync: ${ originalProjectCount } ` ) ;
console . log ( ` \n >>>>> Total projects in the mappings after sync: ${ Object . keys ( mappings ) . length } ` ) ;
2017-08-26 04:53:43 +03:00
fs . writeFileSync ( './codegen_mappings.json' , JSON . stringify ( mappings , null , 2 ) ) ;
2017-09-28 06:01:40 +03:00
} ) ;
// This task synchronizes the dependencies in package.json to the versions of relative service libraries inside lib/services directory.
// This should be done in the end to ensure that all the package dependencies have the correct version.
gulp . task ( 'sync-deps-rollup' , ( cb ) => {
2017-11-13 01:34:13 +03:00
let packagePaths = glob . sync ( path . join ( _ _dirname , './lib/services' , '/**/package.json' ) ) . filter ( ( packagePath ) => {
2017-09-29 21:41:15 +03:00
return packagePath . match ( regexForExcludedServices ) === null ;
2017-09-28 06:01:40 +03:00
} ) ;
//console.log(packagePaths);
console . log ( ` Total packages found under lib/services: ${ packagePaths . length } ` ) ;
let rollupPackage = require ( './package.json' ) ;
let rollupDependencies = rollupPackage . dependencies ;
rollupDependencies [ 'ms-rest' ] = '^2.2.2' ;
2017-09-29 19:54:18 +03:00
rollupDependencies [ 'ms-rest-azure' ] = '^2.3.4' ;
2017-09-28 06:01:40 +03:00
packagePaths . forEach ( ( packagePath ) => {
const package = require ( packagePath ) ;
//console.log(package);
let packageName = package . name ;
let packageVersion = package . version ;
rollupDependencies [ packageName ] = packageVersion ;
} ) ;
rollupPackage . dependencies = Object . keys ( rollupDependencies ) . sort ( ) . reduce ( ( r , k ) => ( r [ k ] = rollupDependencies [ k ] , r ) , { } ) ;
console . log ( ` Total number of dependencies in the rollup package: ${ Object . keys ( rollupPackage . dependencies ) . length } ` ) ;
fs . writeFileSync ( './package.json' , JSON . stringify ( rollupPackage , null , 2 ) , { 'encoding' : 'utf8' } ) ;
2017-10-05 20:14:07 +03:00
} ) ;
gulp . task ( 'sync-package-service-mapping' , ( cb ) => {
let packageMapping = require ( './package_service_mapping' ) ;
2018-03-22 20:21:42 +03:00
for ( const serviceName in mappings ) {
if ( serviceName ) {
const serviceObj = mappings [ serviceName ] ;
const resourceMgr = serviceObj [ 'resource-manager' ] ;
const Dataplane = serviceObj [ 'data-plane' ] ;
if ( resourceMgr ) {
if ( resourceMgr . packageName ) {
if ( ! packageMapping [ resourceMgr . packageName ] ) {
packageMapping [ resourceMgr . packageName ] = {
category : 'Management' ,
'service_name' : resourceMgr . dir . split ( '/' ) [ 0 ]
} ;
}
} else {
for ( let service in resourceMgr ) {
if ( resourceMgr [ service ] . packageName ) {
if ( ! packageMapping [ resourceMgr [ service ] . packageName ] ) {
packageMapping [ resourceMgr [ service ] . packageName ] = {
'category' : 'Management' ,
'service_name' : resourceMgr [ service ] . dir . split ( '/' ) [ 0 ]
} ;
}
2017-10-05 20:14:07 +03:00
}
}
}
}
2018-03-22 20:21:42 +03:00
if ( Dataplane ) {
if ( Dataplane . packageName ) {
if ( ! packageMapping [ Dataplane . packageName ] ) {
packageMapping [ Dataplane . packageName ] = {
category : 'Client' ,
'service_name' : Dataplane . dir . split ( '/' ) [ 0 ]
} ;
}
} else {
for ( let service in Dataplane ) {
if ( Dataplane [ service ] . packageName ) {
if ( ! packageMapping [ Dataplane [ service ] . packageName ] ) {
packageMapping [ Dataplane [ service ] . packageName ] = {
category : 'Client' ,
'service_name' : Dataplane [ service ] . dir . split ( '/' ) [ 0 ]
} ;
}
2017-10-05 20:14:07 +03:00
}
}
}
}
}
}
packageMapping = Object . keys ( packageMapping ) . sort ( ) . reduce ( ( r , k ) => ( r [ k ] = packageMapping [ k ] , r ) , { } ) ;
fs . writeFileSync ( './package_service_mapping.json' , JSON . stringify ( packageMapping , null , 2 ) , { 'encoding' : 'utf8' } ) ;
2018-03-29 00:08:00 +03:00
} ) ;
2018-03-29 20:24:42 +03:00
gulp . task ( 'sort-codegen-mappings' , ( cb ) =>
{
2018-03-29 20:40:21 +03:00
const codegenMappings = require ( './codegen_mappings.json' ) ;
fs . writeFileSync ( './codegen_mappings.json' , jsonStableStringify ( codegenMappings , { space : ' ' } ) ) ;
} ) ;
2018-03-29 20:24:42 +03:00
2018-03-29 19:51:24 +03:00
function findDirProperties ( codegenMappingObject , packageFolderPaths ) {
if ( codegenMappingObject && typeof codegenMappingObject === 'object' ) {
for ( const propertyName in codegenMappingObject ) {
if ( propertyName ) {
const propertyValue = codegenMappingObject [ propertyName ] ;
if ( propertyValue ) {
if ( propertyName == 'dir' && typeof propertyValue === 'string' ) {
if ( ! packageFolderPaths . includes ( propertyValue ) ) {
packageFolderPaths . push ( propertyValue ) ;
}
}
else if ( propertyValue ) {
findDirProperties ( propertyValue , packageFolderPaths ) ;
}
}
}
}
}
}
2018-03-29 00:08:00 +03:00
gulp . task ( 'publish-packages' , ( cb ) => {
const mappings = require ( './codegen_mappings.json' ) ;
2018-03-29 00:31:13 +03:00
2018-03-29 19:51:24 +03:00
const packageFolderPaths = [ ] ;
findDirProperties ( mappings , packageFolderPaths ) ;
2018-03-29 00:08:00 +03:00
2018-03-29 21:51:15 +03:00
let errorPackages = 0 ;
let upToDatePackages = 0 ;
let publishedPackages = 0 ;
2018-03-29 19:51:24 +03:00
for ( const index in packageFolderPaths ) {
if ( true ) {
const packageFolderPath = ` ./lib/services/ ${ packageFolderPaths [ index ] } ` ;
2018-03-29 20:40:21 +03:00
const packageJsonFilePath = ` ${ packageFolderPath } /package.json ` ;
if ( ! fs . existsSync ( packageJsonFilePath ) ) {
2018-03-29 21:51:15 +03:00
console . log ( ` ERROR: Package folder ${ packageFolderPath } is missing a package.json file. ` ) ;
errorPackages ++ ;
2018-03-29 20:40:21 +03:00
}
else {
const packageJson = require ( packageJsonFilePath ) ;
const packageName = packageJson . name ;
const localPackageVersion = packageJson . version ;
2018-03-29 21:51:15 +03:00
if ( ! localPackageVersion ) {
console . log ( ` ERROR: " ${ packageJsonFilePath } " doesn't have a non-empty version property. ` ) ;
errorPackages ++ ;
}
else {
let npmPackageVersion ;
try {
const npmViewResult = JSON . parse ( execSync ( ` npm view ${ packageName } --json ` , { stdio : [ 'pipe' , 'pipe' , 'ignore' ] } ) ) ;
npmPackageVersion = npmViewResult [ 'dist-tags' ] [ 'latest' ] ;
}
catch ( error ) {
// This happens if the package doesn't exist in NPM.
}
2018-03-29 19:51:24 +03:00
2018-03-29 21:51:15 +03:00
//console.log(`Found package "${packageName}" with local version "${localPackageVersion}" and NPM version "${npmPackageVersion}".`);
if ( localPackageVersion === npmPackageVersion ) {
//console.log(`The NPM package "${packageName}" is up to date.`);
upToDatePackages ++ ;
}
else {
console . log ( ` Publishing package " ${ packageName } " with version " ${ localPackageVersion } "... ` ) ;
publishedPackages ++ ;
}
}
2018-03-29 20:40:21 +03:00
}
2018-03-29 00:08:00 +03:00
}
}
2018-03-29 19:51:24 +03:00
2018-03-29 21:51:15 +03:00
console . log ( ` Error packages: ${ errorPackages } ` ) ;
console . log ( ` Up to date packages: ${ upToDatePackages } ` ) ;
console . log ( ` Published packages: ${ publishedPackages } ` ) ;
2017-08-26 04:53:43 +03:00
} ) ;