obsidian-plugin-config 1.6.17 → 1.7.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.
- package/.editorconfig +9 -14
- package/.prettierrc +3 -12
- package/bin/obsidian-inject.js +1 -1
- package/docs/INTERACTIVE_INJECTION.md +4 -4
- package/docs/LLM-GUIDE.md +12 -2
- package/eslint.config.mts +63 -64
- package/package.json +3 -3
- package/scripts/acp.ts +52 -56
- package/scripts/build-npm.ts +161 -169
- package/scripts/inject-core.ts +835 -823
- package/scripts/inject-path.ts +151 -165
- package/scripts/inject-prompt.ts +89 -91
- package/scripts/update-version-config.ts +121 -89
- package/scripts/utils.ts +112 -112
- package/templates/.editorconfig +11 -14
- package/templates/.prettierrc +3 -12
- package/templates/env.template +12 -9
- package/templates/eslint.config.mts +1 -1
- package/templates/package.json +2 -3
- package/templates/scripts/acp.ts +50 -74
- package/templates/scripts/constants.ts +26 -0
- package/templates/scripts/env.ts +94 -0
- package/templates/scripts/esbuild.config.ts +134 -287
- package/templates/scripts/release.ts +92 -87
- package/templates/scripts/reload.ts +46 -0
- package/templates/scripts/typingsPlugin.ts +26 -0
- package/templates/scripts/update-version.ts +120 -123
- package/templates/scripts/utils.ts +234 -134
- package/templates/tsconfig.json +2 -2
- package/tsconfig.json +1 -1
|
@@ -1,310 +1,157 @@
|
|
|
1
1
|
import esbuild from 'esbuild';
|
|
2
2
|
import process from 'process';
|
|
3
|
-
import builtins from 'builtin-modules';
|
|
4
3
|
import { config } from 'dotenv';
|
|
5
4
|
import path from 'path';
|
|
6
|
-
import { readFileSync } from 'fs';
|
|
7
5
|
import { rm } from 'fs/promises';
|
|
8
|
-
import
|
|
6
|
+
import { type Interface } from 'readline';
|
|
7
|
+
import { obsidianTypingsPlugin } from './typingsPlugin.ts';
|
|
8
|
+
import { EXTERNAL_DEPS, BANNER } from './constants.ts';
|
|
9
9
|
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
10
|
+
type Manifest,
|
|
11
|
+
checkManifest,
|
|
12
|
+
validateEnvironment,
|
|
13
|
+
getBuildPath
|
|
14
|
+
} from './env.ts';
|
|
15
|
+
import {
|
|
16
|
+
copyFilesToTargetDir,
|
|
17
|
+
createReadlineInterface,
|
|
18
|
+
isValidPath,
|
|
19
|
+
removeMainCss
|
|
20
|
+
} from './utils.ts';
|
|
21
|
+
import { reloadObsidian } from './reload.ts';
|
|
16
22
|
|
|
17
23
|
// Determine the plugin directory (where the script is called from)
|
|
18
24
|
const pluginDir = process.cwd();
|
|
19
25
|
|
|
20
26
|
// Create readline interface for prompts
|
|
21
|
-
const rl = createReadlineInterface();
|
|
22
|
-
|
|
23
|
-
async function promptForVaultPath(envKey: string): Promise<string> {
|
|
24
|
-
const vaultType = envKey === 'REAL_VAULT' ? 'real' : 'test';
|
|
25
|
-
const usage =
|
|
26
|
-
envKey === 'REAL_VAULT'
|
|
27
|
-
? 'for final plugin installation'
|
|
28
|
-
: 'for development and testing';
|
|
29
|
-
|
|
30
|
-
console.log(`❓ ${envKey} path is required ${usage}`);
|
|
31
|
-
const path = await askQuestion(
|
|
32
|
-
`📝 Enter your ${vaultType} vault path (or Ctrl+C to cancel): `,
|
|
33
|
-
rl
|
|
34
|
-
);
|
|
35
|
-
|
|
36
|
-
if (!path) {
|
|
37
|
-
console.log('❌ No path provided, exiting...');
|
|
38
|
-
process.exit(1);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
return path;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
async function updateEnvFile(envKey: string, vaultPath: string): Promise<void> {
|
|
45
|
-
const envPath = path.join(pluginDir, '.env');
|
|
46
|
-
let envContent = '';
|
|
47
|
-
|
|
48
|
-
// Read existing .env if it exists
|
|
49
|
-
try {
|
|
50
|
-
envContent = readFileSync(envPath, 'utf8');
|
|
51
|
-
} catch {
|
|
52
|
-
// File doesn't exist, start with empty content
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// Update or add the variable
|
|
56
|
-
const regex = new RegExp(`^${envKey}=.*$`, 'm');
|
|
57
|
-
const newLine = `${envKey}=${vaultPath}`;
|
|
58
|
-
|
|
59
|
-
if (regex.test(envContent)) {
|
|
60
|
-
envContent = envContent.replace(regex, newLine);
|
|
61
|
-
} else {
|
|
62
|
-
envContent += envContent.endsWith('\n') ? '' : '\n';
|
|
63
|
-
envContent += newLine + '\n';
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// Write back to .env
|
|
67
|
-
await import('fs').then((fs) => fs.writeFileSync(envPath, envContent));
|
|
68
|
-
console.log(`✅ Updated ${envKey} in .env file`);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
function validateVaultPath(vaultPath: string): boolean {
|
|
72
|
-
// Check if the path contains .obsidian directory
|
|
73
|
-
const obsidianPath = path.join(vaultPath, '.obsidian');
|
|
74
|
-
const pluginsPath = path.join(vaultPath, '.obsidian', 'plugins');
|
|
75
|
-
|
|
76
|
-
return fs.existsSync(obsidianPath) && fs.existsSync(pluginsPath);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function getVaultPath(vaultPath: string): string {
|
|
80
|
-
// Validate that this is a proper vault path
|
|
81
|
-
if (!validateVaultPath(vaultPath)) {
|
|
82
|
-
console.error(`❌ Invalid vault path: ${vaultPath}`);
|
|
83
|
-
console.error(` The path must contain a .obsidian/plugins directory`);
|
|
84
|
-
console.error(` Please enter a valid Obsidian vault path`);
|
|
85
|
-
process.exit(1);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// Check if the path already contains the plugins directory path
|
|
89
|
-
const pluginsPath = path.join('.obsidian', 'plugins');
|
|
90
|
-
if (vaultPath.includes(pluginsPath)) {
|
|
91
|
-
return path.join(vaultPath, manifest.id);
|
|
92
|
-
} else {
|
|
93
|
-
return path.join(vaultPath, '.obsidian', 'plugins', manifest.id);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
const manifestPath = path.join(pluginDir, 'manifest.json');
|
|
97
|
-
|
|
98
|
-
// Check if manifest exists (for plugin-config itself, it might not exist)
|
|
99
|
-
if (!fs.existsSync(manifestPath)) {
|
|
100
|
-
console.log(
|
|
101
|
-
'⚠️ No manifest.json found - this script is designed for Obsidian plugins'
|
|
102
|
-
);
|
|
103
|
-
console.log(" If you're building plugin-config itself, use 'tsc' instead");
|
|
104
|
-
process.exit(0);
|
|
105
|
-
}
|
|
27
|
+
const rl: Interface = createReadlineInterface();
|
|
106
28
|
|
|
107
|
-
const manifest =
|
|
29
|
+
const manifest: Manifest = checkManifest(pluginDir);
|
|
108
30
|
|
|
109
31
|
config();
|
|
110
32
|
|
|
111
|
-
const EXTERNAL_DEPS = [
|
|
112
|
-
'obsidian',
|
|
113
|
-
'electron',
|
|
114
|
-
'@codemirror/autocomplete',
|
|
115
|
-
'@codemirror/collab',
|
|
116
|
-
'@codemirror/commands',
|
|
117
|
-
'@codemirror/language',
|
|
118
|
-
'@codemirror/lint',
|
|
119
|
-
'@codemirror/search',
|
|
120
|
-
'@codemirror/state',
|
|
121
|
-
'@codemirror/view',
|
|
122
|
-
'@lezer/common',
|
|
123
|
-
'@lezer/highlight',
|
|
124
|
-
'@lezer/lr',
|
|
125
|
-
...builtins
|
|
126
|
-
];
|
|
127
|
-
|
|
128
|
-
const BANNER = `/*
|
|
129
|
-
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
|
|
130
|
-
if you want to view the source, please visit the github repository of this plugin
|
|
131
|
-
*/`;
|
|
132
|
-
|
|
133
|
-
async function validateEnvironment(): Promise<void> {
|
|
134
|
-
const srcMainPath = path.join(pluginDir, 'src/main.ts');
|
|
135
|
-
if (!(await isValidPath(srcMainPath))) {
|
|
136
|
-
throw new Error(
|
|
137
|
-
'Invalid path for src/main.ts. main.ts must be in the src directory'
|
|
138
|
-
);
|
|
139
|
-
}
|
|
140
|
-
if (!(await isValidPath(manifestPath))) {
|
|
141
|
-
throw new Error('Invalid path for manifest.json');
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
async function getBuildPath(isProd: boolean): Promise<string> {
|
|
146
|
-
// Check if we're already inside an Obsidian plugins folder
|
|
147
|
-
const pluginsPath = path.join('.obsidian', 'plugins');
|
|
148
|
-
const isInPluginsFolder = pluginDir.includes(pluginsPath);
|
|
149
|
-
|
|
150
|
-
if (isInPluginsFolder) {
|
|
151
|
-
console.log('ℹ️ Building in Obsidian plugins folder (in-place development)');
|
|
152
|
-
return pluginDir;
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
// External development: check for vault paths
|
|
156
|
-
const useRealVault = process.argv.includes('-r') || process.argv.includes('real');
|
|
157
|
-
|
|
158
|
-
// If production build without redirection, return plugin directory
|
|
159
|
-
if (isProd && !useRealVault) {
|
|
160
|
-
return pluginDir;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
// Determine which path to use
|
|
164
|
-
const envKey = useRealVault ? 'REAL_VAULT' : 'TEST_VAULT';
|
|
165
|
-
const vaultPath = process.env[envKey]?.trim();
|
|
166
|
-
|
|
167
|
-
// If empty or undefined, prompt for vault path
|
|
168
|
-
if (!vaultPath || vaultPath.startsWith('/path/to/your/')) {
|
|
169
|
-
const newPath = await promptForVaultPath(envKey);
|
|
170
|
-
await updateEnvFile(envKey, newPath);
|
|
171
|
-
config();
|
|
172
|
-
return getVaultPath(newPath);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
return getVaultPath(vaultPath);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
33
|
async function createBuildContext(
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
34
|
+
buildPath: string,
|
|
35
|
+
isProd: boolean,
|
|
36
|
+
entryPoints: string[],
|
|
37
|
+
hasSass: boolean
|
|
183
38
|
): Promise<esbuild.BuildContext> {
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
plugins
|
|
259
|
-
});
|
|
39
|
+
const plugins = [
|
|
40
|
+
// Add SASS plugin if SCSS files are detected
|
|
41
|
+
...(hasSass
|
|
42
|
+
? [
|
|
43
|
+
await (async () => {
|
|
44
|
+
try {
|
|
45
|
+
// @ts-expect-error - esbuild-sass-plugin is installed during injection
|
|
46
|
+
const { sassPlugin } = await import('esbuild-sass-plugin');
|
|
47
|
+
return sassPlugin({
|
|
48
|
+
syntax: 'scss',
|
|
49
|
+
style: 'expanded'
|
|
50
|
+
});
|
|
51
|
+
} catch (error) {
|
|
52
|
+
console.warn(
|
|
53
|
+
'⚠️ esbuild-sass-plugin not found. Install it with: yarn add -D esbuild-sass-plugin'
|
|
54
|
+
);
|
|
55
|
+
throw error;
|
|
56
|
+
}
|
|
57
|
+
})(),
|
|
58
|
+
{
|
|
59
|
+
name: 'remove-main-css',
|
|
60
|
+
setup(build: esbuild.PluginBuild): void {
|
|
61
|
+
build.onEnd(async (result) => {
|
|
62
|
+
if (result.errors.length === 0) {
|
|
63
|
+
await removeMainCss(buildPath);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
]
|
|
69
|
+
: []),
|
|
70
|
+
{
|
|
71
|
+
name: 'copy-to-plugins-folder',
|
|
72
|
+
setup: (build: esbuild.PluginBuild): void => {
|
|
73
|
+
build.onEnd(async () => {
|
|
74
|
+
// if real or build
|
|
75
|
+
if (isProd) {
|
|
76
|
+
if (process.argv.includes('-r') || process.argv.includes('real')) {
|
|
77
|
+
await copyFilesToTargetDir(buildPath);
|
|
78
|
+
console.log(`Successfully installed in ${buildPath}`);
|
|
79
|
+
await reloadObsidian();
|
|
80
|
+
} else {
|
|
81
|
+
const folderToRemove = path.join(buildPath, '_.._');
|
|
82
|
+
if (await isValidPath(folderToRemove)) {
|
|
83
|
+
await rm(folderToRemove, { recursive: true });
|
|
84
|
+
}
|
|
85
|
+
console.log('Build done in initial folder');
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
// if watch (dev)
|
|
89
|
+
else {
|
|
90
|
+
await copyFilesToTargetDir(buildPath);
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
];
|
|
96
|
+
|
|
97
|
+
return await esbuild.context({
|
|
98
|
+
banner: { js: BANNER },
|
|
99
|
+
minify: isProd,
|
|
100
|
+
entryPoints,
|
|
101
|
+
bundle: true,
|
|
102
|
+
external: EXTERNAL_DEPS,
|
|
103
|
+
format: 'cjs',
|
|
104
|
+
target: 'esNext',
|
|
105
|
+
platform: 'node',
|
|
106
|
+
logLevel: 'info',
|
|
107
|
+
sourcemap: isProd ? false : 'inline',
|
|
108
|
+
treeShaking: true,
|
|
109
|
+
outdir: buildPath,
|
|
110
|
+
outbase: path.join(pluginDir, 'src'),
|
|
111
|
+
plugins: [obsidianTypingsPlugin(pluginDir), ...plugins]
|
|
112
|
+
});
|
|
260
113
|
}
|
|
261
114
|
|
|
262
115
|
async function main(): Promise<void> {
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
await context.watch();
|
|
302
|
-
}
|
|
303
|
-
} catch (error) {
|
|
304
|
-
console.error('Build failed:', error);
|
|
305
|
-
rl.close();
|
|
306
|
-
process.exit(1);
|
|
307
|
-
}
|
|
116
|
+
try {
|
|
117
|
+
await validateEnvironment(pluginDir);
|
|
118
|
+
const isProd = process.argv[2] === 'production';
|
|
119
|
+
const buildPath = await getBuildPath(pluginDir, manifest, isProd, rl);
|
|
120
|
+
console.log(
|
|
121
|
+
buildPath === pluginDir ? 'Building in initial folder' : `Building in ${buildPath}`
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
// Check for SCSS first, then CSS in src, then in root
|
|
125
|
+
const srcStylesScssPath = path.join(pluginDir, 'src/styles.scss');
|
|
126
|
+
const srcStylesPath = path.join(pluginDir, 'src/styles.css');
|
|
127
|
+
const rootStylesPath = path.join(pluginDir, 'styles.css');
|
|
128
|
+
|
|
129
|
+
const scssExists = await isValidPath(srcStylesScssPath);
|
|
130
|
+
const stylePath = scssExists
|
|
131
|
+
? srcStylesScssPath
|
|
132
|
+
: (await isValidPath(srcStylesPath))
|
|
133
|
+
? srcStylesPath
|
|
134
|
+
: (await isValidPath(rootStylesPath))
|
|
135
|
+
? rootStylesPath
|
|
136
|
+
: '';
|
|
137
|
+
|
|
138
|
+
const mainTsPath = path.join(pluginDir, 'src/main.ts');
|
|
139
|
+
const entryPoints = stylePath ? [mainTsPath, stylePath] : [mainTsPath];
|
|
140
|
+
const context = await createBuildContext(buildPath, isProd, entryPoints, scssExists);
|
|
141
|
+
|
|
142
|
+
if (isProd) {
|
|
143
|
+
await context.rebuild();
|
|
144
|
+
rl.close();
|
|
145
|
+
process.exit(0);
|
|
146
|
+
} else {
|
|
147
|
+
await context.watch();
|
|
148
|
+
}
|
|
149
|
+
} catch (error) {
|
|
150
|
+
console.error('Build failed:', error);
|
|
151
|
+
rl.close();
|
|
152
|
+
process.exit(1);
|
|
153
|
+
}
|
|
308
154
|
}
|
|
309
155
|
|
|
310
156
|
main().catch(console.error);
|
|
157
|
+
|
|
@@ -1,113 +1,118 @@
|
|
|
1
1
|
import { writeFile, stat } from 'fs/promises';
|
|
2
2
|
import { execSync } from 'child_process';
|
|
3
3
|
import dedent from 'dedent';
|
|
4
|
-
import {
|
|
4
|
+
import { join } from 'path';
|
|
5
|
+
import {
|
|
6
|
+
askConfirmation,
|
|
7
|
+
askQuestion,
|
|
8
|
+
createReadlineInterface,
|
|
9
|
+
ensureGitSync
|
|
10
|
+
} from './utils.ts';
|
|
5
11
|
|
|
6
12
|
const rl = createReadlineInterface();
|
|
7
13
|
|
|
8
|
-
const body = '.github
|
|
14
|
+
const body = join('.github', 'workflows', 'release-body.md');
|
|
9
15
|
|
|
10
16
|
async function checkOrCreateFile(filename: string): Promise<void> {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
+
try {
|
|
18
|
+
await stat(filename);
|
|
19
|
+
} catch {
|
|
20
|
+
console.log(`Creating ${filename} because it doesn't exist. Avoid deleting it.`);
|
|
21
|
+
await writeFile(filename, '');
|
|
22
|
+
}
|
|
17
23
|
}
|
|
18
24
|
|
|
19
25
|
async function createReleaseNotesFile(tagMessage: string, tag: string): Promise<void> {
|
|
20
|
-
|
|
21
|
-
|
|
26
|
+
await writeFile(body, tagMessage);
|
|
27
|
+
console.log(`Release notes for tag ${tag} have been written to release-body.md`);
|
|
22
28
|
}
|
|
23
29
|
|
|
24
30
|
async function handleExistingTag(tag: string): Promise<boolean> {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
31
|
+
// Get the existing tag message to show to the user
|
|
32
|
+
let existingMessage = '';
|
|
33
|
+
try {
|
|
34
|
+
existingMessage = execSync(`git tag -l -n999 ${tag}`, {
|
|
35
|
+
encoding: 'utf8'
|
|
36
|
+
}).trim();
|
|
37
|
+
} catch {
|
|
38
|
+
// If we can't get the message, continue anyway
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
let prompt = `Tag ${tag} already exists.`;
|
|
42
|
+
if (existingMessage) {
|
|
43
|
+
prompt += `\n\nExisting tag message:\n${existingMessage}\n`;
|
|
44
|
+
}
|
|
45
|
+
prompt += `\nDo you want to replace it?`;
|
|
46
|
+
|
|
47
|
+
const confirmed = await askConfirmation(prompt, rl);
|
|
48
|
+
|
|
49
|
+
if (!confirmed) {
|
|
50
|
+
console.log('Operation aborted');
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
execSync(`git tag -d ${tag}`);
|
|
55
|
+
execSync(`git push origin :refs/tags/${tag}`);
|
|
56
|
+
console.log(`Deleted existing tag ${tag} locally and remotely.`);
|
|
57
|
+
return true;
|
|
52
58
|
}
|
|
53
59
|
|
|
54
60
|
async function createTag(): Promise<void> {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
61
|
+
const currentVersion = process.env.npm_package_version;
|
|
62
|
+
const tag = `${currentVersion}`;
|
|
63
|
+
|
|
64
|
+
await checkOrCreateFile(body);
|
|
65
|
+
const exists = execSync('git ls-remote --tags origin')
|
|
66
|
+
.toString()
|
|
67
|
+
.includes(`refs/tags/${tag}`);
|
|
68
|
+
|
|
69
|
+
if (exists && !(await handleExistingTag(tag))) {
|
|
70
|
+
rl.close();
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
await doCommit(currentVersion, tag);
|
|
68
74
|
}
|
|
69
75
|
|
|
70
76
|
async function doCommit(currentVersion: string | undefined, tag: string): Promise<void> {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
);
|
|
77
|
+
const message = await askQuestion(
|
|
78
|
+
`Enter the commit message for version ${currentVersion}: `,
|
|
79
|
+
rl
|
|
80
|
+
);
|
|
81
|
+
rl.close();
|
|
82
|
+
await doNextSteps(message, tag);
|
|
78
83
|
}
|
|
79
84
|
|
|
80
85
|
async function doNextSteps(message: string, tag: string): Promise<void> {
|
|
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
|
-
|
|
86
|
+
const messages = message.split('\\n');
|
|
87
|
+
const toShow = message.replace(/\\n/g, '\n');
|
|
88
|
+
await createReleaseNotesFile(toShow, tag);
|
|
89
|
+
const tagMessage = messages.map((m) => `-m "${m}"`).join(' ');
|
|
90
|
+
|
|
91
|
+
try {
|
|
92
|
+
execSync('git add -A');
|
|
93
|
+
execSync('git commit -m "update tag description"');
|
|
94
|
+
|
|
95
|
+
// Ensure Git is synchronized before pushing
|
|
96
|
+
await ensureGitSync();
|
|
97
|
+
|
|
98
|
+
execSync('git push');
|
|
99
|
+
} catch (error: unknown) {
|
|
100
|
+
console.error('Error:', error instanceof Error ? error.message : String(error));
|
|
101
|
+
}
|
|
102
|
+
try {
|
|
103
|
+
execSync(`git tag -a ${tag} ${tagMessage}`);
|
|
104
|
+
} catch {
|
|
105
|
+
execSync(`git tag -d ${tag}`);
|
|
106
|
+
execSync(`git push origin :refs/tags/${tag}`);
|
|
107
|
+
console.log('Fixed');
|
|
108
|
+
execSync(`git tag -a ${tag} ${tagMessage}`);
|
|
109
|
+
}
|
|
110
|
+
// Ensure Git is synchronized before pushing tag
|
|
111
|
+
await ensureGitSync();
|
|
112
|
+
|
|
113
|
+
execSync(`git push origin ${tag}`);
|
|
114
|
+
console.log(`Release ${tag} pushed to repo.`);
|
|
115
|
+
console.log(dedent`
|
|
111
116
|
with message:
|
|
112
117
|
${toShow}
|
|
113
118
|
`);
|