cross-bump 0.2.1 → 0.2.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.
package/dist/index.d.ts CHANGED
@@ -6,10 +6,16 @@ declare const DEFAULT_IGNORED_GLOBS: string[];
6
6
  declare const G_GITIGNORE = "**/.gitignore";
7
7
  declare function getGitignores(cwd?: string, ignoreGlobs?: string[]): Set<string>;
8
8
  /**
9
- * parse gitignore to globs
10
- * @param content gitignore file content
9
+ * Parses gitignore content into an array of glob patterns.
10
+ *
11
+ * rules ref: https://git-scm.com/docs/gitignore#_pattern_format
12
+ *
13
+ * @param content The content of the .gitignore file.
14
+ * @param gitignoreFilePath Absolute path to the .gitignore file.
15
+ * @param projectRoot Absolute path to the project root (cwd for fast-glob).
16
+ * @returns An array of glob patterns.
11
17
  */
12
- declare function parseGitingore(content: string): string[];
18
+ declare function parseGitingore(content: string, gitignoreFilePath: string, projectRoot: string): string[];
13
19
 
14
20
  //#endregion
15
21
  //#region src/project.d.ts
package/dist/index.js CHANGED
@@ -1,9 +1,8 @@
1
1
  import * as fs$1 from "node:fs";
2
2
  import fs, { readFileSync } from "node:fs";
3
- import fg from "fast-glob";
4
- import isGlob from "is-glob";
5
3
  import path from "node:path";
6
4
  import process from "node:process";
5
+ import fg from "fast-glob";
7
6
  import initTomlEdit, { edit, parse } from "@rainbowatcher/toml-edit-js";
8
7
  import * as cheerio from "cheerio";
9
8
  import detectIndent from "detect-indent";
@@ -19,50 +18,95 @@ const DEFAULT_IGNORED_GLOBS = [
19
18
  ];
20
19
  const G_GITIGNORE = "**/.gitignore";
