Skip to content

Commit 9223f46

Browse files
feat(babylonlabs-io-btc-staking-ts): update vendor script
2 parents a1d5eea + 618676d commit 9223f46

File tree

5 files changed

+169
-80
lines changed

5 files changed

+169
-80
lines changed

modules/babylonlabs-io-btc-staking-ts/CHANGELOG.md

Lines changed: 0 additions & 32 deletions
This file was deleted.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
BitGo Fork of https://github.com/babylonlabs-io/btc-staking-ts/tree/v0.4.0-rc.2
1+
BitGo Fork of https://github.com/babylonlabs-io/btc-staking-ts/tree/v1.0.3
Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
1-
export { StakingScriptData, Staking } from './staking';
2-
export type { StakingScripts } from './staking';
3-
export { ObservableStaking, ObservableStakingScriptData } from './staking/observable';
4-
export * from './staking/transactions';
5-
export * from './types';
6-
export * from './utils/btc';
7-
export * from './utils/babylon';
8-
export * from './utils/staking';
9-
export * from './utils/utxo/findInputUTXO';
10-
export * from './utils/utxo/getPsbtInputFields';
11-
export * from './utils/utxo/getScriptType';
12-
export { getBabylonParamByBtcHeight, getBabylonParamByVersion } from './utils/staking/param';
13-
export * from './staking/manager';
1+
export { StakingScriptData, Staking } from "./staking";
2+
export type { StakingScripts } from "./staking";
3+
export {
4+
ObservableStaking,
5+
ObservableStakingScriptData,
6+
} from "./staking/observable";
7+
export * from "./staking/transactions";
8+
export * from "./types";
9+
export * from "./utils/btc";
10+
export * from "./utils/utxo/findInputUTXO";
11+
export * from "./utils/utxo/getPsbtInputFields";
12+
export * from "./utils/utxo/getScriptType";
13+
export {
14+
getBabylonParamByBtcHeight,
15+
getBabylonParamByVersion,
16+
} from "./utils/staking/param";
17+
export * from "./staking/manager";
18+
19+
// BitGo-specific exports
20+
export * from "./utils/babylon";
21+
export * from "./utils/staking";

modules/utxo-staking/tsconfig.json

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,6 @@
1919
},
2020
{
2121
"path": "../utxo-core"
22-
},
23-
{
24-
"path": "../babylonlabs-io-btc-staking-ts"
2522
}
2623
]
2724
}

scripts/vendor-github-repo.ts

Lines changed: 147 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,61 @@
1-
import { ChildProcess, execFile } from 'child_process';
1+
import { execa, ResultPromise } from 'execa';
22
import * as fs from 'fs/promises';
33
import * as tmp from 'tmp';
44
import * as yargs from 'yargs';
55

6-
function isErrorExists(e: NodeJS.ErrnoException): boolean {
7-
return e.code === 'EEXIST';
8-
}
9-
106
type GithubSource = {
117
org: string;
128
repo: string;
139
} & ({ tag: string } | { ref: string });
1410

