From 931fbeb4356c11f9ab75dc83ebabd25863f5bc7e Mon Sep 17 00:00:00 2001 From: Wayne Parrott <5588978+wayneparrott@users.noreply.github.com> Date: Thu, 15 Apr 2021 17:07:40 -0700 Subject: [PATCH] add --no-init & --rclnodejs-version cli flags (#14) * add --no-init & --rclnodejs-version cli flags * improved ros version specific tests * set 775 permission on run_ros_version.sh * Updated docs to with new create-package cli flags. --- package-creation-tool/README.md | 10 +- package-creation-tool/lib/package_creator.js | 18 ++-- .../verb/create_nodejs_pkg.py | 33 +++--- package.json | 5 +- test/run_ros_version.bat | 2 + test/run_ros_version.sh | 3 + test/test-create-package-cmd.js | 100 +++++++++++++++++- 7 files changed, 145 insertions(+), 26 deletions(-) create mode 100644 test/run_ros_version.bat create mode 100755 test/run_ros_version.sh diff --git a/package-creation-tool/README.md b/package-creation-tool/README.md index 5ead194..a94e0af 100644 --- a/package-creation-tool/README.md +++ b/package-creation-tool/README.md @@ -20,6 +20,7 @@ Alternatively using npx: npx rclnodejs-cli create-package npx rclnodejs-cli create-package --typescript ``` +Be aware that when using `npx` to run `rclnodejs-cli`, this package includes a dependency on the rclnodejs package which has a lengthy install postinstall step. Thus if you frequently use `rclnodejs-cli` you may benefit from more responsiveness by installing this package globally. View the `create-package` options: ``` @@ -34,7 +35,7 @@ or | | | (__| | | | | (_) | (_| | __/| \__ \ |_| \___|_|_| |_|\___/ \__,_|\___|/ |___/ |__/ -Usage: rclnodejs-cli create-package [options...] +Usage: rclnodejs create-package [options...] Create a ROS2 package for Nodejs development. @@ -42,10 +43,11 @@ Options: --description The description given in the package.xml --destination-directory Directory where to create the package directory --license The license attached to this package - --maintainer-email email address of the maintainer of this package - --maintainer-name name of the maintainer of this package - --typescript Configure as a TypeScript Node.js project + --maintainer-email Email address of the maintainer of this package + --maintainer-name Name of the maintainer of this package --no-init Do not run "npm init" + --rclnodejs-version The version of rclnodejs to use + --typescript Configure as a TypeScript Node.js project --dependencies list of ROS dependencies -h, --help display help for command ``` diff --git a/package-creation-tool/lib/package_creator.js b/package-creation-tool/lib/package_creator.js index 92c1092..ac320b8 100644 --- a/package-creation-tool/lib/package_creator.js +++ b/package-creation-tool/lib/package_creator.js @@ -8,14 +8,14 @@ class PkgCreator { createPkgCmd .usage(' [options...]') .description('Create a ROS2 package for Nodejs development.') - // .option('--rclnodejs-version ', 'The version of rclnodejs to use') .option('--description ', 'The description given in the package.xml') .option('--destination-directory ', 'Directory where to create the package directory') .option('--license ', 'The license attached to this package') - .option('--maintainer-email ', 'email address of the maintainer of this package') - .option('--maintainer-name ', 'name of the maintainer of this package') - .option('--typescript', 'Configure as a TypeScript Node.js project') + .option('--maintainer-email ', 'Email address of the maintainer of this package') + .option('--maintainer-name ', 'Name of the maintainer of this package') .option('--no-init', 'Do not run "npm init"') + .option('--rclnodejs-version ', 'The version of rclnodejs to use') + .option('--typescript', 'Configure as a TypeScript Node.js project') .option('--dependencies ', 'list of ROS dependencies') .action((packageName, options) => { this.createPackage(packageName, options); @@ -35,9 +35,9 @@ class PkgCreator { let cmd = path.join(__dirname, '..', 'scripts', script); cmd += ` ${packageName}`; - // if (options.rclnodejsVersion) { - // cmd += ` --rclnodejs-version "${options.rclnodejsVersion}"`; - // } + if (options.rclnodejsVersion) { + cmd += ` --rclnodejs-version "${options.rclnodejsVersion}"`; + } if (options.description) { cmd += ` --description "${options.description}"`; @@ -59,6 +59,10 @@ class PkgCreator { cmd += ` --maintainer-name "${options.maintainerName}"`; } + if (options.noInit) { + cmd += ' --no-init'; + } + if (options.typescript) { cmd += ' --typescript'; } diff --git a/package-creation-tool/rclnodejs_pkg_creation_tool/verb/create_nodejs_pkg.py b/package-creation-tool/rclnodejs_pkg_creation_tool/verb/create_nodejs_pkg.py index aa790e8..6342fbe 100644 --- a/package-creation-tool/rclnodejs_pkg_creation_tool/verb/create_nodejs_pkg.py +++ b/package-creation-tool/rclnodejs_pkg_creation_tool/verb/create_nodejs_pkg.py @@ -42,10 +42,6 @@ def add_arguments(self, parser, cli_name): parser.add_argument( 'package_name', help='The package name') - # parser.add_argument( - # '--rclnodejs-version', - # default='latest', - # help='The version of the rclnodejs client library to include') parser.add_argument( '--description', default='TODO: Package description', @@ -65,19 +61,27 @@ def add_arguments(self, parser, cli_name): help='list of dependencies') parser.add_argument( '--maintainer-email', - help='email address of the maintainer of this package'), + help='Email address of the maintainer of this package'), parser.add_argument( '--maintainer-name', default=getpass.getuser(), - help='name of the maintainer of this package'), + help='Name of the maintainer of this package'), parser.add_argument( - '--template_location', + '--no-init', + action='store_true', + default=False, + help='Do not run \'npm init\' on newly created package') + parser.add_argument( + '--template-location', help='The path to templates directory') parser.add_argument( '--typescript', action='store_true', default=False, help='Configure as a TypeScript Node.js project') + parser.add_argument( + '--rclnodejs-version', + help='Version of rclnodejs client library to use, x.y.z format') def main(self, *, args): # run 'ros2 pkg create ' @@ -169,8 +173,9 @@ def main(self, *, args): os.path.join(template_dir_path, 'CMakeLists.install.em'), os.path.join(cwd, CMAKELISTS_FILENAME)) - # install all node.js dependencies in package.json - _run_npm_install() + if not args.no_init: + # install all node.js dependencies in package.json + _run_npm_install(args) print('Node.js setup complete.') return SUCCESS_RETURN @@ -264,8 +269,8 @@ def _expand_template(template_file, data, output_file): with open(output_file, 'w') as h: h.write(content) -def _run_npm_install(): - npm = shutil.which('npm'); +def _run_npm_install(args): + npm = shutil.which('npm') if not npm: npm = shutil.which('yarn') if not npm: @@ -279,5 +284,9 @@ def _run_npm_install(): print(f' Running \'{os.path.basename(npm)} install\' command.') subprocess.run([npm, 'install']) - return subprocess.run([npm, 'install', 'rclnodejs']) + rclnodejs_pkg = f"rclnodejs{'@' + args.rclnodejs_version if args.rclnodejs_version else ''}" + return subprocess.run([npm, 'install', rclnodejs_pkg]) + + + diff --git a/package.json b/package.json index fe49cee..a552807 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rclnodejs-cli", - "version": "0.1.1", + "version": "0.1.2", "description": "Commandline tools for the ROS2 rclnodejs client library", "main": "index.js", "bin": "./index.js", @@ -8,7 +8,8 @@ "test": "test" }, "scripts": { - "postinstall": "colcon build --base-paths package-creation-tool && node scripts/set_script_permissions.js", + "postinstall": "npm run build-package-creation-tool && node scripts/set_script_permissions.js", + "build-package-creation-tool": "colcon build --base-paths package-creation-tool", "test": "mocha", "lint": "eslint --max-warnings=0 --ext js index.js src message-generator-tool package-creation-tool test" }, diff --git a/test/run_ros_version.bat b/test/run_ros_version.bat new file mode 100644 index 0000000..96e7669 --- /dev/null +++ b/test/run_ros_version.bat @@ -0,0 +1,2 @@ +echo off +install\local_setup.bat && echo on && echo %ROS_DISTRO% \ No newline at end of file diff --git a/test/run_ros_version.sh b/test/run_ros_version.sh new file mode 100755 index 0000000..e3ead34 --- /dev/null +++ b/test/run_ros_version.sh @@ -0,0 +1,3 @@ +#!/bin/bash +source install/local_setup.sh && \ +echo $ROS_DISTRO diff --git a/test/test-create-package-cmd.js b/test/test-create-package-cmd.js index 3fc5270..f12efd8 100644 --- a/test/test-create-package-cmd.js +++ b/test/test-create-package-cmd.js @@ -17,7 +17,7 @@ function rmdir(dir) { } } -function verifyPackage(pkgPath, typescript) { +function verifyPackage(pkgPath, typescript = false, noInit = false, rclnodejsVersion = undefined) { assert.ok(fs.existsSync(pkgPath)); assert.ok(fs.existsSync(path.join(pkgPath, 'package.xml'))); assert.ok(fs.existsSync(path.join(pkgPath, 'package.json'))); @@ -29,12 +29,52 @@ function verifyPackage(pkgPath, typescript) { } else { assert.ok(fs.existsSync(path.join(pkgPath, 'src', 'index.js'))); } + + const nodeModulesDirExists = fs.existsSync(path.join(pkgPath, 'node_modules')); + assert.ok(noInit ? !nodeModulesDirExists : nodeModulesDirExists); + + if (!noInit && rclnodejsVersion) { + // load package.json and find the version number of the rclnodejs dependency + // eslint-disable-next-line global-require, import/no-dynamic-require + const pkg = require(path.join(pkgPath, 'package.json')); + assert.ok( + pkg + && pkg.dependencies + && pkg.dependencies.rclnodejs + && pkg.dependencies.rclnodejs.endsWith(rclnodejsVersion), + ); + } } function scriptExt() { return process.platform === 'win32' ? '.bat' : '.sh'; } +function rosDistroName() { + const cwd = process.cwd(); + + let script = `run_ros_version${scriptExt()}`; + script = path.join(cwd, 'test', script); + const stdoutBuf = childProcess.execSync(script, [], { + cwd, + }); + + const lines = stdoutBuf.toString().match(/[^\r\n]+/g); + if (lines && lines.length > 0) { + return lines[lines.length - 1]; + } + + return undefined; +} + +function rclnodejsVersionForRosDistro() { + const distroName = rosDistroName(); + if (distroName === 'foxy') return '0.18.1'; + if (distroName === 'eloquent') return '0.18.1'; + if (distroName === 'dashing') return '0.10.3'; + return undefined; +} + describe('rclnodejs-cli package-creation-tool', function () { this.timeout(0); @@ -101,6 +141,38 @@ describe('rclnodejs-cli package-creation-tool', function () { done(); }); + it('ros2cli-extension create javascript package --rclnodejs-version', (done) => { + const version = rclnodejsVersionForRosDistro(); + if (!version) { + console.warn('Unable to run test \'ros2cli-extension create javascript package --rclnodejs-version\' Could not recognized ROS distro name.'); + done(); + } + + const cwd = process.cwd(); + + let script = `run_ros2cli_pkg_create_nodejs${scriptExt()}`; + script = path.join(cwd, 'test', script); + childProcess.execSync(`${script} ${pkgName} --rclnodejs-version ${version}`); + + const pkgPath = path.join(cwd, pkgName); + verifyPackage(pkgPath, false, false, version); + + done(); + }); + + it('ros2cli-extension create javascript package --no-init', (done) => { + const cwd = process.cwd(); + + let script = `run_ros2cli_pkg_create_nodejs${scriptExt()}`; + script = path.join(cwd, 'test', script); + childProcess.execSync(`${script} ${pkgName} --no-init`); + + const pkgPath = path.join(cwd, pkgName); + verifyPackage(pkgPath, false, true); + + done(); + }); + it('rclnodejs-cli create-package javascript', (done) => { const cli = path.join(__dirname, '..', '..', 'rclnodejs-cli'); childProcess.execSync(`npx ${cli} create-package ${pkgName}`).toString(); @@ -120,4 +192,30 @@ describe('rclnodejs-cli package-creation-tool', function () { done(); }); + + it('rclnodejs-cli create-package javascript --no-init', (done) => { + const cli = path.join(__dirname, '..', '..', 'rclnodejs-cli'); + childProcess.execSync(`npx ${cli} create-package ${pkgName} --no-init`).toString(); + + const pkgPath = path.join(cli, pkgName); + verifyPackage(pkgPath, false, false); + + done(); + }); + + it('rclnodejs-cli create-package javascript --rclnodejs-version', (done) => { + const version = rclnodejsVersionForRosDistro(); + if (!version) { + console.warn('Unable to run test \'rclnodejs-cli create-package javascript --rclnodejs-version\'. Could not recognized ROS distro name.'); + done(); + } + + const cli = path.join(__dirname, '..', '..', 'rclnodejs-cli'); + childProcess.execSync(`npx ${cli} create-package ${pkgName} --rclnodejs-version ${version}`).toString(); + + const pkgPath = path.join(cli, pkgName); + verifyPackage(pkgPath, false, false, version); + + done(); + }); });