oh-my-space 0.7.0 → 0.7.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.
@@ -1 +1 @@
1
- {"commit":"23dd80c9eef2a1ba62b193a9497f564dbe116739"}
1
+ {"commit":"b3b6890088ebe3eb5dd965d2fdd730a60b5a0a01"}
package/dist/oms.js CHANGED
@@ -238,10 +238,10 @@ function submodulePath(alias) {
238
238
  function isGitRepo(repoRoot) {
239
239
  return runGit(repoRoot, ["rev-parse", "--is-inside-work-tree"]).stdout.trim() === "true";
240
240
  }
241
- /** True when .gitmodules registers a submodule at the given path (sources/<alias> or oms/<alias>). */
242
- function isRegisteredSubmodule(repoRoot, sourcePath) {
241
+ /** Every submodule path registered in .gitmodules (empty when the file is absent or registers none). */
242
+ function registeredSubmodulePaths(repoRoot) {
243
243
  if (!existsSync(join(repoRoot, ".gitmodules")))
244
- return false;
244
+ return [];
245
245
  const result = runGit(repoRoot, [
246
246
  "config",
247
247
  "--file",
@@ -250,10 +250,19 @@ function isRegisteredSubmodule(repoRoot, sourcePath) {
250
250
  "^submodule\\..*\\.path$",
251
251
  ]);
252
252
  if (!result.success)
253
- return false;
253
+ return [];
254
254
  return result.stdout
255
255
  .split("\n")
256
- .some((line) => line.trim().split(/\s+/)[1] === sourcePath);
256
+ .map((line) => line.trim().split(/\s+/)[1])
257
+ .filter((p) => Boolean(p));
258
+ }
259
+ /** True when .gitmodules registers a submodule at the given path (sources/<alias> or oms/<alias>). */
260
+ function isRegisteredSubmodule(repoRoot, sourcePath) {
261
+ return registeredSubmodulePaths(repoRoot).includes(sourcePath);
262
+ }
263
+ /** True when .gitmodules still registers at least one submodule. */
264
+ function hasRegisteredSubmodules(repoRoot) {
265
+ return registeredSubmodulePaths(repoRoot).length > 0;
257
266
  }
258
267
  /** A submodule is initialized when its working tree has a .git gitlink file/dir. */
259
268
  function submoduleInitialized(repoRoot, alias) {
@@ -512,22 +521,34 @@ function unsyncRepo(repo, repoRoot, force) {
512
521
  if (!registered && !exists)
513
522
  return "nothing-to-remove";
514
523
  if (!force && submoduleInitialized(repoRoot, alias) && isDirty(aliasDir(repoRoot, alias))) {
515
- log.error(`${alias}: ${path} has uncommitted changes. Commit, stash, or pass --force.`);
524
+ log.error(`${alias}: ${path} has uncommitted or untracked changes. Commit, stash, remove them, or pass --force.`);
516
525
  return "failed";
517
526
  }
518
527
  runGit(repoRoot, ["submodule", "deinit", ...(force ? ["-f"] : []), "--", path]);
519
528
  const rm = runGit(repoRoot, ["rm", "-f", "--", path], true);
520
529
  if (!rm.success) {
521
- // Fall back to manual unregistration (e.g. the submodule was never initialized).
530
+ // git rm couldn't stage the removal (e.g. the submodule was never initialized).
522
531
  runGit(repoRoot, ["rm", "-f", "--cached", "--", path]);
523
- runGit(repoRoot, ["config", "--file", ".gitmodules", "--remove-section", `submodule.${path}`]);
524
- if (existsSync(join(repoRoot, ".gitmodules")))
525
- runGit(repoRoot, ["add", ".gitmodules"]);
526
532
  }
533
+ // Always strip the registration explicitly: git rm's implicit .gitmodules edit is unreliable
534
+ // across git versions/states, and when it silently no-ops the section is orphaned for good.
535
+ // A missing section just makes these exit non-zero — harmless, output stays captured.
536
+ runGit(repoRoot, ["config", "--file", ".gitmodules", "--remove-section", `submodule.${path}`]);
537
+ if (existsSync(join(repoRoot, ".gitmodules")))
538
+ runGit(repoRoot, ["add", ".gitmodules"]);
539
+ // Drop the matching .git/config section too, in case deinit was skipped or failed.
540
+ runGit(repoRoot, ["config", "--remove-section", `submodule.${path}`]);
527
541
  try {
528
542
  rmSync(join(repoRoot, ".git", "modules", DATA_DIRNAME, alias), { recursive: true, force: true });
529
543
  }
530
544
  catch { }
545
+ // Drop the now-empty .git/modules/oms/ container so no stale gitdir scaffolding lingers.
546
+ try {
547
+ const modulesParent = join(repoRoot, ".git", "modules", DATA_DIRNAME);
548
+ if (existsSync(modulesParent) && readdirSync(modulesParent).length === 0)
549
+ rmdirSync(modulesParent);
550
+ }
551
+ catch { }
531
552
  if (existsSync(aliasDir(repoRoot, alias))) {
532
553
  rmSync(aliasDir(repoRoot, alias), { recursive: true, force: true });
533
554
  }
@@ -538,9 +559,9 @@ function unsyncRepo(repo, repoRoot, force) {
538
559
  rmdirSync(parent);
539
560
  }
540
561
  catch { }
541
- // Drop a .gitmodules that no longer registers any submodule (git rm leaves it empty).
562
+ // Drop .gitmodules once it no longer registers any submodule (judged by content, not byte-emptiness).
542
563
  const gitmodules = join(repoRoot, ".gitmodules");
543
- if (existsSync(gitmodules) && readFileSync(gitmodules, "utf8").trim().length === 0) {
564
+ if (existsSync(gitmodules) && !hasRegisteredSubmodules(repoRoot)) {
544
565
  if (!runGit(repoRoot, ["rm", "-f", "--", ".gitmodules"]).success) {
545
566
  rmSync(gitmodules, { force: true });
546
567
  }
@@ -764,6 +785,11 @@ async function runUnsync(aliases, options) {
764
785
  });
765
786
  if (results.length > 1 || options.all)
766
787
  printSummary(results);
788
+ // Name the failed aliases so a buried failure among several isn't read as "all unsynced".
789
+ const failed = picked.filter((_, i) => results[i] === "failed").map((r) => r.alias);
790
+ if (failed.length > 0) {
791
+ log.error(`Not unsynced: ${failed.join(", ")}. The submodule had uncommitted or untracked changes — commit/stash/remove them, or re-run with --force.`);
792
+ }
767
793
  return exitFromResults(results);
768
794
  }
769
795
  async function runCheckout(alias, branch, options) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oh-my-space",
3
- "version": "0.7.0",
3
+ "version": "0.7.1",
4
4
  "description": "CLI for managing external source repositories declared in oms.yaml.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://github.com/divlook/oh-my-space",