ziku 0.22.0 → 0.22.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.
Files changed (2) hide show
  1. package/dist/index.mjs +46 -26
  2. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -2,7 +2,7 @@
2
2
  import { createRequire } from "node:module";
3
3
  import * as p from "@clack/prompts";
4
4
  import { defineCommand, runMain } from "citty";
5
- import { copyFileSync, existsSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
5
+ import { accessSync, constants, copyFileSync, existsSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
6
6
  import { mkdir, readFile, rm, writeFile } from "node:fs/promises";
7
7
  import { dirname, join, resolve } from "pathe";
8
8
  import * as YAML from "yaml";
@@ -14,6 +14,7 @@ import { applyPatch, createPatch, diffWords, structuredPatch } from "diff";
14
14
  import pc, { default as pc$1 } from "picocolors";
15
15
  import ignore from "ignore";
16
16
  import { glob, globSync } from "tinyglobby";
17
+ import { homedir, tmpdir } from "node:os";
17
18
  import { match } from "ts-pattern";
18
19
  import { execFileSync } from "node:child_process";
19
20
  import { Octokit } from "@octokit/rest";
@@ -26,7 +27,7 @@ var __require = /* @__PURE__ */ createRequire(import.meta.url);
26
27
 
27
28
  //#endregion
28
29
  //#region package.json
29
- var version$2 = "0.22.0";
30
+ var version$2 = "0.22.2";
30
31
 
31
32
  //#endregion
32
33
  //#region src/modules/schemas.ts
@@ -872,7 +873,7 @@ function getEffectivePatterns(_moduleId, modulePatterns, config) {
872
873
  *
873
874
  * 削除条件: ziku が別の UI フレームワーク(ink 等)に移行する場合。
874
875
  */
875
- const version$1 = "0.22.0";
876
+ const version$1 = "0.22.2";
876
877
  /** CLI の開始表示 */
877
878
  function intro(command) {
878
879
  const title = command ? `ziku ${command}` : "ziku";
@@ -1170,6 +1171,28 @@ function applyWordDiffAndColorize(lines) {
1170
1171
  //#region src/utils/template.ts
1171
1172
  const TEMPLATE_SOURCE = "gh:tktcorporation/.github";
1172
1173
  /**
1174
+ * giget のキャッシュディレクトリが書き込み可能か確認し、不可能なら XDG_CACHE_HOME を
1175
+ * 書き込み可能な一時ディレクトリにフォールバックさせる。
1176
+ *
1177
+ * 背景: giget は内部で homedir()/.cache/giget にキャッシュを作成するが、
1178
+ * Codespaces 等の環境で homedir のキャッシュディレクトリに書き込み権限がない場合に
1179
+ * EACCES エラーが発生する。XDG_CACHE_HOME が設定済みなら giget はそちらを使うため、
1180
+ * フォールバック先として tmpdir を設定する。
1181
+ *
1182
+ * 呼び出し元: downloadTemplateToTemp(), fetchTemplates()
1183
+ * giget が XDG_CACHE_HOME 対応をやめれば不要になる。
1184
+ */
1185
+ function ensureGigetCacheDir() {
1186
+ if (process.env.XDG_CACHE_HOME) return;
1187
+ const defaultCacheDir = resolve(homedir(), ".cache");
1188
+ try {
1189
+ if (!existsSync(defaultCacheDir)) mkdirSync(defaultCacheDir, { recursive: true });
1190
+ accessSync(defaultCacheDir, constants.W_OK);
1191
+ } catch {
1192
+ process.env.XDG_CACHE_HOME = resolve(tmpdir(), "giget-cache");
1193
+ }
1194
+ }
1195
+ /**
1173
1196
  * DevEnvConfig の source フィールドから giget 用のテンプレートソース文字列を構築する。
1174
1197
  *
1175
1198
  * 背景: giget は "gh:owner/repo" または "gh:owner/repo#ref" 形式を期待する。
@@ -1188,6 +1211,7 @@ function buildTemplateSource(source) {
1188
1211
  */
1189
1212
  async function downloadTemplateToTemp(targetDir, source) {
1190
1213
  const tempDir = join(targetDir, ".devenv-temp");
1214
+ ensureGigetCacheDir();
1191
1215
  const { dir: templateDir } = await downloadTemplate(source ?? TEMPLATE_SOURCE, {
1192
1216
  dir: tempDir,
1193
1217
  force: true
@@ -1254,11 +1278,13 @@ async function fetchTemplates(options) {
1254
1278
  const tempDir = join(targetDir, ".devenv-temp");
1255
1279
  let templateDir;
1256
1280
  try {
1257
- if (shouldDownload) templateDir = (await downloadTemplate(TEMPLATE_SOURCE, {
1258
- dir: tempDir,
1259
- force: true
1260
- })).dir;
1261
- else templateDir = preDownloadedDir;
1281
+ if (shouldDownload) {
1282
+ ensureGigetCacheDir();
1283
+ templateDir = (await downloadTemplate(TEMPLATE_SOURCE, {
1284
+ dir: tempDir,
1285
+ force: true
1286
+ })).dir;
1287
+ } else templateDir = preDownloadedDir;
1262
1288
  const gitignore = await loadMergedGitignore([targetDir, templateDir]);
1263
1289
  for (const moduleId of modules) {
1264
1290
  const moduleDef = moduleList ? moduleList.find((m) => m.id === moduleId) : getModuleById(moduleId);
@@ -2040,7 +2066,7 @@ async function hashFiles(dir, patterns) {
2040
2066
 
2041
2067
  //#endregion
2042
2068
  //#region src/commands/init.ts
2043
- const version = "0.22.0";
2069
+ const version = "0.22.2";
2044
2070
  const initCommand = defineCommand({
2045
2071
  meta: {
2046
2072
  name: "ziku",
@@ -2396,15 +2422,15 @@ function threeWayMerge({ base, local, template, filePath }) {
2396
2422
  };
2397
2423
  if (filePath && isJsonFile(filePath)) {
2398
2424
  const jsonResult = mergeJsonContent(base, local, template);
2399
- if (jsonResult !== null) return jsonResult;
2425
+ if (jsonResult !== null && !jsonResult.hasConflicts) return jsonResult;
2400
2426
  }
2401
2427
  if (filePath && isTomlFile(filePath)) {
2402
2428
  const tomlResult = mergeTomlContent(base, local, template);
2403
- if (tomlResult !== null) return tomlResult;
2429
+ if (tomlResult !== null && !tomlResult.hasConflicts) return tomlResult;
2404
2430
  }
2405
2431
  if (filePath && isYamlFile(filePath)) {
2406
2432
  const yamlResult = mergeYamlContent(base, local, template);
2407
- if (yamlResult !== null) return yamlResult;
2433
+ if (yamlResult !== null && !yamlResult.hasConflicts) return yamlResult;
2408
2434
  }
2409
2435
  return textThreeWayMerge(base, local, template, filePath);
2410
2436
  }
@@ -2938,7 +2964,7 @@ const pullCommand = defineCommand({
2938
2964
  await writeFile(join(targetDir, file), result.content, "utf-8");
2939
2965
  if (result.hasConflicts) {
2940
2966
  unresolvedConflicts.push(file);
2941
- logMergeConflict(file, result);
2967
+ logMergeConflict(file);
2942
2968
  } else log.success(`Auto-merged: ${pc$1.cyan(file)}`);
2943
2969
  }
2944
2970
  if (unresolvedConflicts.length > 0) log.warn("Some files have conflicts. Resolve them, then run `ziku pull --continue`");
@@ -3014,20 +3040,14 @@ async function runContinue(targetDir, config) {
3014
3040
  outro("Pull complete");
3015
3041
  }
3016
3042
  /**
3017
- * 1ファイルのマージ結果をユーザーに報告する。
3043
+ * 1ファイルのマージコンフリクトをユーザーに報告する。
3018
3044
  *
3019
- * 背景: JSON/JSONC の構造マージ(conflictDetails あり)とテキストマージ(conflictMarkers あり)で
3020
- * メッセージが異なるため、このヘルパーに集約する。
3021
- * Step 8 と他の呼び出し元でログ出力のロジックを共有する。
3022
- */
3023
- function logMergeConflict(file, result) {
3024
- if (result.conflictDetails.length > 0) {
3025
- log.warn(`Conflict in ${pc$1.cyan(file)} — review these keys:`);
3026
- for (const detail of result.conflictDetails) {
3027
- const pathStr = detail.path.join(".");
3028
- log.message(` ${pc$1.dim("•")} ${pc$1.yellow(pathStr)} — kept local value`);
3029
- }
3030
- } else log.warn(`Conflict in ${pc$1.cyan(file)} — manual resolution needed`);
3045
+ * 背景: threeWayMerge hasConflicts: true を返す場合、必ずファイル内に
3046
+ * コンフリクトマーカー(<<<<<<< LOCAL / ======= / >>>>>>> TEMPLATE)を挿入する。
3047
+ * ユーザーはマーカーを手動で解決し、`ziku pull --continue` で完了する。
3048
+ */
3049
+ function logMergeConflict(file) {
3050
+ log.warn(`Conflict in ${pc$1.cyan(file)} manual resolution needed`);
3031
3051
  }
3032
3052
  /**
3033
3053
  * インストール済みモジュールの有効パターンを全て取得する。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ziku",
3
- "version": "0.22.0",
3
+ "version": "0.22.2",
4
4
  "description": "Interactive CLI to scaffold development environment templates",
5
5
  "repository": {
6
6
  "type": "git",