rian-project-manager 0.2.0

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 (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +156 -0
  3. package/THIRD_PARTY_NOTICES.txt +673 -0
  4. package/bin/rian.cjs +12 -0
  5. package/cmd/rian/main.go +17 -0
  6. package/dist/binaries/darwin-arm64/rian +0 -0
  7. package/dist/binaries/darwin-x64/rian +0 -0
  8. package/dist/binaries/linux-arm64/rian +0 -0
  9. package/dist/binaries/linux-x64/rian +0 -0
  10. package/dist/binaries/manifest.json +29 -0
  11. package/dist/binaries/win32-arm64/rian.exe +0 -0
  12. package/dist/binaries/win32-x64/rian.exe +0 -0
  13. package/go.mod +28 -0
  14. package/go.sum +44 -0
  15. package/internal/app/app.go +298 -0
  16. package/internal/app/app_test.go +85 -0
  17. package/internal/config/config.go +189 -0
  18. package/internal/config/config_test.go +101 -0
  19. package/internal/detect/detect.go +252 -0
  20. package/internal/detect/detect_test.go +86 -0
  21. package/internal/git/git.go +166 -0
  22. package/internal/git/git_test.go +73 -0
  23. package/internal/git/window_unix.go +7 -0
  24. package/internal/git/window_windows.go +8 -0
  25. package/internal/process/platform_unix.go +19 -0
  26. package/internal/process/platform_windows.go +25 -0
  27. package/internal/process/process.go +172 -0
  28. package/internal/process/process_test.go +137 -0
  29. package/internal/project/project.go +180 -0
  30. package/internal/project/project_test.go +71 -0
  31. package/internal/tools/lookup.go +41 -0
  32. package/internal/tools/platform_unix.go +34 -0
  33. package/internal/tools/platform_windows.go +52 -0
  34. package/internal/tools/platform_windows_test.go +29 -0
  35. package/internal/tools/tools.go +152 -0
  36. package/internal/tools/tools_test.go +56 -0
  37. package/internal/ui/actions.go +259 -0
  38. package/internal/ui/forms.go +156 -0
  39. package/internal/ui/model.go +220 -0
  40. package/internal/ui/styles.go +85 -0
  41. package/internal/ui/ui_test.go +170 -0
  42. package/internal/ui/update.go +470 -0
  43. package/internal/ui/view.go +459 -0
  44. package/lib/launcher.cjs +45 -0
  45. package/lib/platforms.cjs +20 -0
  46. package/package.json +41 -0
  47. package/scripts/build-binaries.cjs +60 -0
  48. package/scripts/check-package.cjs +49 -0
  49. package/scripts/ensure-binary.cjs +11 -0
  50. package/test/npm/launcher.test.cjs +45 -0
  51. package/test/npm/package.test.cjs +26 -0
@@ -0,0 +1,11 @@
1
+ 'use strict';
2
+
3
+ // This only fixes executable permissions. No downloads or builds happen on
4
+ // the user's machine. The launcher also repairs permissions if scripts are off.
5
+ const path = require('node:path');
6
+ const { binaryPath } = require('../lib/launcher.cjs');
7
+
8
+ try { binaryPath(path.resolve(__dirname, '..')); } catch (err) {
9
+ console.error(`rian: ${err.message}`);
10
+ process.exitCode = 1;
11
+ }
@@ -0,0 +1,45 @@
1
+ 'use strict';
2
+
3
+ const test = require('node:test');
4
+ const assert = require('node:assert/strict');
5
+ const fs = require('node:fs');
6
+ const path = require('node:path');
7
+ const os = require('node:os');
8
+ const { EventEmitter } = require('node:events');
9
+ const { targets, targetFor } = require('../../lib/platforms.cjs');
10
+ const { binaryPath, launch } = require('../../lib/launcher.cjs');
11
+
12
+ test('dispatches all six platform/architecture combinations', t => {
13
+ const root = fs.mkdtempSync(path.join(os.tmpdir(), 'rian-launcher-'));
14
+ t.after(() => fs.rmSync(root, { recursive: true, force: true }));
15
+ for (const item of targets) {
16
+ const target = targetFor(item.platform, item.arch);
17
+ const file = path.join(root, 'dist', 'binaries', target.key, target.filename);
18
+ fs.mkdirSync(path.dirname(file), { recursive: true }); fs.writeFileSync(file, 'fixture');
19
+ assert.equal(binaryPath(root, item.platform, item.arch), file);
20
+ }
21
+ assert.throws(() => binaryPath(root, 'freebsd', 'x64'), /does not support/);
22
+ assert.throws(() => binaryPath(root, 'darwin', 'ia32'), /does not support/);
23
+ });
24
+
25
+ test('missing binaries give an actionable install error', () => {
26
+ assert.throws(() => binaryPath(path.join(os.tmpdir(), 'rian-missing-install')), /npm install -g rian-project-manager/);
27
+ });
28
+
29
+ test('preserves arguments, terminal stdio, working directory, and child exit status', () => {
30
+ const root = path.resolve(__dirname, '../..');
31
+ const child = new EventEmitter(); child.exitCode = null; child.signalCode = null;
32
+ const oldCode = process.exitCode;
33
+ const oldHandlerCount = process.listenerCount('SIGTERM');
34
+ let invocation;
35
+ const args = ['add', '/directory with spaces', '--yes'];
36
+ launch(root, args, (file, passed, options) => { invocation = { file, passed, options }; return child; });
37
+ assert.deepEqual(invocation.passed, args);
38
+ assert.equal(invocation.options.stdio, 'inherit');
39
+ assert.equal(invocation.options.shell, false);
40
+ assert.equal(invocation.options.cwd, undefined);
41
+ child.emit('exit', 7, null);
42
+ assert.equal(process.exitCode, 7);
43
+ assert.equal(process.listenerCount('SIGTERM'), oldHandlerCount);
44
+ process.exitCode = oldCode;
45
+ });
@@ -0,0 +1,26 @@
1
+ 'use strict';
2
+
3
+ const test = require('node:test');
4
+ const assert = require('node:assert/strict');
5
+ const path = require('node:path');
6
+ const { spawnSync } = require('node:child_process');
7
+ const { checkPackage } = require('../../scripts/check-package.cjs');
8
+ const pkg = require('../../package.json');
9
+
10
+ test('built package includes verified native executables for every supported platform', () => {
11
+ const manifest = checkPackage();
12
+ assert.equal(manifest.version, pkg.version);
13
+ assert.equal(Object.keys(manifest.targets).length, 6);
14
+ assert.equal(pkg.bin.rian, 'bin/rian.cjs');
15
+ });
16
+
17
+ test('npm launcher runs the native executable and returns errors cleanly', () => {
18
+ const root = path.resolve(__dirname, '../..');
19
+ const launcher = path.join(root, 'bin', 'rian.cjs');
20
+ const version = spawnSync(process.execPath, [launcher, '--version'], { encoding: 'utf8', cwd: path.dirname(root), windowsHide: true });
21
+ assert.equal(version.status, 0, version.stderr);
22
+ assert.equal(version.stdout.trim(), `rian ${pkg.version}`);
23
+ const invalid = spawnSync(process.execPath, [launcher, 'invalid-subcommand'], { encoding: 'utf8', windowsHide: true });
24
+ assert.equal(invalid.status, 1);
25
+ assert.match(invalid.stderr, /unknown command/);
26
+ });