@transitive-sdk/utils-caps 0.3.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +3 -2
  2. package/subScript +110 -62
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@transitive-sdk/utils-caps",
3
- "version": "0.3.0",
3
+ "version": "0.4.1",
4
4
  "description": "Utilities to build and run Transitive capabilities in dev",
5
5
  "homepage": "https://transitiverobotics.com",
6
6
  "repository": {
@@ -29,6 +29,7 @@
29
29
  },
30
30
  "dependencies": {
31
31
  "@transitive-sdk/utils": "^0.17.2",
32
- "esbuild": "^0.28.0"
32
+ "esbuild": "^0.28.0",
33
+ "shelljs": "^0.10.0"
33
34
  }
34
35
  }
package/subScript CHANGED
@@ -1,62 +1,110 @@
1
- #!/bin/bash
2
-
3
- # This file gets updated by @transitive-sdk/utils-caps. Do not modify!
4
-
5
- # Use this script in your wrapper package's script to relay invokation to scripts
6
- # in the correct subproject.
7
-
8
- # Define a mapping from lifecycle events to scripts in sub-project. Note that
9
- # we *don't* want to map preinstall to preinstall, since in the subproject
10
- # preinstall will already be executed when running install. Instead we create
11
- # new script names, preall and postall, that will run before *anything* happens
12
- # in the subproject, and in particular before npm dependencies are installed.
13
- declare -A subscripts
14
- subscripts["preinstall"]="preall"
15
- subscripts["postinstall"]="postall"
16
-
17
- # Known npm command that should be invoked without `run`
18
- declare -A npmCommands
19
- npmCommands["install"]=1
20
- npmCommands["update"]=1
21
- npmCommands["rebuild"]=1
22
-
23
- SUBSCRIPT=${subscripts[$npm_lifecycle_event]:-$npm_lifecycle_event}
24
-
25
- if [[ $TRANSITIVE_IS_ROBOT ]]; then
26
- SUBPROJECT=robot
27
- elif [[ $TRANSITIVE_IS_CLOUD ]]; then
28
- SUBPROJECT=cloud
29
- fi;
30
-
31
- if [[ $SUBPROJECT ]]; then
32
- PREFIX="--prefix $SUBPROJECT"
33
- else
34
- PREFIX=
35
- fi;
36
-
37
- if [[ $SUBSCRIPT == "start" ]]; then
38
- # ensure dependencies are installed
39
- if [[ $SUBPROJECT ]]; then
40
- rm -rf $SUBPROJECT/node_modules/.*-* $SUBPROJECT/node_modules/@*/.*-*
41
- fi;
42
- npm $PREFIX ls || FORCE_COLOR=0 npm $PREFIX update
43
- fi;
44
-
45
- if [[ $SUBPROJECT ]]; then
46
- if [[ ${npmCommands[$npm_lifecycle_event]} ]]; then
47
- echo "Invoking $npm_lifecycle_event in $SUBPROJECT"
48
-
49
- if [[ $npm_command == "ci" ]] && [[ $npm_lifecycle_event == "install" ]]; then
50
- echo "ci: Removing $SUBPROJECT/node_modules"
51
- rm -rf $SUBPROJECT/node_modules
52
- fi;
53
-
54
- FORCE_COLOR=0 npm $PREFIX $npm_lifecycle_event
55
- else
56
- echo "Invoking $SUBSCRIPT in $SUBPROJECT"
57
- npm $PREFIX run --if-present $SUBSCRIPT
58
- fi;
59
- else
60
- echo "Invoking dev:$SUBSCRIPT"
61
- npm run --if-present dev:$SUBSCRIPT
62
- fi;
1
+ #!/usr/bin/env node
2
+
3
+ // This file gets updated by @transitive-sdk/utils-caps. Do not modify!
4
+
5
+ // Use this script in your wrapper package's script to relay invocation to
6
+ // scripts in the correct subproject.
7
+
8
+ const path = require('path');
9
+ const { spawnSync } = require('child_process');
10
+ const sh = require('shelljs');
11
+
12
+ sh.config.silent = false; // let npm's own output through
13
+
14
+ const subProject =
15
+ process.env.TRANSITIVE_IS_ROBOT ? 'robot'
16
+ : (process.env.TRANSITIVE_IS_CLOUD ? 'cloud' : undefined);
17
+
18
+ const npmLifecycleEvent = process.env.npm_lifecycle_event;
19
+
20
+ /* Define a mapping from lifecycle events to scripts in sub-project. Note that
21
+ we *don't* want to map preinstall to preinstall, since in the subproject
22
+ preinstall will already be executed when running install. Instead we create
23
+ new script names, preall and postall, that will run before *anything* happens
24
+ in the subproject, and in particular before npm dependencies are installed. */
25
+ const subscripts = {
26
+ preinstall: 'preall',
27
+ postinstall: 'postall',
28
+ };
29
+
30
+ const subscript = subscripts[npmLifecycleEvent] || npmLifecycleEvent;
31
+
32
+ // folder where robot dependencies are cached between installs/upgrades
33
+ const cacheDir =
34
+ path.join(process.env.npm_config_local_prefix, '.robot_node_modules')
35
+
36
+ // Hooks to run on robot before the respective commands
37
+ const robotHooks = {
38
+ install: () => {
39
+ if (process.env.npm_command === 'ci') {
40
+ console.log(`ci: Removing ${subProject}/node_modules`);
41
+ sh.rm('-rf', path.join(subProject, 'node_modules'));
42
+ }
43
+ },
44
+ start: () => {
45
+ if (!subProject) return;
46
+
47
+ // ensure dependencies are installed before starting
48
+ /* Remove stale .*-* in `node_modules` and `node_modules/@*` */
49
+ sh.rm('-rf', `${subProject}/node_modules/.*-*`);
50
+ sh.rm('-rf', `${subProject}/node_modules/@*/.*-*`);
51
+ npm('ls', {subProject}) == 0 || npm('update', {subProject});
52
+ },
53
+ // --- for caching
54
+ postinstall: () => {
55
+ console.log('Caching node_modules');
56
+ sh.rm('-rf', cacheDir);
57
+ sh.cp('-R', 'robot/node_modules', cacheDir);
58
+ },
59
+ preinstall: () => {
60
+ if (sh.test('-d', cacheDir)) {
61
+ console.log('Restoring cached node_modules');
62
+ sh.rm('-rf', 'robot/node_modules');
63
+ sh.mv(cacheDir, 'robot/node_modules');
64
+ }
65
+ }
66
+ // ---
67
+ }
68
+
69
+ /** Run npm command, in subProject if given */
70
+ const npm = (cmd, {env = {}, subProject = undefined} = {}) => {
71
+ console.log(`Invoking ${cmd} ${subProject ? `in ${subProject}` : ''}`);
72
+
73
+ const args = [];
74
+ subProject && args.push('--prefix', subProject);
75
+
76
+ if (['install', 'update', 'rebuild', 'ls'].includes(cmd)) {
77
+ // It's a known npm command that should be invoked without `run`
78
+ env.FORCE_COLOR = '0'; // force no ascii colors (can lead to crashes in gyp)
79
+ } else {
80
+ args.push('run', '--if-present');
81
+ }
82
+
83
+ args.push(cmd);
84
+
85
+ // sh.exec can't start tmux (not a terminal); using spawn instead
86
+ const result = spawnSync('npm', args,
87
+ { env: {...process.env, ...env},
88
+ stdio: 'inherit'
89
+ });
90
+ return result.status;
91
+ }
92
+
93
+
94
+ // --- main --------------------------------------------------------------
95
+
96
+ let exitCode = 0;
97
+
98
+ if (!subProject) {
99
+ exitCode = npm(`dev:${npmLifecycleEvent}`);
100
+ process.exit(exitCode);
101
+ }
102
+
103
+ // -------------
104
+ // We are calling a command in a sub project (robot or cloud)
105
+
106
+ process.env.TRANSITIVE_IS_ROBOT &&
107
+ robotHooks[npmLifecycleEvent]?.();
108
+
109
+ exitCode = npm(subscript, {subProject});
110
+ process.exit(exitCode);