oh-my-space 0.11.3 → 0.11.5
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/build-info.json +1 -1
- package/dist/oms.js +258 -15
- package/package.json +14 -4
package/dist/build-info.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"commit":"
|
|
1
|
+
{"commit":"022ade8884c62e549770e73407066671e8caa50a"}
|
package/dist/oms.js
CHANGED
|
@@ -14014,6 +14014,8 @@ function readJson(path) {
|
|
|
14014
14014
|
}
|
|
14015
14015
|
__name(readJson, "readJson");
|
|
14016
14016
|
function readPackageVersion() {
|
|
14017
|
+
const mocked = testEnv("OMS_TEST_PACKAGE_VERSION");
|
|
14018
|
+
if (mocked !== void 0) return mocked;
|
|
14017
14019
|
const pkg = readJson(join(packageRoot, "package.json"));
|
|
14018
14020
|
return pkg?.version ?? "0.0.0";
|
|
14019
14021
|
}
|
|
@@ -14546,7 +14548,7 @@ function loadForSubmodules() {
|
|
|
14546
14548
|
__name(loadForSubmodules, "loadForSubmodules");
|
|
14547
14549
|
|
|
14548
14550
|
// scripts/lib/status.ts
|
|
14549
|
-
import { existsSync as existsSync5 } from "node:fs";
|
|
14551
|
+
import { existsSync as existsSync5, lstatSync, readdirSync } from "node:fs";
|
|
14550
14552
|
import { relative, resolve as resolve4 } from "node:path";
|
|
14551
14553
|
function pinState(repoRoot, alias) {
|
|
14552
14554
|
const r = runGit(repoRoot, ["submodule", "status", "--", submodulePath(alias)]);
|
|
@@ -14699,6 +14701,55 @@ function partialRemovalTopology(s) {
|
|
|
14699
14701
|
return s.headOid !== null && !s.pathExists !== !s.gitmodulesEntry;
|
|
14700
14702
|
}
|
|
14701
14703
|
__name(partialRemovalTopology, "partialRemovalTopology");
|
|
14704
|
+
function readAliasDirEntries(repoRoot, alias) {
|
|
14705
|
+
const dir = aliasDir(repoRoot, alias);
|
|
14706
|
+
try {
|
|
14707
|
+
if (!lstatSync(dir).isDirectory()) return { exists: true, kind: "file" };
|
|
14708
|
+
return { exists: true, kind: "dir", entries: readdirSync(dir) };
|
|
14709
|
+
} catch (error) {
|
|
14710
|
+
if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT") {
|
|
14711
|
+
return { exists: false };
|
|
14712
|
+
}
|
|
14713
|
+
return { exists: true, kind: "unreadable" };
|
|
14714
|
+
}
|
|
14715
|
+
}
|
|
14716
|
+
__name(readAliasDirEntries, "readAliasDirEntries");
|
|
14717
|
+
function unreadablePathReason(alias) {
|
|
14718
|
+
return `oms/${alias} could not be read (permission or I/O error). Resolve access to it, then retry.`;
|
|
14719
|
+
}
|
|
14720
|
+
__name(unreadablePathReason, "unreadablePathReason");
|
|
14721
|
+
var TOPOLOGY_REASON = {
|
|
14722
|
+
conflict: "the root gitlink is conflicted. Resolve the root repository conflict first.",
|
|
14723
|
+
inProgressOp: /* @__PURE__ */ __name((op) => `the root repository has a ${op} in progress. Resolve, continue, or abort it first.`, "inProgressOp"),
|
|
14724
|
+
occupiedPath: /* @__PURE__ */ __name((alias) => `oms/${alias} is occupied by a non-submodule path. Move or remove it manually, then retry.`, "occupiedPath"),
|
|
14725
|
+
unreadable: /* @__PURE__ */ __name((alias) => unreadablePathReason(alias), "unreadable")
|
|
14726
|
+
};
|
|
14727
|
+
function occupiedByNonSubmodule(repoRoot, alias) {
|
|
14728
|
+
if (isRegisteredSubmodule(repoRoot, submodulePath(alias))) return "clear";
|
|
14729
|
+
const dirState = readAliasDirEntries(repoRoot, alias);
|
|
14730
|
+
if (!dirState.exists) return "clear";
|
|
14731
|
+
if (dirState.kind === "unreadable") return "unreadable";
|
|
14732
|
+
if (dirState.kind === "file") return "occupied";
|
|
14733
|
+
return dirState.entries.length > 0 ? "occupied" : "clear";
|
|
14734
|
+
}
|
|
14735
|
+
__name(occupiedByNonSubmodule, "occupiedByNonSubmodule");
|
|
14736
|
+
function assertRootTopologySafe(repoRoot, alias, checks = ["conflict", "inProgressOp", "occupiedPath"]) {
|
|
14737
|
+
const applies = new Set(checks);
|
|
14738
|
+
if (applies.has("conflict") && gitlinkState(repoRoot, alias).conflict) {
|
|
14739
|
+
return { safe: false, reason: TOPOLOGY_REASON.conflict };
|
|
14740
|
+
}
|
|
14741
|
+
if (applies.has("inProgressOp")) {
|
|
14742
|
+
const op = gitOperationInProgress(repoRoot);
|
|
14743
|
+
if (op) return { safe: false, reason: TOPOLOGY_REASON.inProgressOp(op) };
|
|
14744
|
+
}
|
|
14745
|
+
if (applies.has("occupiedPath")) {
|
|
14746
|
+
const occupied = occupiedByNonSubmodule(repoRoot, alias);
|
|
14747
|
+
if (occupied === "unreadable") return { safe: false, reason: TOPOLOGY_REASON.unreadable(alias) };
|
|
14748
|
+
if (occupied === "occupied") return { safe: false, reason: TOPOLOGY_REASON.occupiedPath(alias) };
|
|
14749
|
+
}
|
|
14750
|
+
return { safe: true };
|
|
14751
|
+
}
|
|
14752
|
+
__name(assertRootTopologySafe, "assertRootTopologySafe");
|
|
14702
14753
|
function rootFollowupHint(alias, s) {
|
|
14703
14754
|
if (s.headOid !== null && s.pathExists && !s.conflict && s.moved) {
|
|
14704
14755
|
return `Run "oms record ${alias}" to record the root pointer update.`;
|
|
@@ -15152,13 +15203,9 @@ async function runRecord(alias) {
|
|
|
15152
15203
|
const selected = resolution.alias;
|
|
15153
15204
|
const path = submodulePath(selected);
|
|
15154
15205
|
const state = gitlinkState(repoRoot, selected);
|
|
15155
|
-
|
|
15156
|
-
|
|
15157
|
-
|
|
15158
|
-
}
|
|
15159
|
-
const rootOp = gitOperationInProgress(repoRoot);
|
|
15160
|
-
if (rootOp) {
|
|
15161
|
-
R2.error(`Root repository has a ${rootOp} in progress. Resolve, continue, or abort it before recording.`);
|
|
15206
|
+
const safety = assertRootTopologySafe(repoRoot, selected, ["conflict", "inProgressOp"]);
|
|
15207
|
+
if (!safety.safe) {
|
|
15208
|
+
R2.error(`${selected}: ${safety.reason}`);
|
|
15162
15209
|
return 1;
|
|
15163
15210
|
}
|
|
15164
15211
|
if (currentBranch(repoRoot) === null) {
|
|
@@ -15764,7 +15811,7 @@ async function runInit(options) {
|
|
|
15764
15811
|
__name(runInit, "runInit");
|
|
15765
15812
|
|
|
15766
15813
|
// scripts/lib/repo-ops.ts
|
|
15767
|
-
import { existsSync as existsSync8, readdirSync, rmSync as rmSync2, rmdirSync, writeFileSync as writeFileSync4 } from "node:fs";
|
|
15814
|
+
import { existsSync as existsSync8, readFileSync as readFileSync4, readdirSync as readdirSync2, rmSync as rmSync2, rmdirSync, writeFileSync as writeFileSync4 } from "node:fs";
|
|
15768
15815
|
import { join as join7 } from "node:path";
|
|
15769
15816
|
function cleanupFailedAdd(repoRoot, alias) {
|
|
15770
15817
|
const path = submodulePath(alias);
|
|
@@ -15782,12 +15829,160 @@ function cleanupFailedAdd(repoRoot, alias) {
|
|
|
15782
15829
|
}
|
|
15783
15830
|
}
|
|
15784
15831
|
__name(cleanupFailedAdd, "cleanupFailedAdd");
|
|
15832
|
+
function headGitmodulesSection(repoRoot, alias) {
|
|
15833
|
+
const path = submodulePath(alias);
|
|
15834
|
+
const r = runGit(repoRoot, ["show", "HEAD:.gitmodules"]);
|
|
15835
|
+
if (!r.success) return null;
|
|
15836
|
+
const lines = r.stdout.split("\n");
|
|
15837
|
+
const start = lines.findIndex((line) => line.trim() === `[submodule "${path}"]`);
|
|
15838
|
+
if (start === -1) return null;
|
|
15839
|
+
let end = lines.length;
|
|
15840
|
+
for (let i = start + 1; i < lines.length; i++) {
|
|
15841
|
+
if (/^\s*\[submodule ".+"\]\s*$/.test(lines[i])) {
|
|
15842
|
+
end = i;
|
|
15843
|
+
break;
|
|
15844
|
+
}
|
|
15845
|
+
}
|
|
15846
|
+
return `${lines.slice(start, end).join("\n").replace(/\n*$/, "\n")}`;
|
|
15847
|
+
}
|
|
15848
|
+
__name(headGitmodulesSection, "headGitmodulesSection");
|
|
15849
|
+
function headFollowingGitmodulesHeaders(repoRoot, alias) {
|
|
15850
|
+
const path = submodulePath(alias);
|
|
15851
|
+
const r = runGit(repoRoot, ["show", "HEAD:.gitmodules"]);
|
|
15852
|
+
if (!r.success) return [];
|
|
15853
|
+
const lines = r.stdout.split("\n");
|
|
15854
|
+
const start = lines.findIndex((line) => line.trim() === `[submodule "${path}"]`);
|
|
15855
|
+
if (start === -1) return [];
|
|
15856
|
+
const headers = [];
|
|
15857
|
+
for (let i = start + 1; i < lines.length; i++) {
|
|
15858
|
+
const match = lines[i].trim().match(/^\[submodule "(.+)"\]$/);
|
|
15859
|
+
if (match) headers.push(`[submodule "${match[1]}"]`);
|
|
15860
|
+
}
|
|
15861
|
+
return headers;
|
|
15862
|
+
}
|
|
15863
|
+
__name(headFollowingGitmodulesHeaders, "headFollowingGitmodulesHeaders");
|
|
15864
|
+
function currentGitmodulesHasSameAliasSection(repoRoot, alias) {
|
|
15865
|
+
const gitmodules = join7(repoRoot, ".gitmodules");
|
|
15866
|
+
if (!existsSync8(gitmodules)) return false;
|
|
15867
|
+
return readFileSync4(gitmodules, "utf8").split("\n").some((line) => line.trim() === `[submodule "${submodulePath(alias)}"]`);
|
|
15868
|
+
}
|
|
15869
|
+
__name(currentGitmodulesHasSameAliasSection, "currentGitmodulesHasSameAliasSection");
|
|
15870
|
+
function insertGitmodulesSection(repoRoot, alias, section) {
|
|
15871
|
+
const gitmodules = join7(repoRoot, ".gitmodules");
|
|
15872
|
+
const existing = existsSync8(gitmodules) ? readFileSync4(gitmodules, "utf8") : "";
|
|
15873
|
+
const followingHeaders = headFollowingGitmodulesHeaders(repoRoot, alias);
|
|
15874
|
+
const lines = existing.split("\n");
|
|
15875
|
+
for (const followingHeader of followingHeaders) {
|
|
15876
|
+
const insertAt = lines.findIndex((line) => line.trim() === followingHeader);
|
|
15877
|
+
if (insertAt !== -1) {
|
|
15878
|
+
lines.splice(insertAt, 0, ...section.replace(/\n$/, "").split("\n"));
|
|
15879
|
+
writeFileSync4(gitmodules, lines.join("\n"));
|
|
15880
|
+
return;
|
|
15881
|
+
}
|
|
15882
|
+
}
|
|
15883
|
+
const separator = existing.length === 0 || existing.endsWith("\n") ? "" : "\n";
|
|
15884
|
+
writeFileSync4(gitmodules, `${existing}${separator}${section}`);
|
|
15885
|
+
}
|
|
15886
|
+
__name(insertGitmodulesSection, "insertGitmodulesSection");
|
|
15887
|
+
function gitmoduleValue(repoRoot, alias, key) {
|
|
15888
|
+
const r = runGit(repoRoot, ["config", "--file", ".gitmodules", "--get", `submodule.${submodulePath(alias)}.${key}`]);
|
|
15889
|
+
const value = r.stdout.trim();
|
|
15890
|
+
return r.success && value.length > 0 ? value : null;
|
|
15891
|
+
}
|
|
15892
|
+
__name(gitmoduleValue, "gitmoduleValue");
|
|
15893
|
+
function reconcileGitmodulesMetadata(repoRoot, repo) {
|
|
15894
|
+
const path = submodulePath(repo.alias);
|
|
15895
|
+
let changed = false;
|
|
15896
|
+
if (gitmoduleValue(repoRoot, repo.alias, "url") !== repo.remotes.origin) {
|
|
15897
|
+
runGit(repoRoot, ["config", "--file", ".gitmodules", `submodule.${path}.url`, repo.remotes.origin]);
|
|
15898
|
+
changed = true;
|
|
15899
|
+
}
|
|
15900
|
+
const currentBranchValue = gitmoduleValue(repoRoot, repo.alias, "branch");
|
|
15901
|
+
if (repo.branch) {
|
|
15902
|
+
if (currentBranchValue !== repo.branch) {
|
|
15903
|
+
runGit(repoRoot, ["config", "--file", ".gitmodules", `submodule.${path}.branch`, repo.branch]);
|
|
15904
|
+
changed = true;
|
|
15905
|
+
}
|
|
15906
|
+
} else if (currentBranchValue !== null) {
|
|
15907
|
+
runGit(repoRoot, ["config", "--file", ".gitmodules", "--unset", `submodule.${path}.branch`]);
|
|
15908
|
+
changed = true;
|
|
15909
|
+
}
|
|
15910
|
+
return changed;
|
|
15911
|
+
}
|
|
15912
|
+
__name(reconcileGitmodulesMetadata, "reconcileGitmodulesMetadata");
|
|
15913
|
+
function cleanupRestorableAliasDir(repoRoot, alias) {
|
|
15914
|
+
if (submoduleInitialized(repoRoot, alias)) return "ok";
|
|
15915
|
+
const dirState = readAliasDirEntries(repoRoot, alias);
|
|
15916
|
+
if (!dirState.exists) return "ok";
|
|
15917
|
+
if (dirState.kind === "unreadable") return "unreadable";
|
|
15918
|
+
if (dirState.kind === "file") return "occupied";
|
|
15919
|
+
const entries = dirState.entries;
|
|
15920
|
+
if (entries.length > 0 && entries.some((entry) => entry !== ".DS_Store")) return "occupied";
|
|
15921
|
+
try {
|
|
15922
|
+
rmSync2(aliasDir(repoRoot, alias), { recursive: true, force: true });
|
|
15923
|
+
} catch {
|
|
15924
|
+
return "unremovable";
|
|
15925
|
+
}
|
|
15926
|
+
return "ok";
|
|
15927
|
+
}
|
|
15928
|
+
__name(cleanupRestorableAliasDir, "cleanupRestorableAliasDir");
|
|
15929
|
+
function restorePendingRemoval(repo, repoRoot) {
|
|
15930
|
+
const alias = repo.alias;
|
|
15931
|
+
const path = submodulePath(alias);
|
|
15932
|
+
const state = gitlinkState(repoRoot, alias);
|
|
15933
|
+
const shouldRestore = state.headOid !== null && (pendingRemovalTopology(state) || partialRemovalTopology(state));
|
|
15934
|
+
if (!shouldRestore) return { result: "failed", restored: false };
|
|
15935
|
+
const unsafe = /* @__PURE__ */ __name((detail) => {
|
|
15936
|
+
R2.error(`${alias}: cannot restore pending removal safely (${detail}). Resolve or commit the pending removal before syncing.`);
|
|
15937
|
+
return { result: "failed", restored: true };
|
|
15938
|
+
}, "unsafe");
|
|
15939
|
+
if (state.conflict) return unsafe("root gitlink is conflicted");
|
|
15940
|
+
const rootOp = gitOperationInProgress(repoRoot);
|
|
15941
|
+
if (rootOp) return unsafe(`root repository has a ${rootOp} in progress`);
|
|
15942
|
+
if (currentGitmodulesHasSameAliasSection(repoRoot, alias) && !state.gitmodulesEntry) {
|
|
15943
|
+
return unsafe("current .gitmodules has an incomplete same-alias section");
|
|
15944
|
+
}
|
|
15945
|
+
const section = headGitmodulesSection(repoRoot, alias);
|
|
15946
|
+
if (!section) return unsafe(".gitmodules metadata is not recoverable from HEAD");
|
|
15947
|
+
const cleanup = cleanupRestorableAliasDir(repoRoot, alias);
|
|
15948
|
+
if (cleanup === "unreadable") return unsafe(`${path} could not be read (permission or I/O error)`);
|
|
15949
|
+
if (cleanup === "unremovable") return unsafe(`${path} could not be removed (permission or I/O error)`);
|
|
15950
|
+
if (cleanup === "occupied") return unsafe(`${path} is occupied by a non-submodule path`);
|
|
15951
|
+
runGit(repoRoot, ["restore", "--source=HEAD", "--staged", "--", ".gitmodules"]);
|
|
15952
|
+
if (!state.gitmodulesEntry) insertGitmodulesSection(repoRoot, alias, section);
|
|
15953
|
+
const metadataUpdated = reconcileGitmodulesMetadata(repoRoot, repo);
|
|
15954
|
+
const restorePath = runGit(repoRoot, ["restore", "--source=HEAD", "--staged", "--worktree", "--", path], true);
|
|
15955
|
+
if (!restorePath.success) return unsafe(`failed to restore ${path} from HEAD`);
|
|
15956
|
+
runGit(repoRoot, ["submodule", "sync", "--", path]);
|
|
15957
|
+
R2.step(`${alias}: git submodule update --init ${path}`);
|
|
15958
|
+
const upd = runGit(repoRoot, ["submodule", "update", "--init", "--", path], true);
|
|
15959
|
+
if (!upd.success) {
|
|
15960
|
+
R2.error(`${alias}: git submodule update --init failed (exit ${upd.exitCode})`);
|
|
15961
|
+
return { result: "failed", restored: true };
|
|
15962
|
+
}
|
|
15963
|
+
ensureRemotes(repoRoot, alias, repo.remotes);
|
|
15964
|
+
const branch = gitmodulesBranch(repoRoot, alias) ?? repo.branch;
|
|
15965
|
+
if (branch) attachBranch(repoRoot, alias, branch);
|
|
15966
|
+
R2.success(`${alias}: restored pending removal${metadataUpdated ? " and updated .gitmodules metadata" : ""}`);
|
|
15967
|
+
return { result: "added", restored: true };
|
|
15968
|
+
}
|
|
15969
|
+
__name(restorePendingRemoval, "restorePendingRemoval");
|
|
15785
15970
|
function syncRepo(repo, repoRoot) {
|
|
15786
15971
|
const alias = repo.alias;
|
|
15787
15972
|
const path = submodulePath(alias);
|
|
15788
15973
|
const registered = isRegisteredSubmodule(repoRoot, path);
|
|
15974
|
+
const state = gitlinkState(repoRoot, alias);
|
|
15975
|
+
if (!registered && state.headOid !== null) {
|
|
15976
|
+
const restore = restorePendingRemoval(repo, repoRoot);
|
|
15977
|
+
if (restore.restored) return restore.result;
|
|
15978
|
+
}
|
|
15789
15979
|
if (!registered) {
|
|
15790
|
-
|
|
15980
|
+
const dirState = readAliasDirEntries(repoRoot, alias);
|
|
15981
|
+
if (dirState.exists && dirState.kind === "unreadable") {
|
|
15982
|
+
R2.error(`${alias}: ${unreadablePathReason(alias)}`);
|
|
15983
|
+
return "failed";
|
|
15984
|
+
}
|
|
15985
|
+
if (dirState.exists && (dirState.kind === "file" || dirState.entries.length > 0)) {
|
|
15791
15986
|
R2.error(
|
|
15792
15987
|
`${alias}: ${path}/ already exists but is not a registered submodule. Move or remove it manually, then retry.`
|
|
15793
15988
|
);
|
|
@@ -15861,6 +16056,11 @@ function unsyncRepo(repo, repoRoot, force) {
|
|
|
15861
16056
|
const registered = isRegisteredSubmodule(repoRoot, path);
|
|
15862
16057
|
const exists = existsSync8(aliasDir(repoRoot, alias));
|
|
15863
16058
|
if (!registered && !exists) return "nothing-to-remove";
|
|
16059
|
+
const safety = assertRootTopologySafe(repoRoot, alias);
|
|
16060
|
+
if (!safety.safe) {
|
|
16061
|
+
R2.error(`${alias}: ${safety.reason}`);
|
|
16062
|
+
return "failed";
|
|
16063
|
+
}
|
|
15864
16064
|
if (!force && submoduleInitialized(repoRoot, alias) && isDirty(aliasDir(repoRoot, alias))) {
|
|
15865
16065
|
R2.error(
|
|
15866
16066
|
`${alias}: ${path} has uncommitted or untracked changes. Commit, stash, remove them, or pass --force.`
|
|
@@ -15881,7 +16081,7 @@ function unsyncRepo(repo, repoRoot, force) {
|
|
|
15881
16081
|
}
|
|
15882
16082
|
try {
|
|
15883
16083
|
const modulesParent = join7(repoRoot, ".git", "modules", DATA_DIRNAME);
|
|
15884
|
-
if (existsSync8(modulesParent) &&
|
|
16084
|
+
if (existsSync8(modulesParent) && readdirSync2(modulesParent).length === 0) rmdirSync(modulesParent);
|
|
15885
16085
|
} catch {
|
|
15886
16086
|
}
|
|
15887
16087
|
if (existsSync8(aliasDir(repoRoot, alias))) {
|
|
@@ -15889,7 +16089,7 @@ function unsyncRepo(repo, repoRoot, force) {
|
|
|
15889
16089
|
}
|
|
15890
16090
|
try {
|
|
15891
16091
|
const parent = join7(repoRoot, DATA_DIRNAME);
|
|
15892
|
-
if (existsSync8(parent) &&
|
|
16092
|
+
if (existsSync8(parent) && readdirSync2(parent).length === 0) rmdirSync(parent);
|
|
15893
16093
|
} catch {
|
|
15894
16094
|
}
|
|
15895
16095
|
const gitmodules = join7(repoRoot, ".gitmodules");
|
|
@@ -16088,9 +16288,7 @@ async function runUnsync(aliases, options) {
|
|
|
16088
16288
|
if (results.length > 1 || options.all) printSummary(results);
|
|
16089
16289
|
const failed = picked.filter((_, i) => results[i] === "failed").map((r) => r.alias);
|
|
16090
16290
|
if (failed.length > 0) {
|
|
16091
|
-
R2.error(
|
|
16092
|
-
`Not unsynced: ${failed.join(", ")}. The submodule had uncommitted or untracked changes \u2014 commit/stash/remove them, or re-run with --force.`
|
|
16093
|
-
);
|
|
16291
|
+
R2.error(`Not unsynced: ${failed.join(", ")}. See the per-alias error above for each.`);
|
|
16094
16292
|
}
|
|
16095
16293
|
return exitFromResults(results) || topoExit;
|
|
16096
16294
|
}
|
|
@@ -16249,6 +16447,12 @@ function compareVersions(currentVersion, latestVersion) {
|
|
|
16249
16447
|
return import_semver.default.compare(current, latest);
|
|
16250
16448
|
}
|
|
16251
16449
|
__name(compareVersions, "compareVersions");
|
|
16450
|
+
function isPrereleaseVersion(version) {
|
|
16451
|
+
const parsed = import_semver.default.valid(version);
|
|
16452
|
+
if (!parsed) throw new Error(`Installed version is not valid semver: ${version}`);
|
|
16453
|
+
return import_semver.default.prerelease(parsed) !== null;
|
|
16454
|
+
}
|
|
16455
|
+
__name(isPrereleaseVersion, "isPrereleaseVersion");
|
|
16252
16456
|
function printUpdateHeader(currentVersion, latestVersion) {
|
|
16253
16457
|
R2.info(`Current version: ${currentVersion}`);
|
|
16254
16458
|
R2.info(`Latest version: ${latestVersion}`);
|
|
@@ -16266,6 +16470,36 @@ function printGuidance(context) {
|
|
|
16266
16470
|
for (const command of context.guidance) R2.message(` ${command}`);
|
|
16267
16471
|
}
|
|
16268
16472
|
__name(printGuidance, "printGuidance");
|
|
16473
|
+
function channelInstallCommand(manager, tag) {
|
|
16474
|
+
if (manager === "npm") return `npm install -g ${PACKAGE_NAME}@${tag}`;
|
|
16475
|
+
if (manager === "pnpm") return `pnpm add -g ${PACKAGE_NAME}@${tag}`;
|
|
16476
|
+
if (manager === "yarn") return `yarn global add ${PACKAGE_NAME}@${tag}`;
|
|
16477
|
+
return `bun add -g ${PACKAGE_NAME}@${tag}`;
|
|
16478
|
+
}
|
|
16479
|
+
__name(channelInstallCommand, "channelInstallCommand");
|
|
16480
|
+
function prereleaseGuidanceManager(context) {
|
|
16481
|
+
return context.manager ?? context.updateCommand?.executable ?? null;
|
|
16482
|
+
}
|
|
16483
|
+
__name(prereleaseGuidanceManager, "prereleaseGuidanceManager");
|
|
16484
|
+
function printPrereleaseGuidance(context) {
|
|
16485
|
+
const manager = prereleaseGuidanceManager(context);
|
|
16486
|
+
R2.info("Prerelease channel guidance:");
|
|
16487
|
+
if (manager) {
|
|
16488
|
+
R2.message(` Stay on beta manually: ${channelInstallCommand(manager, "beta")}`);
|
|
16489
|
+
R2.message(` Return to stable: ${channelInstallCommand(manager, "latest")}`);
|
|
16490
|
+
return;
|
|
16491
|
+
}
|
|
16492
|
+
for (const fallbackManager of ["npm", "pnpm", "yarn", "bun"]) {
|
|
16493
|
+
R2.message(` ${fallbackManager} beta: ${channelInstallCommand(fallbackManager, "beta")}`);
|
|
16494
|
+
R2.message(` ${fallbackManager} stable: ${channelInstallCommand(fallbackManager, "latest")}`);
|
|
16495
|
+
}
|
|
16496
|
+
}
|
|
16497
|
+
__name(printPrereleaseGuidance, "printPrereleaseGuidance");
|
|
16498
|
+
function printPrereleaseStatus(currentVersion, latestVersion) {
|
|
16499
|
+
R2.info(`Installed prerelease version: ${currentVersion}`);
|
|
16500
|
+
R2.info(`Stable latest version: ${latestVersion}`);
|
|
16501
|
+
}
|
|
16502
|
+
__name(printPrereleaseStatus, "printPrereleaseStatus");
|
|
16269
16503
|
function commandAvailability(command) {
|
|
16270
16504
|
const mocked = testEnv("OMS_TEST_MANAGER_AVAILABLE");
|
|
16271
16505
|
if (mocked !== void 0) return mocked === "1" || mocked === "true";
|
|
@@ -16324,12 +16558,16 @@ async function runUpdate(options) {
|
|
|
16324
16558
|
try {
|
|
16325
16559
|
latestVersion = await fetchLatestPackageVersion();
|
|
16326
16560
|
const comparison = compareVersions(currentVersion, latestVersion);
|
|
16561
|
+
const prerelease2 = isPrereleaseVersion(currentVersion);
|
|
16327
16562
|
printUpdateHeader(currentVersion, latestVersion);
|
|
16563
|
+
if (prerelease2) printPrereleaseStatus(currentVersion, latestVersion);
|
|
16328
16564
|
if (comparison === 0) {
|
|
16565
|
+
if (prerelease2) printPrereleaseGuidance(detectInstallContext());
|
|
16329
16566
|
R2.success("oms is up to date.");
|
|
16330
16567
|
return 0;
|
|
16331
16568
|
}
|
|
16332
16569
|
if (comparison > 0) {
|
|
16570
|
+
if (prerelease2) printPrereleaseGuidance(detectInstallContext());
|
|
16333
16571
|
R2.info("Installed version is newer than the npm registry latest; no downgrade will be performed.");
|
|
16334
16572
|
return 0;
|
|
16335
16573
|
}
|
|
@@ -16340,6 +16578,11 @@ async function runUpdate(options) {
|
|
|
16340
16578
|
R2.warn("Update available.");
|
|
16341
16579
|
const context = detectInstallContext();
|
|
16342
16580
|
printInstallContext(context);
|
|
16581
|
+
const prerelease = isPrereleaseVersion(currentVersion);
|
|
16582
|
+
if (prerelease) {
|
|
16583
|
+
R2.info("Selected update channel: stable latest (oh-my-space@latest).");
|
|
16584
|
+
printPrereleaseGuidance(context);
|
|
16585
|
+
}
|
|
16343
16586
|
if (options.check) {
|
|
16344
16587
|
if (!context.updateCommand) printGuidance(context);
|
|
16345
16588
|
return 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "oh-my-space",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.5",
|
|
4
4
|
"description": "Manage multi-repo workspaces with Git submodules.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://github.com/divlook/oh-my-space",
|
|
@@ -13,9 +13,18 @@
|
|
|
13
13
|
},
|
|
14
14
|
"keywords": [
|
|
15
15
|
"oms",
|
|
16
|
-
"
|
|
16
|
+
"oh-my-space",
|
|
17
17
|
"git",
|
|
18
|
-
"cli"
|
|
18
|
+
"cli",
|
|
19
|
+
"git-submodule",
|
|
20
|
+
"submodule",
|
|
21
|
+
"workspace",
|
|
22
|
+
"multi-repo",
|
|
23
|
+
"monorepo",
|
|
24
|
+
"repository-management",
|
|
25
|
+
"developer-tools",
|
|
26
|
+
"ai",
|
|
27
|
+
"agent"
|
|
19
28
|
],
|
|
20
29
|
"author": {
|
|
21
30
|
"name": "divlook",
|
|
@@ -40,7 +49,8 @@
|
|
|
40
49
|
"prepack": "npm test",
|
|
41
50
|
"changeset": "changeset",
|
|
42
51
|
"version": "changeset version",
|
|
43
|
-
"release": "changeset publish"
|
|
52
|
+
"release": "changeset publish",
|
|
53
|
+
"release:beta": "node scripts/publish-beta.mjs"
|
|
44
54
|
},
|
|
45
55
|
"devDependencies": {
|
|
46
56
|
"@changesets/changelog-github": "^0.7.0",
|