-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathversion.ts
More file actions
146 lines (119 loc) · 4.45 KB
/
version.ts
File metadata and controls
146 lines (119 loc) · 4.45 KB
1
2
3
4
5
6
7
8
9
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
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
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
import { LaunchQLPackage } from '@launchql/core';
import { Logger } from '@launchql/logger';
import { errors } from '@launchql/types';
import { CLIOptions, Inquirerer, Question } from 'inquirerer';
import { extractFirst } from '../utils/argv';
import { selectPackage } from '../utils/module-utils';
import * as path from 'path';
import * as fs from 'fs';
const semver = require('semver');
const log = new Logger('version');
const versionUsageText = `
LaunchQL Version Command:
lql version [OPTIONS]
Bump package version and create corresponding tag.
Options:
--help, -h Show this help message
--package <name> Target specific package
--cwd <directory> Working directory (default: current directory)
Examples:
lql version Prompt for version bump type
lql version --package mypackage Version specific package
`;
export default async (
argv: Partial<Record<string, any>>,
prompter: Inquirerer,
_options: CLIOptions
) => {
if (argv.help || argv.h) {
console.log(versionUsageText);
process.exit(0);
}
const { newArgv } = extractFirst(argv);
const cwdResult = await prompter.prompt(newArgv, [
{
type: 'text',
name: 'cwd',
message: 'Working directory',
required: false,
default: process.cwd(),
useDefault: true
}
]);
const cwd = (cwdResult as any).cwd || process.cwd();
const pkg = new LaunchQLPackage(cwd);
let packageName: string | undefined;
if (argv.package) {
packageName = argv.package as string;
log.info(`Using specified package: ${packageName}`);
}
else if (pkg.isInModule()) {
packageName = pkg.getModuleName();
log.info(`Using current module: ${packageName}`);
}
else if (pkg.isInWorkspace()) {
packageName = await selectPackage(newArgv, prompter, cwd, 'version', log);
if (!packageName) {
throw new Error('No package selected. Cannot version without specifying a target package.');
}
} else {
throw new Error('This command must be run inside a LaunchQL workspace or module.');
}
const versionAnswer = await prompter.prompt(newArgv, [
{
type: 'autocomplete',
name: 'bumpType',
message: 'Select version bump type',
options: ['patch', 'minor', 'major'],
required: true
}
]) as any;
const bumpType = versionAnswer.bumpType;
try {
if (argv.package || !pkg.isInModule()) {
const moduleMap = pkg.getModuleMap();
const module = moduleMap[packageName];
if (!module) {
throw errors.MODULE_NOT_FOUND({ name: packageName });
}
const workspacePath = pkg.getWorkspacePath()!;
const absoluteModulePath = path.resolve(workspacePath, module.path);
const originalCwd = process.cwd();
process.chdir(absoluteModulePath);
try {
const modulePkg = new LaunchQLPackage(absoluteModulePath);
const newVersion = await updatePackageVersion(absoluteModulePath, bumpType);
modulePkg.addTag(`v${newVersion}`, undefined, `Version bump: ${bumpType}`);
log.info(`Successfully bumped ${packageName} to version ${newVersion} and added tag v${newVersion}`);
} finally {
process.chdir(originalCwd);
}
} else {
const newVersion = await updatePackageVersion(pkg.getModulePath()!, bumpType);
pkg.addTag(`v${newVersion}`, undefined, `Version bump: ${bumpType}`);
log.info(`Successfully bumped to version ${newVersion} and added tag v${newVersion}`);
}
} catch (error) {
log.error(`Failed to version package: ${error instanceof Error ? error.message : String(error)}`);
throw error;
}
return newArgv;
};
async function updatePackageVersion(modulePath: string, bumpType: 'major' | 'minor' | 'patch'): Promise<string> {
const pkgJsonPath = path.join(modulePath, 'package.json');
if (!fs.existsSync(pkgJsonPath)) {
throw new Error(`No package.json found at module path: ${modulePath}`);
}
const pkgData = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));
const currentVersion = pkgData.version;
if (!currentVersion) {
throw new Error('No version field found in package.json');
}
const newVersion = semver.inc(currentVersion, bumpType);
if (!newVersion) {
throw new Error(`Failed to calculate new ${bumpType} version from ${currentVersion}`);
}
pkgData.version = newVersion;
fs.writeFileSync(pkgJsonPath, JSON.stringify(pkgData, null, 2) + '\n');
return newVersion;
}