15-
async function wait(p: ChildProcess): Promise<void> {
16-
p.stderr?.pipe(process.stderr);
17-
p.stdout?.pipe(process.stdout);
18-
return new Promise((resolve, reject) => {
19-
p.on('exit', (code) => {
20-
if (code === 0) {
21-
resolve();
22-
} else {
23-
reject(new Error(`Process exited with code ${code}`));
24-
}
25-
});
11+
export function getDescription(source: GithubSource): string {
12+
if ('tag' in source) {
13+
return `${source.org}/${source.repo}#${source.tag}`;
14+
} else if ('ref' in source) {
15+
return `${source.org}/${source.repo}#${source.ref}`;
16+
} else {
17+
throw new Error('Invalid GithubSource, must have either tag or ref');
18+
}
19+
}
20+
21+
export type VendorConfig = GithubSource & {
22+
targetDir: string;
23+
removeFiles: string[];
24+
/** Git commit range with patches */
25+
cherryPick: {
26+
start: string;
27+
end: string;
28+
} | null;
29+
};
30+
31+
function isErrorExists(e: NodeJS.ErrnoException): boolean {
32+
return e.code === 'EEXIST';
33+
}
34+
35+
async function gitCommit({ path, title, message }: { path: string; title: string; message: string }): Promise<void> {
36+
await execa('git', ['add', path]);
37+
await execa('git', ['commit', path, '-m', title, '-m', message, '--no-verify'], {
38+
stdio: 'inherit',
39+
});
40+
}
41+
42+
async function gitCherryPick(revRange: { start: string; end: string }): Promise<void> {
43+
const range = `${revRange.start}^..${revRange.end}`;
44+
await execa('git', ['cherry-pick', range], {
45+
stdio: 'inherit',
46+
});
47+
}
48+
49+
async function removeDevAndTestFiles(removePaths: string[], targetDir: string): Promise<void> {
50+
for (const path of removePaths) {
51+
console.log(`Removing dev/test file: ${path}`);
52+
const fullPath = `${targetDir}/${path}`;
53+
await fs.rm(fullPath, { recursive: true, force: true });
54+
}
55+
await gitCommit({
56+
path: targetDir,
57+
title: 'chore: remove dev and test files',
58+
message: 'This commit removes unnecessary development and test files from the vendor directory.',
2659
});
2760
}
2861

@@ -58,6 +91,12 @@ async function fetchArchive(lib: GithubSource, outfile: string): Promise<void> {
5891
await fs.writeFile(outfile, Buffer.from(await result.arrayBuffer()));
5992
}
6093

94+
function pipe(cmd: ResultPromise): ResultPromise {
95+
cmd.stdout?.pipe(process.stdout);
96+
cmd.stderr?.pipe(process.stderr);
97+
return cmd;
98+
}
99+
61100
async function extractArchive(archivePath: string, targetDir: string): Promise<void> {
62101
try {
63102
await fs.mkdir(targetDir, { recursive: true });
@@ -66,18 +105,42 @@ async function extractArchive(archivePath: string, targetDir: string): Promise<v
66105
throw e;
67106
}
68107
}
69-
await wait(execFile('tar', ['-C', targetDir, '--strip-components', '1', '-xzf', archivePath]));
108+
await pipe(execa('tar', ['-C', targetDir, '--strip-components', '1', '-xzf', archivePath]));
70109
}
71110

72-
type VendorConfig = GithubSource & {
73-
targetDir: string;
74-
};
75-
76-
async function main(cfgs: VendorConfig[]) {
111+
async function cmdVendor(
112+
cfgs: VendorConfig[],
113+
opts: {
114+
removeFiles: boolean;
115+
cherryPick: boolean;
116+
}
117+
) {
77118
for (const cfg of cfgs) {
119+
const desc = getDescription(cfg);
78120
const archivePath = getArchivePath(cfg);
79121
await fetchArchive(cfg, archivePath);
80122
await extractArchive(archivePath, cfg.targetDir);
123+
await gitCommit({
124+
path: cfg.targetDir,
125+
title: `chore: vendor ${desc}`,
126+
message: `This commit was generated by the vendor-github-repo script.`,
127+
});
128+
129+
if (cfg.removeFiles.length === 0) {
130+
console.log('No files to remove for', cfg.repo);
131+
} else if (opts.removeFiles) {
132+
await removeDevAndTestFiles(cfg.removeFiles, cfg.targetDir);
133+
} else {
134+
console.log(`Skipping removal of dev/test files for ${cfg.repo}, use --removeFiles to enable.`);
135+
}
136+
137+
if (cfg.cherryPick === null) {
138+
console.log(`No patch set defined for ${cfg.repo}, skipping rebase.`);
139+
} else if (opts.removeFiles) {
140+
await gitCherryPick(cfg.cherryPick);
141+
} else {
142+
console.log(`Skipping cherry-pick for ${cfg.repo}, use --cherryPick to enable.`);
143+
}
81144
}
82145
}
83146

@@ -87,24 +150,77 @@ const vendorConfigs: VendorConfig[] = [
87150
repo: 'btc-staking-ts',
88151
tag: 'v1.0.3',
89152
targetDir: 'modules/babylonlabs-io-btc-staking-ts',
153+
removeFiles: [
154+
'.eslintrc.json',
155+
'.github/',
156+
'.husky/',
157+
'.npmrc',
158+
'.nvmrc',
159+
'.prettierignore',
160+
'.prettierrc.json',
161+
'docs/',
162+
'tests/',
163+
'README.md',
164+
],
165+
cherryPick: {
166+
start: '8b8261b8b639d09cbe1223615797c18a2788cd89',
167+
end: '06110dd3e892df326261cd79ead158c28370add7',
168+
},
90169
},
91170
];
92171

172+
function getMatches(name: string, version: string | undefined): VendorConfig[] {
173+
const matches = vendorConfigs.filter((cfg) => {
174+
if (name !== cfg.repo) {
175+
return false;
176+
}
177+
if ('tag' in cfg && version !== undefined) {
178+
return cfg.tag === version;
179+
}
180+
return true;
181+
});
182+
if (matches.length === 0) {
183+
throw new Error(`no such vendor config ${name} version ${version}`);
184+
}
185+
if (matches.length > 1) {
186+
throw new Error(`ambiguous vendor config ${name}`);
187+
}
188+
return matches;
189+
}
190+
191+
const optName = {
192+
type: 'string',
193+
demand: true,
194+
describe: 'Name of the vendor config to use, e.g. btc-staking-ts',
195+
} as const;
196+
197+
const optVersion = {
198+
type: 'string',
199+
describe: 'Version of the vendor config to use, e.g. v2.3.4',
200+
} as const;
201+
93202
yargs
94203
.command({
95204
command: 'vendor',
205+
describe: 'Vendor a github repo',
96206
builder(a) {
97-
return a.options({ name: { type: 'string' } });
207+
return a.options({
208+
name: optName,
209+
pkgVersion: optVersion,
210+
removeFiles: {
211+
type: 'boolean',
212+
default: true,
213+
describe: 'Remove dev/test files after extracting the archive',
214+
},
215+
cherryPick: {
216+
type: 'boolean',
217+
default: true,
218+
describe: 'Apply cherry-pick patches after extracting the archive',
219+
},
220+
});
98221
},
99222
async handler(a) {
100-
const matches = vendorConfigs.filter((cfg) => a.name === cfg.repo);
101-
if (matches.length === 0) {
102-
throw new Error(`no such vendor config ${a.name}`);
103-
}
104-
if (matches.length > 1) {
105-
throw new Error(`ambiguous vendor config ${a.name}`);
106-
}
107-
await main(matches);
223+
await cmdVendor(getMatches(a.name, a.pkgVersion), a);
108224
},
109225
})
110226
.help()

0 commit comments

Comments
 (0)