21
20
  function getGitignores(cwd, ignoreGlobs = DEFAULT_IGNORED_GLOBS) {
22
- const gitignores = fg.sync(G_GITIGNORE, {
21
+ const gitignoreFiles = fg.sync(G_GITIGNORE, {
23
22
  absolute: true,
24
23
  cwd,
25
24
  ignore: ignoreGlobs,
26
25
  onlyFiles: true
27
26
  });
28
27
  const set = new Set();
29
- for (const gi of gitignores) {
30
- const rules = readFileSync(gi, { encoding: "utf8" });
31
- const globs = parseGitingore(rules);
28
+ for (const gitignoreFilePath of gitignoreFiles) {
29
+ const rules = readFileSync(gitignoreFilePath, { encoding: "utf8" });
30
+ const globs = parseGitingore(rules, gitignoreFilePath, cwd = process.cwd());
32
31
  if (globs.length === 0) continue;
33
32
  for (const item of globs) set.add(item);
34
33
  }
35
34
  return set;
36
35
  }
37
36
  /**
38
- * parse gitignore to globs
39
- * @param content gitignore file content
37
+ * Processes a raw line from .gitignore content.
38
+ * Handles empty lines, comments, trailing whitespace
39
+ */
40
+ function processRawGitignoreLine(rawLine) {
41
+ let line = rawLine.trimStart();
42
+ if (line.length === 0 || line.startsWith("#")) return {
43
+ cleanedLine: "",
44
+ shouldSkip: true
45
+ };
46
+ line = normalizeIgnoreRule(line);
47
+ let isNegative = false;
48
+ if (/\\\s*$/.test(line)) line = `${line.replace(/\\\s*$/, "")} `;
49
+ else line = line.trimEnd();
50
+ if (line.startsWith("!")) {
51
+ line = line.slice(1);
52
+ isNegative = true;
53
+ }
54
+ return {
55
+ cleanedLine: line,
56
+ isNegative
57
+ };
58
+ }
59
+ /**
60
+ * Converts the gitignore pattern to a glob pattern relative to the project root.
61
+ * @param result The processed gitignore line result
62
+ * @param gitignoreFileDirAbs Absolute path to the directory containing the .gitignore file.
63
+ * @param projectRoot Absolute path to the project root.
40
64
  */
41
- function parseGitingore(content) {
42
- const globs = [];
65
+ function toRelativeGlob(result, gitignoreFileDirAbs, projectRoot) {
66
+ const { cleanedLine, isNegative } = result;
67
+ const pattern = cleanedLine.replaceAll(/\\([# !])/g, "$1");
68
+ const relativeGitignoreDir = path.relative(projectRoot, gitignoreFileDirAbs);
69
+ let glob;
70
+ if (pattern.includes("/")) {
71
+ const _pattern = pattern.startsWith("/") ? pattern.slice(1) : pattern.startsWith("**/") ? pattern : `**/${pattern.endsWith("/") ? pattern.slice(0, -1) : pattern}`;
72
+ const targetPath = path.resolve(gitignoreFileDirAbs, _pattern);
73
+ glob = path.relative(projectRoot, targetPath) || ".";
74
+ } else glob = path.join(relativeGitignoreDir, "**", pattern);
75
+ if (glob === "*" || glob === ".") glob = path.join(relativeGitignoreDir, glob);
76
+ return isNegative ? `!${glob}` : glob;
77
+ }
78
+ /**
79
+ * Normalizes the gitignore rule
80
+ * Converts path separators to `/`, removes leading `./`, and handles empty globs.
81
+ */
82
+ function normalizeIgnoreRule(glob) {
83
+ let normalized = glob.replaceAll("\\\\", "/");
84
+ if (normalized.startsWith("./")) normalized = normalized.slice(2);
85
+ if (normalized === "") normalized = ".";
86
+ return normalized;
87
+ }
88
+ /**
89
+ * Parses gitignore content into an array of glob patterns.
90
+ *
91
+ * rules ref: https://git-scm.com/docs/gitignore#_pattern_format
92
+ *
93
+ * @param content The content of the .gitignore file.
94
+ * @param gitignoreFilePath Absolute path to the .gitignore file.
95
+ * @param projectRoot Absolute path to the project root (cwd for fast-glob).
96
+ * @returns An array of glob patterns.
97
+ */
98
+ function parseGitingore(content, gitignoreFilePath, projectRoot) {
99
+ const resultGlobs = [];
43
100
  const lines = content.split(/\r\n?|\n/);
101
+ const gitignoreFileDirAbs = path.dirname(gitignoreFilePath);
44
102
  for (const rawLine of lines) {
45
- const line = rawLine.trim();
46
- if (line.startsWith("#") || line.length === 0) continue;
47
- let isNegative = false;
48
- let pattern = line;
49
- if (pattern.startsWith("!")) {
50
- isNegative = true;
51
- pattern = pattern.slice(1);
52
- }
53
- if (isGlob(pattern)) {
54
- globs.push(isNegative ? `!${pattern}` : pattern);
55
- continue;
56
- }
57
- if (pattern.endsWith("/")) {
58
- const dirPattern = pattern.slice(0, -1);
59
- globs.push(isNegative ? `!**/${dirPattern}/**` : `**/${dirPattern}/**`);
60
- } else if (pattern.startsWith("/")) {
61
- const rootPattern = pattern.slice(1);
62
- globs.push(isNegative ? `!${rootPattern}` : rootPattern, isNegative ? `!${rootPattern}/**` : `${rootPattern}/**`);
63
- } else globs.push(isNegative ? `!**/${pattern}` : `**/${pattern}`, isNegative ? `!**/${pattern}/**` : `**/${pattern}/**`);
103
+ const result = processRawGitignoreLine(rawLine);
104
+ if (result.shouldSkip) continue;
105
+ const relativeGlob = toRelativeGlob(result, gitignoreFileDirAbs, projectRoot);
106
+ resultGlobs.push(relativeGlob);
107
+ if (!relativeGlob.endsWith("*") && relativeGlob !== ".") resultGlobs.push(`${relativeGlob}/**`);
64
108
  }
65
- return globs;
109
+ return [...new Set(resultGlobs)];
66
110
  }
67
111
 
68
112
  //#endregion
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "cross-bump",
3
3
  "type": "module",
4
- "version": "0.2.1",
4
+ "version": "0.2.2",
5
5
  "description": "cross language bump utility",
6
6
  "author": {
7
7
  "name": "rainbowatcher",
@@ -39,7 +39,7 @@
39
39
  "detect-indent": "^7.0.1",
40
40
  "fast-glob": "^3.3.3",
41
41
  "is-glob": "^4.0.3",
42
- "semver": "^7.7.1"
42
+ "semver": "^7.7.2"
43
43
  },
44
44
  "scripts": {
45
45
  "clean": "rimraf dist/*",