wyvrnpm 1.2.1 → 2.0.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.
- package/README.md +513 -413
- package/bin/wyvrn.js +277 -163
- package/package.json +37 -37
- package/src/commands/install.js +156 -109
- package/src/commands/link.js +316 -0
- package/src/commands/profile.js +171 -0
- package/src/commands/publish.js +232 -180
- package/src/config.js +63 -60
- package/src/download.js +325 -164
- package/src/index.js +10 -9
- package/src/link-utils.js +95 -0
- package/src/manifest.js +133 -77
- package/src/profile.js +377 -0
- package/src/providers/base.js +133 -56
- package/src/providers/file.js +181 -71
- package/src/providers/http.js +268 -118
- package/src/providers/s3.js +273 -136
- package/src/resolve.js +262 -200
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const {
|
|
4
|
+
detectProfile,
|
|
5
|
+
hashProfile,
|
|
6
|
+
formatProfile,
|
|
7
|
+
readProfile,
|
|
8
|
+
writeProfile,
|
|
9
|
+
deleteProfile,
|
|
10
|
+
listProfiles,
|
|
11
|
+
getProfilesDir,
|
|
12
|
+
mergeProfile,
|
|
13
|
+
} = require('../profile');
|
|
14
|
+
const { readConfig, writeConfig } = require('../config');
|
|
15
|
+
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// list
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* wyvrnpm configure profile list
|
|
22
|
+
* Show all saved profiles and which one is the default.
|
|
23
|
+
*/
|
|
24
|
+
function list() {
|
|
25
|
+
const config = readConfig();
|
|
26
|
+
const names = listProfiles();
|
|
27
|
+
const dir = getProfilesDir();
|
|
28
|
+
const defName = config.defaultProfile ?? 'default';
|
|
29
|
+
|
|
30
|
+
console.log(`[wyvrn] Profiles directory: ${dir}`);
|
|
31
|
+
console.log(`[wyvrn] Default profile : ${defName}\n`);
|
|
32
|
+
|
|
33
|
+
if (names.length === 0) {
|
|
34
|
+
console.log(' (no profiles saved — run `wyvrnpm configure profile detect` to create one)');
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
for (const name of names) {
|
|
39
|
+
const marker = name === defName ? ' *' : '';
|
|
40
|
+
const p = readProfile(name);
|
|
41
|
+
const summary = p
|
|
42
|
+
? `${p.os}/${p.arch} ${p.compiler} ${p['compiler.version']} C++${p['compiler.cppstd']}` +
|
|
43
|
+
(p['compiler.runtime'] ? ` [${p['compiler.runtime']}]` : '')
|
|
44
|
+
: '(unreadable)';
|
|
45
|
+
console.log(` ${(name + marker).padEnd(24)} ${summary}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
// show
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* wyvrnpm configure profile show [--name <name>]
|
|
55
|
+
* Display a specific profile (defaults to the configured default).
|
|
56
|
+
*/
|
|
57
|
+
function show(argv) {
|
|
58
|
+
const config = readConfig();
|
|
59
|
+
const name = argv.name ?? config.defaultProfile ?? 'default';
|
|
60
|
+
const stored = readProfile(name);
|
|
61
|
+
|
|
62
|
+
if (stored) {
|
|
63
|
+
console.log(`[wyvrn] Profile "${name}":`);
|
|
64
|
+
console.log(formatProfile(stored));
|
|
65
|
+
console.log(`\nProfile hash : ${hashProfile(stored)}`);
|
|
66
|
+
} else {
|
|
67
|
+
const detected = detectProfile();
|
|
68
|
+
console.log(`[wyvrn] Profile "${name}" not found — showing auto-detected environment:`);
|
|
69
|
+
console.log(formatProfile(detected));
|
|
70
|
+
console.log(`\nProfile hash : ${hashProfile(detected)}`);
|
|
71
|
+
console.log(`\nRun \`wyvrnpm configure profile detect --name ${name}\` to save this.`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// ---------------------------------------------------------------------------
|
|
76
|
+
// detect
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* wyvrnpm configure profile detect [--name <name>] [--dry-run]
|
|
81
|
+
* Auto-detect the current build environment and save it as a named profile.
|
|
82
|
+
*/
|
|
83
|
+
function detect(argv) {
|
|
84
|
+
const config = readConfig();
|
|
85
|
+
const name = argv.name ?? config.defaultProfile ?? 'default';
|
|
86
|
+
const p = detectProfile();
|
|
87
|
+
|
|
88
|
+
console.log('[wyvrn] Detected profile:');
|
|
89
|
+
console.log(formatProfile(p));
|
|
90
|
+
console.log(`\nProfile hash : ${hashProfile(p)}`);
|
|
91
|
+
|
|
92
|
+
if (!argv.dryRun) {
|
|
93
|
+
writeProfile(name, p);
|
|
94
|
+
console.log(`\n[wyvrn] Saved as profile "${name}".`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// ---------------------------------------------------------------------------
|
|
99
|
+
// set
|
|
100
|
+
// ---------------------------------------------------------------------------
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* wyvrnpm configure profile set [--name <name>] [field options]
|
|
104
|
+
* Manually override individual fields in a named profile.
|
|
105
|
+
* Starts from the existing saved profile, or auto-detects if none exists yet.
|
|
106
|
+
*/
|
|
107
|
+
function set(argv) {
|
|
108
|
+
const config = readConfig();
|
|
109
|
+
const name = argv.name ?? config.defaultProfile ?? 'default';
|
|
110
|
+
const base = readProfile(name) ?? detectProfile();
|
|
111
|
+
|
|
112
|
+
const updated = mergeProfile(base, {
|
|
113
|
+
os: argv.os ?? null,
|
|
114
|
+
arch: argv.arch ?? null,
|
|
115
|
+
compiler: argv.compiler ?? null,
|
|
116
|
+
'compiler.version': argv.compilerVersion ?? null,
|
|
117
|
+
'compiler.cppstd': argv.cppstd ?? null,
|
|
118
|
+
'compiler.runtime': argv.runtime ?? null,
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
writeProfile(name, updated);
|
|
122
|
+
|
|
123
|
+
console.log(`[wyvrn] Profile "${name}" updated:`);
|
|
124
|
+
console.log(formatProfile(updated));
|
|
125
|
+
console.log(`\nProfile hash : ${hashProfile(updated)}`);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// ---------------------------------------------------------------------------
|
|
129
|
+
// setDefault
|
|
130
|
+
// ---------------------------------------------------------------------------
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* wyvrnpm configure profile set-default <name>
|
|
134
|
+
* Change which named profile is used by default.
|
|
135
|
+
*/
|
|
136
|
+
function setDefault(argv) {
|
|
137
|
+
const name = argv.name;
|
|
138
|
+
if (!readProfile(name)) {
|
|
139
|
+
console.error(`[wyvrn] Error: profile "${name}" does not exist. Create it first.`);
|
|
140
|
+
process.exit(1);
|
|
141
|
+
}
|
|
142
|
+
const config = readConfig();
|
|
143
|
+
config.defaultProfile = name;
|
|
144
|
+
writeConfig(config);
|
|
145
|
+
console.log(`[wyvrn] Default profile set to "${name}".`);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// ---------------------------------------------------------------------------
|
|
149
|
+
// del
|
|
150
|
+
// ---------------------------------------------------------------------------
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* wyvrnpm configure profile delete <name>
|
|
154
|
+
* Remove a saved profile file.
|
|
155
|
+
*/
|
|
156
|
+
function del(argv) {
|
|
157
|
+
const name = argv.name;
|
|
158
|
+
if (name === 'default') {
|
|
159
|
+
console.error('[wyvrn] Error: cannot delete the "default" profile.');
|
|
160
|
+
process.exit(1);
|
|
161
|
+
}
|
|
162
|
+
const removed = deleteProfile(name);
|
|
163
|
+
if (removed) {
|
|
164
|
+
console.log(`[wyvrn] Profile "${name}" deleted.`);
|
|
165
|
+
} else {
|
|
166
|
+
console.error(`[wyvrn] Error: profile "${name}" not found.`);
|
|
167
|
+
process.exit(1);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
module.exports = { list, show, detect, set, setDefault, del };
|
package/src/commands/publish.js
CHANGED
|
@@ -1,180 +1,232 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const fs
|
|
4
|
-
const path = require('path');
|
|
5
|
-
const os
|
|
6
|
-
const AdmZip = require('adm-zip');
|
|
7
|
-
|
|
8
|
-
const {
|
|
9
|
-
const {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
.
|
|
21
|
-
.
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
.replace(/
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const os = require('os');
|
|
6
|
+
const AdmZip = require('adm-zip');
|
|
7
|
+
|
|
8
|
+
const { readManifest } = require('../manifest');
|
|
9
|
+
const { getProvider } = require('../providers');
|
|
10
|
+
const { readConfig } = require('../config');
|
|
11
|
+
const { loadProfile, hashProfile, sha256Of, getGitSha, getGitRepo } = require('../profile');
|
|
12
|
+
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// .wyvrnignore helpers (unchanged from v1)
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
|
|
17
|
+
function loadIgnorePatterns(ignoreFile) {
|
|
18
|
+
if (!fs.existsSync(ignoreFile)) return [];
|
|
19
|
+
return fs
|
|
20
|
+
.readFileSync(ignoreFile, 'utf8')
|
|
21
|
+
.split(/\r?\n/)
|
|
22
|
+
.map((l) => l.trim())
|
|
23
|
+
.filter((l) => l.length > 0 && !l.startsWith('#'));
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function patternToRegex(pattern) {
|
|
27
|
+
const anchored = pattern.startsWith('/');
|
|
28
|
+
const p = anchored ? pattern.slice(1) : pattern;
|
|
29
|
+
let re = p
|
|
30
|
+
.replace(/[.+^${}()|[\]\\]/g, '\\$&')
|
|
31
|
+
.replace(/\*\*/g, '\x00')
|
|
32
|
+
.replace(/\*/g, '[^/]*')
|
|
33
|
+
.replace(/\?/g, '[^/]')
|
|
34
|
+
.replace(/\x00/g, '.*');
|
|
35
|
+
return anchored ? new RegExp(`^${re}(/|$)`) : new RegExp(`(^|/)${re}(/|$)`);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function addFolderFiltered(zip, dir, base, ignoreRe) {
|
|
39
|
+
for (const entry of fs.readdirSync(dir)) {
|
|
40
|
+
const fullPath = path.join(dir, entry);
|
|
41
|
+
const relPath = path.relative(base, fullPath).replace(/\\/g, '/');
|
|
42
|
+
if (ignoreRe.some((re) => re.test(relPath))) {
|
|
43
|
+
console.log(`[wyvrn] Ignoring: ${relPath}`);
|
|
44
|
+
continue;
|
|
45
|
+
}
|
|
46
|
+
const stat = fs.statSync(fullPath);
|
|
47
|
+
if (stat.isDirectory()) {
|
|
48
|
+
addFolderFiltered(zip, fullPath, base, ignoreRe);
|
|
49
|
+
} else {
|
|
50
|
+
const zipDir = path.dirname(relPath).replace(/\\/g, '/');
|
|
51
|
+
zip.addLocalFile(fullPath, zipDir === '.' ? '' : zipDir);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// ---------------------------------------------------------------------------
|
|
57
|
+
// Source resolution
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
59
|
+
|
|
60
|
+
function resolveSource(argv) {
|
|
61
|
+
let { source, awsProfile, token } = argv;
|
|
62
|
+
const config = readConfig();
|
|
63
|
+
|
|
64
|
+
if (source) {
|
|
65
|
+
const named = config.publishSources.find((s) => s.name === source);
|
|
66
|
+
if (named) {
|
|
67
|
+
console.log(`[wyvrn] Using publish source "${named.name}" from config`);
|
|
68
|
+
source = named.url;
|
|
69
|
+
awsProfile = awsProfile ?? named.profile;
|
|
70
|
+
token = token ?? named.token;
|
|
71
|
+
}
|
|
72
|
+
} else {
|
|
73
|
+
if (config.publishSources.length === 0) {
|
|
74
|
+
console.error(
|
|
75
|
+
'[wyvrn] Error: --source is required (or configure one with: ' +
|
|
76
|
+
'wyvrnpm configure add-source --kind publish ...)',
|
|
77
|
+
);
|
|
78
|
+
process.exit(1);
|
|
79
|
+
}
|
|
80
|
+
const first = config.publishSources[0];
|
|
81
|
+
console.log(`[wyvrn] Using publish source "${first.name}" from config`);
|
|
82
|
+
source = first.url;
|
|
83
|
+
awsProfile = awsProfile ?? first.profile;
|
|
84
|
+
token = token ?? first.token;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return { source, awsProfile, token };
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// ---------------------------------------------------------------------------
|
|
91
|
+
// Main publish command
|
|
92
|
+
// ---------------------------------------------------------------------------
|
|
93
|
+
|
|
94
|
+
async function publish(argv) {
|
|
95
|
+
const { source, awsProfile, token } = resolveSource(argv);
|
|
96
|
+
const {
|
|
97
|
+
profile: profileName,
|
|
98
|
+
path: publishPath,
|
|
99
|
+
force,
|
|
100
|
+
manifest: manifestArg,
|
|
101
|
+
} = argv;
|
|
102
|
+
|
|
103
|
+
// ── Load manifest ─────────────────────────────────────────────────────────
|
|
104
|
+
const manifestPath = path.resolve(manifestArg || './wyvrn.json');
|
|
105
|
+
const manifest = await readManifest(manifestPath);
|
|
106
|
+
if (!manifest) {
|
|
107
|
+
console.error(`[wyvrn] Error: Could not read manifest at ${manifestPath}`);
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const { name, version } = manifest;
|
|
112
|
+
if (!name || !version) {
|
|
113
|
+
console.error('[wyvrn] Error: Manifest must have "name" and "version" fields');
|
|
114
|
+
process.exit(1);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const srcDir = path.resolve(publishPath || '.');
|
|
118
|
+
if (!fs.existsSync(srcDir)) {
|
|
119
|
+
console.error(`[wyvrn] Error: Publish path does not exist: ${srcDir}`);
|
|
120
|
+
process.exit(1);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// ── Resolve provider ──────────────────────────────────────────────────────
|
|
124
|
+
let provider;
|
|
125
|
+
try {
|
|
126
|
+
provider = getProvider(source);
|
|
127
|
+
} catch (err) {
|
|
128
|
+
console.error(`[wyvrn] Error: ${err.message}`);
|
|
129
|
+
process.exit(1);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// ── Load build profile ────────────────────────────────────────────────────
|
|
133
|
+
const config = readConfig();
|
|
134
|
+
const activeProfileName = profileName ?? config.defaultProfile ?? 'default';
|
|
135
|
+
const { profile: buildProfile, fromFile } = loadProfile(activeProfileName);
|
|
136
|
+
const profileHash = hashProfile(buildProfile);
|
|
137
|
+
|
|
138
|
+
console.log(
|
|
139
|
+
`[wyvrn] Publishing ${name}@${version}\n` +
|
|
140
|
+
`[wyvrn] Profile : "${activeProfileName}"${fromFile ? '' : ' (auto-detected — save with `wyvrnpm configure profile detect`)'}\n` +
|
|
141
|
+
`[wyvrn] ${buildProfile.os}/${buildProfile.arch} ` +
|
|
142
|
+
`${buildProfile.compiler} ${buildProfile['compiler.version']} ` +
|
|
143
|
+
`C++${buildProfile['compiler.cppstd']}` +
|
|
144
|
+
(buildProfile['compiler.runtime'] ? ` [${buildProfile['compiler.runtime']}]` : '') + '\n' +
|
|
145
|
+
`[wyvrn] Profile hash: ${profileHash}\n` +
|
|
146
|
+
`[wyvrn] Provider : ${provider.constructor.providerName}`,
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
// ── Check v2 existence ────────────────────────────────────────────────────
|
|
150
|
+
const v2AlreadyExists = await provider.v2Exists({ source, name, version, profileHash, awsProfile, token });
|
|
151
|
+
if (v2AlreadyExists) {
|
|
152
|
+
if (force) {
|
|
153
|
+
console.warn(`[wyvrn] Warning: ${name}@${version} [${profileHash}] already exists — overwriting (--force)`);
|
|
154
|
+
} else {
|
|
155
|
+
console.error(
|
|
156
|
+
`[wyvrn] Error: ${name}@${version} [${profileHash}] already exists.\n` +
|
|
157
|
+
' Bump the version, use a different profile, or pass --force to overwrite.',
|
|
158
|
+
);
|
|
159
|
+
process.exit(1);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// ── Read locked dependency versions from wyvrn.lock ──────────────────────
|
|
164
|
+
const lockPath = path.join(path.dirname(manifestPath), 'wyvrn.lock');
|
|
165
|
+
const lockedDependencies = {};
|
|
166
|
+
if (fs.existsSync(lockPath)) {
|
|
167
|
+
try {
|
|
168
|
+
const lock = JSON.parse(fs.readFileSync(lockPath, 'utf8'));
|
|
169
|
+
for (const [pkgName, entry] of Object.entries(lock.packages ?? {})) {
|
|
170
|
+
const ver = typeof entry === 'string' ? entry : entry.version;
|
|
171
|
+
if (ver) lockedDependencies[pkgName] = ver;
|
|
172
|
+
}
|
|
173
|
+
console.log(`[wyvrn] Lock file : ${Object.keys(lockedDependencies).length} pinned package(s)`);
|
|
174
|
+
} catch {
|
|
175
|
+
console.warn('[wyvrn] Warning: could not read wyvrn.lock — dependency versions will be published as-is from wyvrn.json');
|
|
176
|
+
}
|
|
177
|
+
} else {
|
|
178
|
+
console.warn('[wyvrn] Warning: no wyvrn.lock found — run `wyvrnpm install` before publishing to pin dependency versions');
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// ── Git metadata ──────────────────────────────────────────────────────────
|
|
182
|
+
const gitSha = getGitSha(srcDir);
|
|
183
|
+
const gitRepo = getGitRepo(srcDir);
|
|
184
|
+
if (gitSha) console.log(`[wyvrn] Git commit : ${gitSha}`);
|
|
185
|
+
if (gitRepo) console.log(`[wyvrn] Git remote : ${gitRepo}`);
|
|
186
|
+
|
|
187
|
+
// ── .wyvrnignore ──────────────────────────────────────────────────────────
|
|
188
|
+
const ignoreFile = path.join(srcDir, '.wyvrnignore');
|
|
189
|
+
const ignorePatterns = loadIgnorePatterns(ignoreFile);
|
|
190
|
+
const ignoreRe = ignorePatterns.map(patternToRegex);
|
|
191
|
+
if (ignorePatterns.length > 0) {
|
|
192
|
+
console.log(`[wyvrn] Loaded ${ignorePatterns.length} pattern(s) from .wyvrnignore`);
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// ── Build zip ─────────────────────────────────────────────────────────────
|
|
196
|
+
const tmpZipPath = path.join(os.tmpdir(), `wyvrnpm-${name}-${version}-${Date.now()}.zip`);
|
|
197
|
+
try {
|
|
198
|
+
console.log(`[wyvrn] Zipping ${srcDir} ...`);
|
|
199
|
+
const zip = new AdmZip();
|
|
200
|
+
addFolderFiltered(zip, srcDir, srcDir, ignoreRe);
|
|
201
|
+
zip.writeZip(tmpZipPath);
|
|
202
|
+
|
|
203
|
+
const contentSha256 = sha256Of(tmpZipPath);
|
|
204
|
+
console.log(`[wyvrn] Content SHA256 : ${contentSha256}`);
|
|
205
|
+
|
|
206
|
+
// ── v2 publish ────────────────────────────────────────────────────────
|
|
207
|
+
console.log('[wyvrn] Publishing (v2) ...');
|
|
208
|
+
await provider.v2Publish(
|
|
209
|
+
{ manifest: manifestPath, zip: tmpZipPath },
|
|
210
|
+
{
|
|
211
|
+
source,
|
|
212
|
+
name,
|
|
213
|
+
version,
|
|
214
|
+
profileHash,
|
|
215
|
+
// buildSettings stored in metadata for debugging — NOT wyvrn.json
|
|
216
|
+
buildSettings: buildProfile,
|
|
217
|
+
contentSha256,
|
|
218
|
+
gitSha,
|
|
219
|
+
gitRepo,
|
|
220
|
+
lockedDependencies,
|
|
221
|
+
awsProfile,
|
|
222
|
+
token,
|
|
223
|
+
},
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
console.log(`[wyvrn] Successfully published ${name}@${version} [${profileHash}] to ${source}`);
|
|
227
|
+
} finally {
|
|
228
|
+
if (fs.existsSync(tmpZipPath)) fs.unlinkSync(tmpZipPath);
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
module.exports = publish;
|