@atom-js-org/cli 0.5.3-alpha.1 → 0.5.3-alpha.2

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.
package/README.md CHANGED
@@ -8,9 +8,9 @@ atom run build
8
8
  atom build windows
9
9
  atom build macos
10
10
  atom build linux
11
- atom build all
11
+ atom build current --local
12
12
  ```
13
13
 
14
- `atom.config.json` controls artifact names, Windows EXE/NSIS branding, macOS app/DMG metadata and Linux AppImage/DEB/RPM output. New projects include default PNG and ICO assets that can be replaced directly.
14
+ `atom.config.json` controls artifact names, Windows EXE/NSIS branding, macOS app/DMG metadata and Linux AppImage/DEB/RPM output. New projects include default PNG and ICO assets that can be replaced directly. Builds are local-first and do not require GitHub Actions; run the target build on the matching operating system.
15
15
 
16
16
  Project: https://github.com/Atom-js-org/atom
package/bin/atom.cjs CHANGED
@@ -25,10 +25,10 @@ program
25
25
  program
26
26
  .command('build')
27
27
  .description('Build an AtomJS project')
28
- .argument('<target>', 'windows, macos, linux, or all')
28
+ .argument('<target>', 'current, windows, macos, linux, or all')
29
29
  .option('-p, --project <path>', 'project directory', process.cwd())
30
- .option('--local', 'never use the remote build workflow')
31
- .option('--remote', 'always use the remote build workflow')
30
+ .option('--local', 'build on this machine (default; kept for compatibility)')
31
+ .option('--remote', 'deprecated: remote GitHub Actions builds are disabled')
32
32
  .option('--skip-install', 'reuse staged node_modules when possible')
33
33
  .action(async (target, options) => buildCommand(target, options));
34
34
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atom-js-org/cli",
3
- "version": "0.5.3-alpha.1",
3
+ "version": "0.5.3-alpha.2",
4
4
  "description": "CLI for running and building AtomJS desktop applications.",
5
5
  "bin": {
6
6
  "atom": "bin/atom.cjs"
package/src/build.cjs CHANGED
@@ -21,17 +21,33 @@ const { resolveElectronCompatibilityRoot } = require('./electron-compat.cjs');
21
21
  const cliPackageVersion = require('../package.json').version;
22
22
 
23
23
  async function buildCommand(targetInput, options = {}) {
24
- const target = validateTarget(targetInput);
24
+ const requestedTarget = validateTarget(targetInput);
25
25
  const project = loadProject(options.project);
26
26
  const host = hostTarget();
27
+ const target = requestedTarget === 'current' ? host : requestedTarget;
27
28
 
28
- if (options.local && (target === 'all' || target !== host)) {
29
- throw new Error(`A local ${host} machine cannot produce a complete '${target}' release. Remove --local to use GitHub Actions.`);
29
+ if (options.remote) {
30
+ throw new Error([
31
+ 'Remote GitHub Actions builds are disabled.',
32
+ 'Build locally on the matching operating system instead:',
33
+ ' Windows: atom build windows --local',
34
+ ' macOS: atom build macos --local',
35
+ ' Linux: atom build linux --local'
36
+ ].join('\n'));
37
+ }
38
+
39
+ if (target === 'all') {
40
+ throw new Error([
41
+ "'atom build all' cannot safely cross-build native WebView applications.",
42
+ 'Run the matching local build command once on each operating system.'
43
+ ].join('\n'));
30
44
  }
31
45
 
32
- const needsRemote = options.remote || target === 'all' || target !== host;
33
- if (needsRemote) return remoteBuild(project, target);
34
- return localBuild(project, host, options);
46
+ if (target !== host) {
47
+ throw new Error(`Local target mismatch: this machine is ${host}, but '${target}' was requested. Build that target on a ${target} machine.`);
48
+ }
49
+
50
+ return localBuild(project, target, options);
35
51
  }
36
52
 
37
53
  async function localBuild(project, target, options = {}) {
@@ -61,8 +77,8 @@ async function localBuild(project, target, options = {}) {
61
77
  await vendorFramework(stagedApp, project, target);
62
78
  await installProductionDependencies(stagedApp, options.skipInstall, target);
63
79
 
64
- console.log('Embedding application code and production dependencies into the executable...');
65
- await createApplicationPayload(stagedApp, payloadPath);
80
+ console.log('Embedding application code, assets and production dependencies into the executable...');
81
+ const payloadSummary = await createApplicationPayload(stagedApp, payloadPath);
66
82
 
67
83
  const executableName = target === 'windows' ? `${productName}.exe` : productName;
68
84
  const executablePath = path.join(unpacked, executableName);
@@ -108,6 +124,15 @@ async function localBuild(project, target, options = {}) {
108
124
  outputs = await packageLinux({ project, buildRoot, unpacked, executableName, productName });
109
125
  }
110
126
 
127
+ const inventoryPath = path.join(buildRoot, 'packed-files.json');
128
+ await fs.promises.writeFile(inventoryPath, JSON.stringify({
129
+ format: 1,
130
+ fileCount: payloadSummary.fileCount,
131
+ sourceBytes: payloadSummary.sourceBytes,
132
+ compressedBytes: payloadSummary.compressedBytes,
133
+ files: payloadSummary.paths
134
+ }, null, 2));
135
+
111
136
  const manifest = {
112
137
  atomjsVersion: cliPackageVersion,
113
138
  target,
@@ -116,6 +141,12 @@ async function localBuild(project, target, options = {}) {
116
141
  createdAt: new Date().toISOString(),
117
142
  run: path.relative(buildRoot, runPath),
118
143
  unpacked: path.relative(buildRoot, unpackedPath),
144
+ payload: {
145
+ fileCount: payloadSummary.fileCount,
146
+ sourceBytes: payloadSummary.sourceBytes,
147
+ compressedBytes: payloadSummary.compressedBytes,
148
+ inventory: path.basename(inventoryPath)
149
+ },
119
150
  outputs: outputs.map((file) => path.relative(buildRoot, file))
120
151
  };
121
152
  await fs.promises.writeFile(path.join(buildRoot, 'manifest.json'), JSON.stringify(manifest, null, 2));
@@ -251,12 +282,15 @@ async function installProductionDependencies(appDir, skipInstall, target) {
251
282
 
252
283
  async function createApplicationPayload(appDir, outputPath) {
253
284
  const files = [];
285
+ let sourceBytes = 0;
254
286
 
255
287
  async function addFile(source, relative, stat) {
288
+ const data = await fs.promises.readFile(source);
289
+ sourceBytes += data.length;
256
290
  files.push({
257
291
  path: relative.split(path.sep).join('/'),
258
292
  mode: stat.mode & 0o777,
259
- data: (await fs.promises.readFile(source)).toString('base64')
293
+ data: data.toString('base64')
260
294
  });
261
295
  }
262
296
 
@@ -300,6 +334,12 @@ async function createApplicationPayload(appDir, outputPath) {
300
334
  const payload = Buffer.from(JSON.stringify({ format: 1, files }));
301
335
  const compressed = require('node:zlib').gzipSync(payload, { level: 9 });
302
336
  await fs.promises.writeFile(outputPath, compressed);
337
+ return {
338
+ fileCount: files.length,
339
+ sourceBytes,
340
+ compressedBytes: compressed.length,
341
+ paths: files.map((entry) => entry.path)
342
+ };
303
343
  }
304
344
 
305
345
  async function createSeaLauncher({ executablePath, appDir, target, productName, appId, project = null, payloadPath = null }) {
@@ -955,6 +995,8 @@ async function packageMacOS({ project, buildRoot, unpacked, executableName, prod
955
995
  <key>CFBundleName</key><string>${xml(bundleName)}</string>
956
996
  <key>CFBundleDisplayName</key><string>${xml(productName)}</string>
957
997
  <key>CFBundlePackageType</key><string>APPL</string>
998
+ <key>LSUIElement</key><true/>
999
+ <key>LSMultipleInstancesProhibited</key><true/>
958
1000
  <key>CFBundleShortVersionString</key><string>${xml(version)}</string>
959
1001
  <key>CFBundleVersion</key><string>${xml(bundleVersion)}</string>
960
1002
  <key>LSMinimumSystemVersion</key><string>${xml(config.minimumSystemVersion)}</string>
package/src/init.cjs CHANGED
@@ -17,7 +17,6 @@ async function initCommand(directory, options = {}) {
17
17
  const productName = humanize(packageName);
18
18
 
19
19
  await fse.ensureDir(path.join(root, 'src'));
20
- await fse.ensureDir(path.join(root, '.github', 'workflows'));
21
20
 
22
21
  await fs.promises.writeFile(path.join(root, 'package.json'), JSON.stringify({
23
22
  name: packageName,
@@ -26,8 +25,8 @@ async function initCommand(directory, options = {}) {
26
25
  main: 'src/main.js',
27
26
  scripts: {
28
27
  dev: 'atom run dev',
29
- build: 'atom build all',
30
- 'build:current': `atom build ${hostTarget()}`,
28
+ build: 'atom build current --local',
29
+ 'build:current': 'atom build current --local',
31
30
  start: 'atom run build'
32
31
  },
33
32
  dependencies: {
@@ -81,9 +80,6 @@ async function initCommand(directory, options = {}) {
81
80
  deb: true,
82
81
  rpm: true
83
82
  }
84
- },
85
- github: {
86
- workflow: 'atom-build.yml'
87
83
  }
88
84
  }, null, 2));
89
85
 
@@ -95,7 +91,6 @@ async function initCommand(directory, options = {}) {
95
91
  await fs.promises.writeFile(path.join(root, 'src', 'index.html'), htmlTemplate(productName));
96
92
  await fs.promises.writeFile(path.join(root, 'src', 'renderer.js'), rendererTemplate());
97
93
  await fs.promises.writeFile(path.join(root, '.gitignore'), 'node_modules/\nbuild/\n.atom/\n');
98
- await fs.promises.writeFile(path.join(root, '.github', 'workflows', 'atom-build.yml'), workflowTemplate());
99
94
 
100
95
  console.log(`Created AtomJS project in ${root}`);
101
96
  console.log('Next: npm install && npm run dev');
package/src/utils.cjs CHANGED
@@ -4,7 +4,7 @@ const fs = require('node:fs');
4
4
  const path = require('node:path');
5
5
  const { spawn, spawnSync } = require('node:child_process');
6
6
 
7
- const TARGETS = new Set(['windows', 'macos', 'linux', 'all']);
7
+ const TARGETS = new Set(['current', 'windows', 'macos', 'linux', 'all']);
8
8
 
9
9
  function hostTarget() {
10
10
  if (process.platform === 'win32') return 'windows';
@@ -169,7 +169,7 @@ function commandExists(command, args = ['--version']) {
169
169
  function validateTarget(target) {
170
170
  const normalized = String(target).toLowerCase();
171
171
  if (!TARGETS.has(normalized)) {
172
- throw new Error(`Unknown build target '${target}'. Use windows, macos, linux, or all.`);
172
+ throw new Error(`Unknown build target '${target}'. Use current, windows, macos, linux, or all.`);
173
173
  }
174
174
  return normalized;
175
175
  }