oh-my-space 0.4.0 → 0.5.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 (3) hide show
  1. package/README.md +5 -1
  2. package/dist/oms.js +31 -1
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -32,9 +32,10 @@ bun install -g oh-my-space
32
32
 
33
33
  ## Quick start
34
34
 
35
- Create an `oms.yaml` in your project root:
35
+ Run `oms init` to scaffold a starter `oms.yaml` (also adds `oms/` to `.gitignore`), or create one by hand in your project root:
36
36
 
37
37
  ```yaml
38
+ # yaml-language-server: $schema=https://raw.githubusercontent.com/divlook/oh-my-space/main/oms.schema.json
38
39
  repos:
39
40
  - alias: api
40
41
  url: git@github.com:example/api.git
@@ -46,6 +47,7 @@ repos:
46
47
  Sync and explore:
47
48
 
48
49
  ```bash
50
+ oms init # scaffold a starter oms.yaml
49
51
  oms doctor # validate oms.yaml + bare/worktree state
50
52
  oms sync --list # list registered source repos
51
53
  oms sync <alias>... # bare-clone + create the baseline worktree
@@ -81,6 +83,7 @@ Slash-containing branch names are kept nested as directories.
81
83
 
82
84
  | Command | Runs in | Does | Notes |
83
85
  | --- | --- | --- | --- |
86
+ | `oms init` | current directory | Writes a starter `oms.yaml` and adds `oms/` to `.gitignore`. | Refuses if `oms.yaml` exists; use `--force` to overwrite. |
84
87
  | `oms doctor` | project root or child path | Checks `oms.yaml`, git availability, `.gitignore`, and each alias's bare clone + `remote.origin.fetch`. | Returns exit 2 if any warning is raised. |
85
88
  | `oms sync <alias>` / `--all` | workspace root | Bare-clones missing repos, fetches origin, creates the baseline worktree. | Adds `oms/` to `.gitignore` if absent. |
86
89
  | `oms unsync <alias>` / `--all` | workspace root | Removes every worktree, the bare clone, and the `.git` placeholder for the alias. | Keeps the `oms.yaml` entry. Use `--force` to discard uncommitted changes. |
@@ -94,6 +97,7 @@ Slash-containing branch names are kept nested as directories.
94
97
  ## `oms.yaml` format
95
98
 
96
99
  ```yaml
100
+ # yaml-language-server: $schema=https://raw.githubusercontent.com/divlook/oh-my-space/main/oms.schema.json
97
101
  repos:
98
102
  - alias: service-a
99
103
  url: git@github.com:example/service-a.git
package/dist/oms.js CHANGED
@@ -13,6 +13,7 @@ const FETCH_REFSPEC = "+refs/heads/*:refs/remotes/origin/*";
13
13
  const MANIFEST_FILENAME = "oms.yaml";
14
14
  const DATA_DIRNAME = "oms";
15
15
  const GITIGNORE_ENTRY = `${DATA_DIRNAME}/`;
16
+ const GITIGNORE_COMMENT = "# managed by oms";
16
17
  const LEGACY_MANIFEST = "sources.yaml";
17
18
  const LEGACY_DATA_DIRNAME = "sources";
18
19
  const LEGACY_MIGRATION_DOC = "docs/migrations/0.3.x-to-0.4.0.md";
@@ -247,7 +248,8 @@ function ensureGitignore(repoRoot) {
247
248
  return;
248
249
  }
249
250
  const needsNewline = content.length > 0 && !content.endsWith("\n");
250
- writeFileSync(path, `${content}${needsNewline ? "\n" : ""}${GITIGNORE_ENTRY}\n`);
251
+ const block = `${GITIGNORE_COMMENT}\n${GITIGNORE_ENTRY}\n`;
252
+ writeFileSync(path, `${content}${needsNewline ? "\n" : ""}${block}`);
251
253
  log.info(`added ${GITIGNORE_ENTRY} to .gitignore`);
252
254
  }
253
255
  function setupBareRepo(repo, repoRoot) {
@@ -800,6 +802,25 @@ async function runWorktreeRemove(alias, branch, options) {
800
802
  log.success(`${alias}: removed worktree for ${branch}`);
801
803
  return 0;
802
804
  }
805
+ const INIT_TEMPLATE = `# yaml-language-server: $schema=https://raw.githubusercontent.com/divlook/oh-my-space/main/oms.schema.json
806
+ repos:
807
+ - alias: example
808
+ url: git@github.com:example/repo.git
809
+ branch: main
810
+ `;
811
+ /** 현재 디렉터리에 기본 oms.yaml 템플릿을 생성합니다. */
812
+ async function runInit(options) {
813
+ const target = join(process.cwd(), MANIFEST_FILENAME);
814
+ if (existsSync(target) && !options.force) {
815
+ log.error(`${MANIFEST_FILENAME} already exists at ${target}. Use --force to overwrite.`);
816
+ return 1;
817
+ }
818
+ writeFileSync(target, INIT_TEMPLATE);
819
+ log.success(`created ${MANIFEST_FILENAME} at ${target}`);
820
+ ensureGitignore(process.cwd());
821
+ log.info(`edit alias/url/branch, then run "oms sync".`);
822
+ return 0;
823
+ }
803
824
  async function runDoctor() {
804
825
  const loaded = loadRepos();
805
826
  if (!loaded) {
@@ -884,6 +905,7 @@ async function exitWith(action) {
884
905
  }
885
906
  const exitHelp = "\nExit codes: 0 ok | 1 usage/config error | 2 one or more git operations failed.";
886
907
  const commandNames = new Set([
908
+ "init",
887
909
  "doctor",
888
910
  "sync",
889
911
  "fetch",
@@ -899,6 +921,14 @@ program
899
921
  .description(`Manage source repositories listed in ${MANIFEST_FILENAME} as bare clones + worktrees under ${DATA_DIRNAME}/<alias>/.`)
900
922
  .version(readPackageVersion())
901
923
  .addHelpText("after", exitHelp);
924
+ program
925
+ .command("init")
926
+ .description(`Create a starter ${MANIFEST_FILENAME} in the current directory.`)
927
+ .option("--force", `overwrite an existing ${MANIFEST_FILENAME}`)
928
+ .addHelpText("after", exitHelp)
929
+ .action(async (options) => {
930
+ await exitWith(runInit(options));
931
+ });
902
932
  program
903
933
  .command("doctor")
904
934
  .description(`Check ${MANIFEST_FILENAME}, git availability, bare-clone state, and .gitignore for each registered alias.`)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oh-my-space",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
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",