@gjsify/cli 0.4.28 → 0.4.29
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/dist/cli.gjs.mjs +33 -33
- package/lib/actions/barrels-generate.js +1 -5
- package/lib/actions/build.d.ts +3 -3
- package/lib/actions/build.js +56 -64
- package/lib/bundler-pick.d.ts +3 -3
- package/lib/bundler-pick.js +5 -6
- package/lib/commands/build.js +37 -31
- package/lib/commands/check.js +3 -3
- package/lib/commands/fix.js +33 -23
- package/lib/commands/flatpak/build.js +6 -2
- package/lib/commands/flatpak/check.js +9 -3
- package/lib/commands/flatpak/ci.js +1 -2
- package/lib/commands/flatpak/deps.js +1 -2
- package/lib/commands/flatpak/diff.js +2 -6
- package/lib/commands/flatpak/init.js +19 -19
- package/lib/commands/flatpak/release.js +2 -2
- package/lib/commands/flatpak/scaffold.js +3 -11
- package/lib/commands/flatpak/sync-flathub.js +4 -8
- package/lib/commands/flatpak/utils.js +1 -6
- package/lib/commands/foreach.js +5 -14
- package/lib/commands/format.js +54 -41
- package/lib/commands/gettext.js +2 -10
- package/lib/commands/gresource.js +2 -8
- package/lib/commands/gsettings.js +1 -3
- package/lib/commands/install.js +13 -6
- package/lib/commands/lint.d.ts +1 -1
- package/lib/commands/lint.js +22 -22
- package/lib/commands/pack.js +29 -17
- package/lib/commands/publish.js +17 -18
- package/lib/commands/run.js +2 -6
- package/lib/commands/self-update.js +1 -3
- package/lib/commands/showcase.js +1 -1
- package/lib/commands/system-check.js +8 -11
- package/lib/commands/test.js +12 -8
- package/lib/commands/uninstall.js +1 -3
- package/lib/commands/upgrade.d.ts +1 -1
- package/lib/commands/upgrade.js +109 -120
- package/lib/commands/workspace.js +1 -3
- package/lib/config.js +18 -13
- package/lib/index.js +3 -1
- package/lib/templates/install.mjs.tmpl +20 -14
- package/lib/templates/oxfmtrc.tmpl +54 -0
- package/lib/templates/oxlintrc.json.tmpl +35 -0
- package/lib/types/config-data.d.ts +23 -13
- package/lib/utils/check-system-deps.js +10 -4
- package/lib/utils/detect-native-packages.js +1 -1
- package/lib/utils/dlx-cache.js +2 -7
- package/lib/utils/install-backend-native.d.ts +2 -2
- package/lib/utils/install-backend-native.js +65 -58
- package/lib/utils/install-backend.js +2 -1
- package/lib/utils/install-global.js +1 -3
- package/lib/utils/normalize-bundler-options.js +52 -17
- package/lib/utils/oxc-resolve.d.ts +63 -0
- package/lib/utils/oxc-resolve.js +264 -0
- package/lib/utils/pkg-json-edit.js +1 -6
- package/lib/utils/run-gjs.js +1 -4
- package/lib/utils/run-lifecycle-script.js +3 -7
- package/lib/utils/workspace-root.js +3 -1
- package/package.json +17 -17
- package/lib/templates/biome.json.tmpl +0 -79
- package/lib/utils/biome-resolve.d.ts +0 -47
- package/lib/utils/biome-resolve.js +0 -204
|
@@ -88,12 +88,16 @@ export const flatpakBuildCommand = {
|
|
|
88
88
|
rmSync(buildDir, { recursive: true, force: true });
|
|
89
89
|
await runFlatpakBuilder([...sharedFlags, buildDir, manifest], { verbose: args.verbose });
|
|
90
90
|
if (args.install) {
|
|
91
|
-
await runFlatpakBuilder(['--user', '--install', '--force-clean', buildDir, manifest], {
|
|
91
|
+
await runFlatpakBuilder(['--user', '--install', '--force-clean', buildDir, manifest], {
|
|
92
|
+
verbose: args.verbose,
|
|
93
|
+
});
|
|
92
94
|
}
|
|
93
95
|
if (args.repo) {
|
|
94
96
|
const repoPath = resolve(cwd, args.repo);
|
|
95
97
|
mkdirSync(dirname(repoPath), { recursive: true });
|
|
96
|
-
await runFlatpakBuilder([`--repo=${repoPath}`, '--force-clean', buildDir, manifest], {
|
|
98
|
+
await runFlatpakBuilder([`--repo=${repoPath}`, '--force-clean', buildDir, manifest], {
|
|
99
|
+
verbose: args.verbose,
|
|
100
|
+
});
|
|
97
101
|
}
|
|
98
102
|
if (args.bundle) {
|
|
99
103
|
if (!args.repo) {
|
|
@@ -101,7 +101,9 @@ function resolveAppId(explicit, flatpak, cwd) {
|
|
|
101
101
|
if (looksLikeAppId(pkg.name))
|
|
102
102
|
return pkg.name;
|
|
103
103
|
}
|
|
104
|
-
catch {
|
|
104
|
+
catch {
|
|
105
|
+
/* no pkg.json */
|
|
106
|
+
}
|
|
105
107
|
if (explicit) {
|
|
106
108
|
// strip `.json` extension if present
|
|
107
109
|
return explicit.replace(/\.json$/, '');
|
|
@@ -130,8 +132,12 @@ function runLinter(bin, args, verbose) {
|
|
|
130
132
|
if (!verbose) {
|
|
131
133
|
child.stdout?.setEncoding('utf-8');
|
|
132
134
|
child.stderr?.setEncoding('utf-8');
|
|
133
|
-
child.stdout?.on('data', (c) => {
|
|
134
|
-
|
|
135
|
+
child.stdout?.on('data', (c) => {
|
|
136
|
+
stdout += c;
|
|
137
|
+
});
|
|
138
|
+
child.stderr?.on('data', (c) => {
|
|
139
|
+
stderr += c;
|
|
140
|
+
});
|
|
135
141
|
}
|
|
136
142
|
child.on('error', (err) => {
|
|
137
143
|
const e = err;
|
|
@@ -61,8 +61,7 @@ export const flatpakCiCommand = {
|
|
|
61
61
|
const configData = await cfg.forBuild({}).catch(() => ({}));
|
|
62
62
|
const flatpak = configData.flatpak ?? {};
|
|
63
63
|
const pkg = readPackageJson(cwd);
|
|
64
|
-
const appId = flatpak.appId ??
|
|
65
|
-
(looksLikeAppId(pkg.name) ? pkg.name : undefined);
|
|
64
|
+
const appId = flatpak.appId ?? (looksLikeAppId(pkg.name) ? pkg.name : undefined);
|
|
66
65
|
if (!appId) {
|
|
67
66
|
throw new Error('gjsify flatpak ci: no app id available. Set gjsify.flatpak.appId in package.json ' +
|
|
68
67
|
'or rename the package to a reverse-DNS id.');
|
|
@@ -53,8 +53,7 @@ export const flatpakDepsCommand = {
|
|
|
53
53
|
if (!existsSync(lockfile)) {
|
|
54
54
|
throw new Error(`gjsify flatpak deps: lockfile ${lockfile} not found (use --lockfile to override)`);
|
|
55
55
|
}
|
|
56
|
-
const type = args.type ??
|
|
57
|
-
(lockfile.endsWith('package-lock.json') ? 'npm' : 'yarn');
|
|
56
|
+
const type = args.type ?? (lockfile.endsWith('package-lock.json') ? 'npm' : 'yarn');
|
|
58
57
|
const out = resolve(cwd, args.out ?? 'flatpak-node-sources.json');
|
|
59
58
|
mkdirSync(dirname(out), { recursive: true });
|
|
60
59
|
const cmdArgs = [type, lockfile, '-o', out];
|
|
@@ -62,15 +62,11 @@ export const flatpakDiffCommand = {
|
|
|
62
62
|
const cfg = new Config();
|
|
63
63
|
const configData = await cfg.forBuild({}).catch(() => ({}));
|
|
64
64
|
const flatpak = configData.flatpak ?? {};
|
|
65
|
-
const appId = args.appId ??
|
|
66
|
-
flatpak.appId ??
|
|
67
|
-
readPackageJson(cwd).name;
|
|
65
|
+
const appId = args.appId ?? flatpak.appId ?? readPackageJson(cwd).name;
|
|
68
66
|
if (!appId) {
|
|
69
67
|
throw new Error('[gjsify flatpak diff] no app id available — pass --app-id or set gjsify.flatpak.appId.');
|
|
70
68
|
}
|
|
71
|
-
const flathubRepo = args.flathubRepo ??
|
|
72
|
-
flatpak.flathubRepo ??
|
|
73
|
-
`flathub/${appId}`;
|
|
69
|
+
const flathubRepo = args.flathubRepo ?? flatpak.flathubRepo ?? `flathub/${appId}`;
|
|
74
70
|
const localVersion = args.version ?? (await resolveLatestTag(cwd, args.verbose));
|
|
75
71
|
const remoteSource = await loadFlathubSource({ appId, flathubRepo, against: args.against, verbose: args.verbose }, args.sourceIndex);
|
|
76
72
|
const remoteTag = remoteSource?.tag;
|
|
@@ -16,7 +16,7 @@ import { dirname, resolve } from 'node:path';
|
|
|
16
16
|
import { DEFAULT_CLI_FINISH_ARGS, DEFAULT_GUI_FINISH_ARGS, looksLikeAppId, readPackageJson, resolveRuntime, } from './utils.js';
|
|
17
17
|
import { renderDesktop, renderFlathubJson, renderMetainfoApp, renderMetainfoCli, validateScaffoldInputs, } from './scaffold.js';
|
|
18
18
|
import { Config } from '../../config.js';
|
|
19
|
-
import {
|
|
19
|
+
import { OxcNotFoundError, hasOxcDevDep, runOxfmt } from '../../utils/oxc-resolve.js';
|
|
20
20
|
export const flatpakInitCommand = {
|
|
21
21
|
command: 'init',
|
|
22
22
|
description: 'Generate Flatpak manifest + MetaInfo XML + .desktop + flathub.json from `gjsify.flatpak` config.',
|
|
@@ -88,8 +88,9 @@ export const flatpakInitCommand = {
|
|
|
88
88
|
default: false,
|
|
89
89
|
})
|
|
90
90
|
.option('format', {
|
|
91
|
-
description: 'Run `
|
|
92
|
-
'Default: true. Pass --no-format to skip.'
|
|
91
|
+
description: 'Run `oxfmt --write` on the generated JS/TS files when `oxfmt` is detected in the project. ' +
|
|
92
|
+
'Default: true. Pass --no-format to skip. Note: oxfmt formats JS/TS only — the JSON/XML/.desktop ' +
|
|
93
|
+
'manifests generated here are not reformatted (CSS/JSON formatting was dropped in the oxc migration).',
|
|
93
94
|
type: 'boolean',
|
|
94
95
|
default: true,
|
|
95
96
|
});
|
|
@@ -107,9 +108,7 @@ export const flatpakInitCommand = {
|
|
|
107
108
|
throw new Error('gjsify flatpak init: no app id available. Pass --app-id, set gjsify.flatpak.appId in package.json, ' +
|
|
108
109
|
'or rename the package to a reverse-DNS id like org.example.MyApp.');
|
|
109
110
|
}
|
|
110
|
-
const kind = args.kind ??
|
|
111
|
-
flatpak.kind ??
|
|
112
|
-
(args.cliOnly ? 'cli' : 'app');
|
|
111
|
+
const kind = args.kind ?? flatpak.kind ?? (args.cliOnly ? 'cli' : 'app');
|
|
113
112
|
const { runtime, runtimeId, sdk, runtimeVersion } = resolveRuntime(flatpak, {
|
|
114
113
|
runtime: args.runtime,
|
|
115
114
|
runtimeVersion: args.runtimeVersion,
|
|
@@ -120,8 +119,7 @@ export const flatpakInitCommand = {
|
|
|
120
119
|
const explicitFinishArgs = args.finishArg;
|
|
121
120
|
const finishArgs = explicitFinishArgs !== undefined
|
|
122
121
|
? explicitFinishArgs
|
|
123
|
-
: flatpak.finishArgs ??
|
|
124
|
-
(kind === 'cli' ? DEFAULT_CLI_FINISH_ARGS : DEFAULT_GUI_FINISH_ARGS);
|
|
122
|
+
: (flatpak.finishArgs ?? (kind === 'cli' ? DEFAULT_CLI_FINISH_ARGS : DEFAULT_GUI_FINISH_ARGS));
|
|
125
123
|
const manifest = {
|
|
126
124
|
id: appId,
|
|
127
125
|
runtime: runtimeId,
|
|
@@ -199,20 +197,22 @@ export const flatpakInitCommand = {
|
|
|
199
197
|
const flathubOut = args.flathubJson ?? 'flathub.json';
|
|
200
198
|
trackWrite(writeIfFresh(resolve(cwd, flathubOut), renderFlathubJson(kind), args.force ?? false, 'flathub.json'));
|
|
201
199
|
}
|
|
202
|
-
// Optional post-format: when
|
|
203
|
-
//
|
|
204
|
-
//
|
|
205
|
-
// JSON
|
|
206
|
-
//
|
|
207
|
-
//
|
|
208
|
-
|
|
200
|
+
// Optional post-format: when oxfmt is configured in the project, run
|
|
201
|
+
// `oxfmt --write` on any generated JS/TS files. oxfmt formats JS/TS
|
|
202
|
+
// (+TOML) only — the manifest/MetaInfo/.desktop/flathub outputs are
|
|
203
|
+
// JSON/XML/INI and are therefore left untouched (CSS/JSON formatting
|
|
204
|
+
// was dropped in the Biome → oxc migration). In practice flatpak init
|
|
205
|
+
// emits no JS/TS, so this is usually a no-op; it remains as a hook for
|
|
206
|
+
// any future JS/TS scaffold output.
|
|
207
|
+
const jsLikeFiles = writtenFiles.filter((p) => /\.(ts|tsx|mts|cts|js|jsx|mjs|cjs)$/.test(p));
|
|
208
|
+
if (jsLikeFiles.length > 0 && args.format !== false && hasOxcDevDep(cwd)) {
|
|
209
209
|
try {
|
|
210
|
-
await
|
|
210
|
+
await runOxfmt(['--write', ...jsLikeFiles], { cwd });
|
|
211
211
|
}
|
|
212
212
|
catch (err) {
|
|
213
|
-
if (err instanceof
|
|
214
|
-
//
|
|
215
|
-
console.warn(`[gjsify flatpak init] post-format skipped:
|
|
213
|
+
if (err instanceof OxcNotFoundError) {
|
|
214
|
+
// oxfmt configured but binding missing — non-fatal warning.
|
|
215
|
+
console.warn(`[gjsify flatpak init] post-format skipped: oxfmt declared but binding not installed. ` +
|
|
216
216
|
`Run \`gjsify install\` then re-run with --force, or pass --no-format.`);
|
|
217
217
|
}
|
|
218
218
|
else {
|
|
@@ -22,7 +22,7 @@ export const flatpakReleaseCommand = {
|
|
|
22
22
|
command: 'release <version>',
|
|
23
23
|
description: 'Cut a release end-to-end: regenerate Flathub assets, run linters, create + push the git tag, then open the Flathub PR. Each step delegates to the equivalent `gjsify flatpak <sub>` command.',
|
|
24
24
|
builder: (yargs) => {
|
|
25
|
-
return yargs
|
|
25
|
+
return (yargs
|
|
26
26
|
// yargs' built-in `--version` flag would otherwise consume the
|
|
27
27
|
// positional value.
|
|
28
28
|
.version(false)
|
|
@@ -64,7 +64,7 @@ export const flatpakReleaseCommand = {
|
|
|
64
64
|
description: 'Echo every sub-command invocation.',
|
|
65
65
|
type: 'boolean',
|
|
66
66
|
default: false,
|
|
67
|
-
});
|
|
67
|
+
}));
|
|
68
68
|
},
|
|
69
69
|
handler: async (args) => {
|
|
70
70
|
const version = typeof args.version === 'string' ? args.version.trim() : '';
|
|
@@ -75,9 +75,7 @@ export function renderMetainfoCli(inputs) {
|
|
|
75
75
|
export function renderDesktop(inputs) {
|
|
76
76
|
const f = inputs.flatpak;
|
|
77
77
|
const categoriesLine = (f.categories ?? ['Utility']).join(';') + ';';
|
|
78
|
-
const keywordsLine = f.keywords?.length
|
|
79
|
-
? `Keywords=${f.keywords.join(';')};\n`
|
|
80
|
-
: '';
|
|
78
|
+
const keywordsLine = f.keywords?.length ? `Keywords=${f.keywords.join(';')};\n` : '';
|
|
81
79
|
return substitute(loadDesktopTemplate(), {
|
|
82
80
|
NAME: inputs.name,
|
|
83
81
|
SUMMARY: f.summary ?? inputs.name,
|
|
@@ -265,9 +263,7 @@ function renderMetainfo(inputs, kind) {
|
|
|
265
263
|
}
|
|
266
264
|
// ─── Description block renderer ──────────────────────────────────────────
|
|
267
265
|
function renderDescriptionBlocks(description, indent) {
|
|
268
|
-
const blocks = typeof description === 'string'
|
|
269
|
-
? stringToBlocks(description)
|
|
270
|
-
: description;
|
|
266
|
+
const blocks = typeof description === 'string' ? stringToBlocks(description) : description;
|
|
271
267
|
const out = [];
|
|
272
268
|
for (const block of blocks) {
|
|
273
269
|
if ('p' in block) {
|
|
@@ -319,9 +315,5 @@ function substitute(template, tokens) {
|
|
|
319
315
|
return out;
|
|
320
316
|
}
|
|
321
317
|
function escapeXml(value) {
|
|
322
|
-
return value
|
|
323
|
-
.replace(/&/g, '&')
|
|
324
|
-
.replace(/</g, '<')
|
|
325
|
-
.replace(/>/g, '>')
|
|
326
|
-
.replace(/"/g, '"');
|
|
318
|
+
return value.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
|
|
327
319
|
}
|
|
@@ -26,7 +26,7 @@ export const flatpakSyncFlathubCommand = {
|
|
|
26
26
|
command: 'sync-flathub',
|
|
27
27
|
description: 'Update the per-app Flathub tracking-repo manifest to a new git tag + commit. Clones, edits, commits, optionally opens a PR.',
|
|
28
28
|
builder: (yargs) => {
|
|
29
|
-
return yargs
|
|
29
|
+
return (yargs
|
|
30
30
|
// Disable yargs' built-in `--version` (which would otherwise
|
|
31
31
|
// print the package version) so this command's `--version
|
|
32
32
|
// <tag>` flag works.
|
|
@@ -69,22 +69,18 @@ export const flatpakSyncFlathubCommand = {
|
|
|
69
69
|
description: 'Echo every git / gh invocation before running.',
|
|
70
70
|
type: 'boolean',
|
|
71
71
|
default: false,
|
|
72
|
-
});
|
|
72
|
+
}));
|
|
73
73
|
},
|
|
74
74
|
handler: async (args) => {
|
|
75
75
|
const cwd = process.cwd();
|
|
76
76
|
const cfg = new Config();
|
|
77
77
|
const configData = await cfg.forBuild({}).catch(() => ({}));
|
|
78
78
|
const flatpak = configData.flatpak ?? {};
|
|
79
|
-
const appId = args.appId ??
|
|
80
|
-
flatpak.appId ??
|
|
81
|
-
readPackageJson(cwd).name;
|
|
79
|
+
const appId = args.appId ?? flatpak.appId ?? readPackageJson(cwd).name;
|
|
82
80
|
if (!appId) {
|
|
83
81
|
throw new Error('[gjsify flatpak sync-flathub] no app id available — pass --app-id or set gjsify.flatpak.appId.');
|
|
84
82
|
}
|
|
85
|
-
const flathubRepo = args.flathubRepo ??
|
|
86
|
-
flatpak.flathubRepo ??
|
|
87
|
-
`flathub/${appId}`;
|
|
83
|
+
const flathubRepo = args.flathubRepo ?? flatpak.flathubRepo ?? `flathub/${appId}`;
|
|
88
84
|
const version = args.version ?? (await resolveLatestTag(cwd, args.verbose));
|
|
89
85
|
if (!version) {
|
|
90
86
|
throw new Error('[gjsify flatpak sync-flathub] no version resolved — pass --version vX.Y.Z or create a git tag locally.');
|
|
@@ -10,12 +10,7 @@ export const DEFAULT_GNOME_RUNTIME_VERSION = '50';
|
|
|
10
10
|
/** Default Freedesktop-Platform runtime version (LTS-ish). */
|
|
11
11
|
export const DEFAULT_FREEDESKTOP_RUNTIME_VERSION = '24.08';
|
|
12
12
|
/** Permissive GUI defaults for GTK4 + Adwaita apps. */
|
|
13
|
-
export const DEFAULT_GUI_FINISH_ARGS = [
|
|
14
|
-
'--device=dri',
|
|
15
|
-
'--share=ipc',
|
|
16
|
-
'--socket=fallback-x11',
|
|
17
|
-
'--socket=wayland',
|
|
18
|
-
];
|
|
13
|
+
export const DEFAULT_GUI_FINISH_ARGS = ['--device=dri', '--share=ipc', '--socket=fallback-x11', '--socket=wayland'];
|
|
19
14
|
/** Lean defaults for headless CLI tools — no display, no GPU. */
|
|
20
15
|
export const DEFAULT_CLI_FINISH_ARGS = [];
|
|
21
16
|
/** Read package.json from a directory. Throws a helpful error if missing/invalid. */
|
package/lib/commands/foreach.js
CHANGED
|
@@ -38,7 +38,7 @@ export const foreachCommand = {
|
|
|
38
38
|
default: false,
|
|
39
39
|
})
|
|
40
40
|
.option('topological', {
|
|
41
|
-
description:
|
|
41
|
+
description: "Wait for each workspace's deps to finish before starting it (production deps only).",
|
|
42
42
|
type: 'boolean',
|
|
43
43
|
alias: 't',
|
|
44
44
|
default: false,
|
|
@@ -105,8 +105,7 @@ export const foreachCommand = {
|
|
|
105
105
|
// With populate--:true, anything after the literal `--`
|
|
106
106
|
// separator lands in top-level args['--']. yargs DOES NOT
|
|
107
107
|
// attach it to args._ — it's a sibling array.
|
|
108
|
-
const fromDoubleDash = (args['--'] ?? [])
|
|
109
|
-
.filter((v) => typeof v === 'string');
|
|
108
|
+
const fromDoubleDash = (args['--'] ?? []).filter((v) => typeof v === 'string');
|
|
110
109
|
if (fromDoubleDash.length > 0) {
|
|
111
110
|
if (!cmd) {
|
|
112
111
|
cmd = fromDoubleDash[0];
|
|
@@ -206,11 +205,7 @@ async function runTopologicalParallel(workspaces, script, args, concurrency, ver
|
|
|
206
205
|
for (const ws of workspaces) {
|
|
207
206
|
const wsDeps = new Set();
|
|
208
207
|
const m = ws.manifest;
|
|
209
|
-
for (const block of [
|
|
210
|
-
m.dependencies,
|
|
211
|
-
includeDev ? m.devDependencies : undefined,
|
|
212
|
-
m.optionalDependencies,
|
|
213
|
-
]) {
|
|
208
|
+
for (const block of [m.dependencies, includeDev ? m.devDependencies : undefined, m.optionalDependencies]) {
|
|
214
209
|
if (!block)
|
|
215
210
|
continue;
|
|
216
211
|
for (const [name, spec] of Object.entries(block)) {
|
|
@@ -284,9 +279,7 @@ async function runOne(ws, script, args, prefixOutput, verbose, exec) {
|
|
|
284
279
|
// when nothing is detectable; the script-runner (D.5) will replace
|
|
285
280
|
// this once `gjsify run` ships.
|
|
286
281
|
const runner = detectPackageManager();
|
|
287
|
-
const argv = runner === 'gjsify'
|
|
288
|
-
? ['run', script, ...args]
|
|
289
|
-
: ['run', script, ...(args.length > 0 ? ['--', ...args] : [])];
|
|
282
|
+
const argv = runner === 'gjsify' ? ['run', script, ...args] : ['run', script, ...(args.length > 0 ? ['--', ...args] : [])];
|
|
290
283
|
if (verbose) {
|
|
291
284
|
console.error(`[${ws.name}] $ ${runner} ${argv.join(' ')}`);
|
|
292
285
|
}
|
|
@@ -307,9 +300,7 @@ function spawnPrefixed(cmd, args, cwd, prefix) {
|
|
|
307
300
|
// Default FORCE_COLOR=1 unless the user explicitly opted out, so tools
|
|
308
301
|
// that key on `process.stdout.isTTY` (chalk, picocolors, …) still emit
|
|
309
302
|
// ANSI colors when run under gjsify foreach. Mirrors yarn / npm.
|
|
310
|
-
const colorEnv = process.env.FORCE_COLOR !== undefined || process.env.NO_COLOR !== undefined
|
|
311
|
-
? {}
|
|
312
|
-
: { FORCE_COLOR: '1' };
|
|
303
|
+
const colorEnv = process.env.FORCE_COLOR !== undefined || process.env.NO_COLOR !== undefined ? {} : { FORCE_COLOR: '1' };
|
|
313
304
|
return new Promise((resolve, reject) => {
|
|
314
305
|
const child = spawn(cmd, args, {
|
|
315
306
|
cwd,
|
package/lib/commands/format.js
CHANGED
|
@@ -1,19 +1,25 @@
|
|
|
1
|
-
// `gjsify format` — wraps
|
|
1
|
+
// `gjsify format` — wraps oxfmt.
|
|
2
2
|
//
|
|
3
|
-
// Resolves
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
3
|
+
// Resolves oxfmt's Node launcher from node_modules
|
|
4
|
+
// (`node_modules/oxfmt/bin/oxfmt` → `dist/cli.js`) and spawns it with the
|
|
5
|
+
// current Node executable. oxfmt is a napi-rs hybrid CLI; the launcher carries
|
|
6
|
+
// the per-platform `@oxfmt/binding-<target>` native code as an
|
|
7
|
+
// optionalDependency, keeping the Node-free runtime promise for the bundled
|
|
8
|
+
// CLI intact (the formatter runs in dev/CI, not in shipped GJS apps).
|
|
7
9
|
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
//
|
|
10
|
+
// oxfmt formats JS/TS (+TOML) only. CSS/JSON formatting that the old Biome
|
|
11
|
+
// toolchain handled is intentionally DROPPED in the oxc migration — no other
|
|
12
|
+
// formatter is wired up for those file types.
|
|
13
|
+
//
|
|
14
|
+
// `--init` writes recommended `.oxlintrc.json` + `.oxfmtrc.json` templates
|
|
15
|
+
// tuned for GJS/GNOME projects (4-space, single-quote, printWidth 120,
|
|
16
|
+
// trailing-comma all, semicolons always, arrow parens always).
|
|
11
17
|
import { existsSync, writeFileSync } from 'node:fs';
|
|
12
18
|
import { resolve } from 'node:path';
|
|
13
|
-
import {
|
|
19
|
+
import { OxcNotFoundError, findOxfmtConfig, loadOxfmtTemplate, loadOxlintTemplate, printOxcNotFound, runOxfmt, } from '../utils/oxc-resolve.js';
|
|
14
20
|
export const formatCommand = {
|
|
15
21
|
command: 'format [paths..]',
|
|
16
|
-
description: 'Format source files via
|
|
22
|
+
description: 'Format JS/TS source files via oxfmt (CSS/JSON formatting is not supported).',
|
|
17
23
|
builder: (yargs) => {
|
|
18
24
|
return yargs
|
|
19
25
|
.positional('paths', {
|
|
@@ -22,7 +28,7 @@ export const formatCommand = {
|
|
|
22
28
|
array: true,
|
|
23
29
|
})
|
|
24
30
|
.option('write', {
|
|
25
|
-
description: 'Modify files in place (default:
|
|
31
|
+
description: 'Modify files in place (default: report drift without writing).',
|
|
26
32
|
type: 'boolean',
|
|
27
33
|
default: false,
|
|
28
34
|
})
|
|
@@ -32,22 +38,22 @@ export const formatCommand = {
|
|
|
32
38
|
default: false,
|
|
33
39
|
})
|
|
34
40
|
.option('config-path', {
|
|
35
|
-
description: 'Path to
|
|
41
|
+
description: 'Path to an .oxfmtrc.json. Default: walks up from cwd to find one.',
|
|
36
42
|
type: 'string',
|
|
37
43
|
normalize: true,
|
|
38
44
|
})
|
|
39
45
|
.option('init', {
|
|
40
|
-
description: 'Write
|
|
46
|
+
description: 'Write recommended .oxlintrc.json + .oxfmtrc.json into cwd (skips existing files unless --force).',
|
|
41
47
|
type: 'boolean',
|
|
42
48
|
default: false,
|
|
43
49
|
})
|
|
44
50
|
.option('force', {
|
|
45
|
-
description: 'Overwrite
|
|
51
|
+
description: 'Overwrite existing .oxlintrc.json / .oxfmtrc.json with --init.',
|
|
46
52
|
type: 'boolean',
|
|
47
53
|
default: false,
|
|
48
54
|
})
|
|
49
55
|
.option('verbose', {
|
|
50
|
-
description: 'Echo the resolved
|
|
56
|
+
description: 'Echo the resolved oxfmt launcher + args before spawning.',
|
|
51
57
|
type: 'boolean',
|
|
52
58
|
default: false,
|
|
53
59
|
});
|
|
@@ -55,29 +61,33 @@ export const formatCommand = {
|
|
|
55
61
|
handler: async (args) => {
|
|
56
62
|
const cwd = process.cwd();
|
|
57
63
|
if (args.init) {
|
|
58
|
-
|
|
64
|
+
handleInit({ cwd, force: args.force ?? false });
|
|
59
65
|
return;
|
|
60
66
|
}
|
|
61
|
-
const paths = args.paths?.length
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
67
|
+
const paths = args.paths?.length ? args.paths : ['.'];
|
|
68
|
+
const oxfmtArgs = [];
|
|
69
|
+
if (args.check) {
|
|
70
|
+
oxfmtArgs.push('--check');
|
|
71
|
+
}
|
|
72
|
+
else if (args.write) {
|
|
73
|
+
oxfmtArgs.push('--write');
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
// No flag: report drift without modifying files. oxfmt's bare
|
|
77
|
+
// default is `--write`, so be explicit with `--list-different`.
|
|
78
|
+
oxfmtArgs.push('--list-different');
|
|
79
|
+
}
|
|
80
|
+
const configPath = args.configPath ?? findOxfmtConfig(cwd) ?? undefined;
|
|
71
81
|
if (configPath)
|
|
72
|
-
|
|
73
|
-
|
|
82
|
+
oxfmtArgs.push('--config', resolve(configPath));
|
|
83
|
+
oxfmtArgs.push(...paths);
|
|
74
84
|
try {
|
|
75
|
-
const code = await
|
|
85
|
+
const code = await runOxfmt(oxfmtArgs, { cwd, verbose: args.verbose });
|
|
76
86
|
process.exitCode = code;
|
|
77
87
|
}
|
|
78
88
|
catch (err) {
|
|
79
|
-
if (err instanceof
|
|
80
|
-
|
|
89
|
+
if (err instanceof OxcNotFoundError) {
|
|
90
|
+
printOxcNotFound(err);
|
|
81
91
|
process.exitCode = 1;
|
|
82
92
|
return;
|
|
83
93
|
}
|
|
@@ -85,14 +95,17 @@ export const formatCommand = {
|
|
|
85
95
|
}
|
|
86
96
|
},
|
|
87
97
|
};
|
|
88
|
-
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
+
function handleInit({ cwd, force }) {
|
|
99
|
+
const writeOne = (name, contents) => {
|
|
100
|
+
const target = resolve(cwd, name);
|
|
101
|
+
if (existsSync(target) && !force) {
|
|
102
|
+
console.log(`[gjsify format] ${name} exists at ${target} — pass --force to overwrite.`);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
writeFileSync(target, contents, 'utf-8');
|
|
106
|
+
console.log(`[gjsify format] wrote ${target}`);
|
|
107
|
+
};
|
|
108
|
+
writeOne('.oxlintrc.json', loadOxlintTemplate());
|
|
109
|
+
writeOne('.oxfmtrc.json', loadOxfmtTemplate());
|
|
110
|
+
console.log('[gjsify format] Run `gjsify format --write .` to apply the formatter to the project.');
|
|
98
111
|
}
|
package/lib/commands/gettext.js
CHANGED
|
@@ -28,13 +28,7 @@ async function fileExists(path) {
|
|
|
28
28
|
async function compileBulkXml(opts) {
|
|
29
29
|
const outputFile = join(opts.outDir, opts.filename);
|
|
30
30
|
await ensureDir(opts.outDir);
|
|
31
|
-
const args = [
|
|
32
|
-
`--output-file=${outputFile}`,
|
|
33
|
-
'--xml',
|
|
34
|
-
`--template=${opts.template}`,
|
|
35
|
-
'-d',
|
|
36
|
-
opts.poDir,
|
|
37
|
-
];
|
|
31
|
+
const args = [`--output-file=${outputFile}`, '--xml', `--template=${opts.template}`, '-d', opts.poDir];
|
|
38
32
|
if (opts.verbose) {
|
|
39
33
|
console.log(`[gjsify gettext] msgfmt ${args.join(' ')}`);
|
|
40
34
|
}
|
|
@@ -55,9 +49,7 @@ async function compilePerLanguage(opts) {
|
|
|
55
49
|
}
|
|
56
50
|
for (const lang of languages) {
|
|
57
51
|
const poFile = join(opts.poDir, `${lang}.po`);
|
|
58
|
-
const langDir = opts.format === 'mo'
|
|
59
|
-
? join(opts.outDir, lang, 'LC_MESSAGES')
|
|
60
|
-
: join(opts.outDir, lang);
|
|
52
|
+
const langDir = opts.format === 'mo' ? join(opts.outDir, lang, 'LC_MESSAGES') : join(opts.outDir, lang);
|
|
61
53
|
await ensureDir(langDir);
|
|
62
54
|
const outputFile = join(langDir, opts.filename);
|
|
63
55
|
// msgfmt produces the binary .mo format by default — there is no
|
|
@@ -43,14 +43,8 @@ export const gresourceCommand = {
|
|
|
43
43
|
handler: async (args) => {
|
|
44
44
|
const xmlPath = resolve(args.xml);
|
|
45
45
|
const target = args.target ? resolve(args.target) : defaultTargetFor(xmlPath);
|
|
46
|
-
const sourcedir = args.sourcedir
|
|
47
|
-
|
|
48
|
-
: dirname(xmlPath);
|
|
49
|
-
const cmdArgs = [
|
|
50
|
-
`--sourcedir=${sourcedir}`,
|
|
51
|
-
`--target=${target}`,
|
|
52
|
-
xmlPath,
|
|
53
|
-
];
|
|
46
|
+
const sourcedir = args.sourcedir ? resolve(args.sourcedir) : dirname(xmlPath);
|
|
47
|
+
const cmdArgs = [`--sourcedir=${sourcedir}`, `--target=${target}`, xmlPath];
|
|
54
48
|
if (args.verbose) {
|
|
55
49
|
console.log(`[gjsify gresource] glib-compile-resources ${cmdArgs.join(' ')}`);
|
|
56
50
|
}
|
|
@@ -33,9 +33,7 @@ export const gsettingsCommand = {
|
|
|
33
33
|
},
|
|
34
34
|
handler: async (args) => {
|
|
35
35
|
const schemadir = resolve(args.schemadir);
|
|
36
|
-
const targetdir = args.targetdir
|
|
37
|
-
? resolve(args.targetdir)
|
|
38
|
-
: schemadir;
|
|
36
|
+
const targetdir = args.targetdir ? resolve(args.targetdir) : schemadir;
|
|
39
37
|
const cmdArgs = [];
|
|
40
38
|
if (args.strict)
|
|
41
39
|
cmdArgs.push('--strict');
|
package/lib/commands/install.js
CHANGED
|
@@ -22,10 +22,10 @@ import { chmodSync, existsSync, lstatSync, mkdirSync, readFileSync, rmSync, syml
|
|
|
22
22
|
import { dirname, join, relative } from 'node:path';
|
|
23
23
|
import { spawn } from 'node:child_process';
|
|
24
24
|
import { discoverWorkspaces } from '@gjsify/workspace';
|
|
25
|
-
import { buildInstallCommand, detectPackageManager, runMinimalChecks
|
|
25
|
+
import { buildInstallCommand, detectPackageManager, runMinimalChecks } from '../utils/check-system-deps.js';
|
|
26
26
|
import { detectNativePackages } from '../utils/detect-native-packages.js';
|
|
27
27
|
import { installPackages } from '../utils/install-backend.js';
|
|
28
|
-
import { binDirOnPath, defaultGlobalLayout, linkGlobalBins, specToPackageName
|
|
28
|
+
import { binDirOnPath, defaultGlobalLayout, linkGlobalBins, specToPackageName } from '../utils/install-global.js';
|
|
29
29
|
import { addDependencyEntry, defaultRangeFromVersion, parseSpec, projectSpecsFromPackageJson, readPackageJson, writePackageJson, } from '../utils/pkg-json-edit.js';
|
|
30
30
|
export const installCommand = {
|
|
31
31
|
command: 'install [packages..]',
|
|
@@ -320,7 +320,8 @@ async function workspaceInstall(cwd, args) {
|
|
|
320
320
|
try {
|
|
321
321
|
rmSync(linkPath, { recursive: true, force: true });
|
|
322
322
|
}
|
|
323
|
-
catch {
|
|
323
|
+
catch {
|
|
324
|
+
/* unexpected — Gio failure on a path we just lstat'd to
|
|
324
325
|
decide we wanted to remove. The subsequent symlinkSync
|
|
325
326
|
will surface the real reason if there is one. */
|
|
326
327
|
}
|
|
@@ -367,7 +368,9 @@ async function workspaceInstall(cwd, args) {
|
|
|
367
368
|
lstatSync(linkPath);
|
|
368
369
|
existsHere = true;
|
|
369
370
|
}
|
|
370
|
-
catch {
|
|
371
|
+
catch {
|
|
372
|
+
/* ENOENT */
|
|
373
|
+
}
|
|
371
374
|
if (existsHere)
|
|
372
375
|
continue;
|
|
373
376
|
mkdirSync(dirname(linkPath), { recursive: true });
|
|
@@ -419,8 +422,12 @@ async function workspaceInstall(cwd, args) {
|
|
|
419
422
|
try {
|
|
420
423
|
rmSync(linkPath, { force: true });
|
|
421
424
|
}
|
|
422
|
-
catch {
|
|
423
|
-
|
|
425
|
+
catch {
|
|
426
|
+
/* fine */
|
|
427
|
+
}
|
|
428
|
+
writeFileSync(linkPath, buildBinShim(ws.location, nodeTarget, gjsTarget, nativePrebuildDirs), {
|
|
429
|
+
mode: 0o755,
|
|
430
|
+
});
|
|
424
431
|
chmodSync(linkPath, 0o755);
|
|
425
432
|
wsBinsCreated++;
|
|
426
433
|
}
|