wyvrnpm 1.1.1 → 1.1.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "wyvrnpm",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "description": "A simple, static-hosting-compatible C++ package manager",
5
5
  "keywords": [
6
6
  "c++",
@@ -8,6 +8,69 @@ const { readManifest } = require('../manifest');
8
8
  const { getProvider } = require('../providers');
9
9
  const { readConfig } = require('../config');
10
10
 
11
+ /**
12
+ * Parse a .wyvrnignore file and return an array of pattern strings.
13
+ * Lines starting with '#' and blank lines are ignored.
14
+ */
15
+ function loadIgnorePatterns(ignoreFile) {
16
+ if (!fs.existsSync(ignoreFile)) return [];
17
+ return fs
18
+ .readFileSync(ignoreFile, 'utf8')
19
+ .split(/\r?\n/)
20
+ .map((l) => l.trim())
21
+ .filter((l) => l.length > 0 && !l.startsWith('#'));
22
+ }
23
+
24
+ /**
25
+ * Convert a glob-style ignore pattern to a RegExp.
26
+ * Supports '*', '**', '?' wildcards and leading '/' to anchor to root.
27
+ */
28
+ function patternToRegex(pattern) {
29
+ // A leading slash means "anchored to root"; strip it and keep the rest
30
+ const anchored = pattern.startsWith('/');
31
+ const p = anchored ? pattern.slice(1) : pattern;
32
+
33
+ let re = p
34
+ .replace(/[.+^${}()|[\]\\]/g, '\\$&') // escape regex special chars
35
+ .replace(/\*\*/g, '\x00') // placeholder for **
36
+ .replace(/\*/g, '[^/]*') // * → match within segment
37
+ .replace(/\?/g, '[^/]') // ? → single non-slash char
38
+ .replace(/\x00/g, '.*'); // ** → match across segments
39
+
40
+ // If anchored, match from the start; otherwise match any path segment
41
+ return anchored ? new RegExp(`^${re}(/|$)`) : new RegExp(`(^|/)${re}(/|$)`);
42
+ }
43
+
44
+ /**
45
+ * Recursively add files from `dir` into `zip`, skipping any path that
46
+ * matches one of the compiled ignore regexes.
47
+ *
48
+ * @param {AdmZip} zip
49
+ * @param {string} dir Absolute path of the directory being zipped
50
+ * @param {string} base Absolute path of the root publish directory
51
+ * @param {RegExp[]} ignoreRe Compiled ignore patterns
52
+ */
53
+ function addFolderFiltered(zip, dir, base, ignoreRe) {
54
+ for (const entry of fs.readdirSync(dir)) {
55
+ const fullPath = path.join(dir, entry);
56
+ // Relative path from publish root, always using forward slashes
57
+ const relPath = path.relative(base, fullPath).replace(/\\/g, '/');
58
+
59
+ if (ignoreRe.some((re) => re.test(relPath))) {
60
+ console.log(`[wyvrn] Ignoring: ${relPath}`);
61
+ continue;
62
+ }
63
+
64
+ const stat = fs.statSync(fullPath);
65
+ if (stat.isDirectory()) {
66
+ addFolderFiltered(zip, fullPath, base, ignoreRe);
67
+ } else {
68
+ const zipDir = path.dirname(relPath).replace(/\\/g, '/');
69
+ zip.addLocalFile(fullPath, zipDir === '.' ? '' : zipDir);
70
+ }
71
+ }
72
+ }
73
+
11
74
  async function publish(argv) {
12
75
  let { source, profile, platform, path: publishPath, token, manifest: manifestArg } = argv;
13
76
 
@@ -74,12 +137,20 @@ async function publish(argv) {
74
137
  `[wyvrn] Publishing ${name}@${version} (${targetPlatform}) via ${provider.constructor.providerName} provider`,
75
138
  );
76
139
 
140
+ // Load .wyvrnignore patterns from the publish directory
141
+ const ignoreFile = path.join(srcDir, '.wyvrnignore');
142
+ const ignorePatterns = loadIgnorePatterns(ignoreFile);
143
+ const ignoreRe = ignorePatterns.map(patternToRegex);
144
+ if (ignorePatterns.length > 0) {
145
+ console.log(`[wyvrn] Loaded ${ignorePatterns.length} pattern(s) from .wyvrnignore`);
146
+ }
147
+
77
148
  // Build a temporary zip of the publish directory
78
149
  const tmpZipPath = path.join(os.tmpdir(), `wyvrnpm-${name}-${version}-${Date.now()}.zip`);
79
150
  try {
80
151
  console.log(`[wyvrn] Zipping ${srcDir} ...`);
81
152
  const zip = new AdmZip();
82
- zip.addLocalFolder(srcDir);
153
+ addFolderFiltered(zip, srcDir, srcDir, ignoreRe);
83
154
  zip.writeZip(tmpZipPath);
84
155
 
85
156
  await provider.publish(