UNPKG

@sap/cds-dk

Version:

Command line client and development toolkit for the SAP Cloud Application Programming Model

161 lines (133 loc) 5.55 kB
const { join, resolve } = require ('path') const { execSync, spawnSync } = require('child_process') module.exports = Object.assign(list_versions, { flags: [ '--info', '--markdown', '--all', '--npm-list', '--npm-tree', '--no-colors'], shortcuts: [ '-i', '-m','-a', '-ls', '-ll' ], info, help: ` # SYNOPSIS *cds version* <options> *cds -v* <option> Prints the versions of all @sap/cds packages in your package dependencies. # OPTIONS *-i | --info* Prints version information in a tabular markdown format, which you can embed into your bug reports. *-a | --all* Also lists sub-packages and optional dependencies. *-ls | --npm-list* <pattern> *-ll | --npm-tree* <pattern> Prints an npm ls tree filtered to the specified pattern. (default: '@sap/cds') `}) const MISSING = '-- missing --' function list_versions(args, options) { const {colors} = require('../lib/util/term') if (options['npm-list'] || options['npm-tree']) { let [pattern] = args, re = pattern ? RegExp(pattern) : /@sap\/cd[rs]|@sap\/eslint-plugin-cds/ let cmd = 'npm ls --depth ' + (options['npm-tree'] ? 11 : 0) console.log (cmd,'| grep', re.source) return require('child_process').exec(cmd, (e,stdout)=>{ // if (e) console.error(e) const replacement = (!colors ? '$1 $2$3$4' : '\x1b[91m$1 \x1b[32m$2\x1b[0m\x1b[2m$3\x1b[32m$4\x1b[0m'); for (let line of stdout.split(/\n/)) if (line.match(re)) console.log( line.replace(/(@sap[^@]*)@([\S]+)( -> [\S]+)?(deduped)?/,replacement) ) }) } const versions = info (options) process.stdout.isTTY && console.log() if (options.markdown || options.info) { _markdown (versions) } else { const mark = !colors ? s => s : require('../lib/util/term').info for (let each of Object.keys(versions)) console.log(`${mark(each)}: ${versions[each]}`) } process.stdout.isTTY && console.log() } function info({ root:cwd=process.cwd() }) { const cds = require('../lib') const env = cds.env.for('cds', cwd) env.cli ??= {}; env.cli.version ??= {} const javaInfo = !env.cli.version.skipjava && env['project-nature'] === 'java' if (javaInfo && process.stderr.isTTY) { console.error('\x1b[2m'+'This takes a while. Collecting Java versions...', '\x1b[0m') } const npmRoot = execSync('npm root -g').toString().trim() let versions = { ..._versions_from(_pkg_path('@sap/cds-dk', npmRoot), '@sap/cds-dk (global)'), // linked in cap/dev or installed globally ..._versions_from(_pkg_path('@sap/cds-dk', cwd)), // local dk, important for Java projects ..._versions_from(_pkg_path('@sap/cds', __dirname)), // @sap/cds from here ..._versions_from(_pkg_path('@sap/cds', cds.home)), // ... or local @sap/cds ..._versions_from(_pkg_path('@cap-js/db-service', cwd)), // only required transitively ..._versions_from(cwd), // ... more from local app dependencies '@sap/cds-compiler': cds.compiler.version(), 'Node.js': process.version, 'home': cds.home, // effective cds home } // sort Node entries versions = Object.keys(versions).sort().reduce((all, key) => { all[key] = versions[key]; return all }, {}) if (javaInfo) { Object.assign(versions, capJavaVersion(cwd)) } return versions } function _versions_from(pkg_path, pkg_label) { let pkg; try { pkg = require(join(pkg_path, 'package.json')) } catch { return {} } let versions = {} if (pkg.name) versions[pkg_label || pkg.name] = pkg.version const deps = { ...pkg.dependencies, ...pkg.devDependencies } for (let dep in deps) { if (!dep.match(/@sap\/.*cds.*/) && !dep.startsWith('@cap-js/')) continue try { const dep_path = require.resolve(join(dep, 'package.json'), {paths:[pkg_path]}) const dep_pkg = require(dep_path) versions[dep_pkg.name] = dep_pkg.version } catch (e) { if (e.code !== 'MODULE_NOT_FOUND') console.error(e) } } return versions } function _markdown (versions) { const pkg = { name:'', repository:'', version:'' }; try { Object.assign (pkg, require (resolve('package.json'))) } catch (e) {/* ignored */} const repo = pkg.repository.url || pkg.repository || 'https://github.com/<your/repo>' const valLength = Math.max(repo.length, versions.home.length) console.log ('|', $(pkg.name, repo), '|') console.log ('|', $('----------------------', '-'.repeat(valLength)), '|') Object.keys(versions) .filter(mod => mod != pkg.name) .sort() .forEach(id => console.log ('|', $(id, versions[id]), '|')) function $ (key, val=MISSING) { return ( key + ' '.repeat(22)).slice(0,22) +' | '+ (val + ' '.repeat(valLength)).slice(0,valLength) } } function _pkg_path(id, ...paths) { try { const pk_path = require.resolve(join(id, 'package.json'), { paths }) return resolve(pk_path, '..') } catch (e) { if (e.code !== 'MODULE_NOT_FOUND') throw e } } function capJavaVersion(cwd) { const cmd = 'mvn com.sap.cds:cds-maven-plugin:version -B -Dcds.version.excludeCds -Dcds.version.json' let out = '' try { out = spawnSync(cmd, {cwd, shell: true}).stdout.toString().trim() } catch (e) { /* ignored */ } const match = out.match(/===\n(.*)\n===/ms) if (match?.[1]) { const res = {} Object.entries(JSON.parse(match[1])).forEach(([k,v]) => { const entries = Object.entries(v) res[k] = entries.map(([k,v]) => (k === 'version' || k === 'name') ? v : `${k}: ${v}`).join(', ') }) return res } return { 'CAP Java SDK': MISSING } }