add build-and-install command

This commit is contained in:
Filip Noetzel 2025-09-06 15:07:24 +02:00
parent 0dd7b2ec75
commit ae6d438929
4 changed files with 151 additions and 4 deletions

View file

@ -24,7 +24,7 @@ paths_blocked = [
build = ["npm", "run", "build"]
# Debug build
build_debug = ["npm", "run", "build-debug"]
build_debug = ["npm", "run", "build:debug"]
# Type checking
type_check = ["npm", "run", "type-check"]

146
install-dev.js Normal file
View file

@ -0,0 +1,146 @@
#!/usr/bin/env node
const { execSync } = require('child_process');
const fs = require('fs');
const path = require('path');
function getVCSChangeId() {
try {
// Try Jujutsu first
try {
// Try current working copy @
let changeId = execSync('jj log -r @ --no-graph -T change_id', { encoding: 'utf8' }).trim();
// If working copy is empty, try parent revision @-
if (!changeId || changeId === '' || changeId.includes('(empty)')) {
changeId = execSync('jj log -r @- --no-graph -T change_id', { encoding: 'utf8' }).trim();
}
return changeId;
} catch (jjError) {
// Fall back to Git
const gitHash = execSync('git rev-parse --short HEAD', { encoding: 'utf8' }).trim();
return gitHash;
}
} catch (error) {
console.error('Warning: Could not get VCS change ID:', error.message);
return 'unknown';
}
}
function getLatestCommitMessage() {
try {
// Try Jujutsu first
try {
// Try current working copy @
let message = execSync('jj log -r @ --no-graph -T description', { encoding: 'utf8' }).trim();
// If working copy is empty, try parent revision @-
if (!message || message === '' || message.includes('(empty)')) {
message = execSync('jj log -r @- --no-graph -T description', { encoding: 'utf8' }).trim();
}
const firstLine = message.split('\n')[0];
return firstLine;
} catch (jjError) {
// Fall back to Git
const message = execSync('git log -1 --pretty=%B', { encoding: 'utf8' }).trim();
const firstLine = message.split('\n')[0];
return firstLine;
}
} catch (error) {
console.error('Warning: Could not get commit message:', error.message);
return 'Development build';
}
}
function generateDevManifest() {
try {
// Read the original manifest
const manifestPath = path.join(__dirname, 'manifest.json');
const originalManifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
// Get VCS info
const changeId = getVCSChangeId();
const commitMessage = getLatestCommitMessage();
// Create dev version of manifest
const devManifest = {
...originalManifest,
id: `${originalManifest.id}-dev`,
name: `${originalManifest.name} (Dev)`,
version: `${originalManifest.version}-dev-${changeId.substring(0, 8)}`,
description: `${commitMessage} [dev-${changeId.substring(0, 8)}]`
};
// Return JSON string when used as module, output to stdout when run directly
const jsonString = JSON.stringify(devManifest, null, 2);
if (require.main === module && process.argv.includes('--preview')) {
console.log(jsonString);
process.exit(0);
}
return jsonString;
} catch (error) {
console.error('Error generating dev manifest:', error.message);
process.exit(1);
}
}
function buildAndInstall() {
try {
// Check if VAULT_PATH is provided
const vaultPath = process.env.VAULT_PATH;
if (!vaultPath) {
console.error('Usage: VAULT_PATH="/path/to/vault" npm run build-and-install');
process.exit(1);
}
console.log('📄 Generating dev manifest...');
const devManifestContent = generateDevManifest();
// Read original manifest to get plugin ID
const originalManifest = JSON.parse(fs.readFileSync('manifest.json', 'utf8'));
const pluginId = originalManifest.id;
// Create plugin directory path
const pluginDir = path.join(vaultPath, '.obsidian', 'plugins', pluginId);
console.log('📁 Creating plugin directory...');
fs.mkdirSync(pluginDir, { recursive: true });
console.log('📋 Copying plugin files...');
// Copy main files
const filesToCopy = ['main.js', 'styles.css'];
for (const file of filesToCopy) {
if (fs.existsSync(file)) {
fs.copyFileSync(file, path.join(pluginDir, file));
console.log(` ✓ Copied ${file}`);
}
}
// Write dev manifest
fs.writeFileSync(path.join(pluginDir, 'manifest.json'), devManifestContent);
console.log(' ✓ Copied dev manifest.json');
console.log('✅ Installed dev build successfully!');
console.log(` Plugin directory: ${pluginDir}`);
} catch (error) {
console.error('❌ Build and install failed:', error.message);
process.exit(1);
}
}
// Handle command line arguments
if (require.main === module) {
if (process.argv.includes('--preview')) {
generateDevManifest();
} else {
buildAndInstall();
}
}
module.exports = { buildAndInstall, generateDevManifest, getVCSChangeId, getLatestCommitMessage };

View file

@ -5,8 +5,9 @@
"main": "main.js",
"scripts": {
"build": "node esbuild.config.js",
"build-debug": "LOGGING_ENABLED=true node esbuild.config.js",
"build:debug": "LOGGING_ENABLED=true node esbuild.config.js",
"build:watch": "node esbuild.config.js --watch",
"build-and-install": "npm run build:debug && node install-dev.js",
"type-check": "tsc --noEmit"
},
"keywords": [

View file

@ -6,7 +6,7 @@ import { SymbolSet } from './types';
//
// Logging is controlled via esbuild's sophisticated build-time mechanism:
// - Production builds: `npm run build` (logging disabled)
// - Debug builds: `npm run build-debug` (logging enabled via LOGGING_ENABLED=true)
// - Debug builds: `npm run build:debug` (logging enabled via LOGGING_ENABLED=true)
//
// The value below is replaced at BUILD TIME by esbuild.config.js using the
// `define` feature. This ensures zero runtime overhead for production builds.
@ -14,7 +14,7 @@ import { SymbolSet } from './types';
// ⚠️ NEVER change this to a hardcoded boolean value!
// ⚠️ Use the npm scripts to control logging instead:
// - `npm run build` for production (no logging)
// - `npm run build-debug` for debug builds (with logging)
// - `npm run build:debug` for debug builds (with logging)
//
// The esbuild configuration will replace `process.env.LOGGING_ENABLED` with
// the actual boolean value at compile time, so this becomes a constant in