Skip to content

Commit 9e8a1bb

Browse files
committed
fix(boost-clone): scan patch module dependencies during submodule init
fix #28
1 parent d408338 commit 9e8a1bb

File tree

4 files changed

+184
-148
lines changed

4 files changed

+184
-148
lines changed

boost-clone/dist/index.js

Lines changed: 131 additions & 131 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

boost-clone/dist/index.js.map

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

boost-clone/src/index.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ import { isReleaseTag, estimateTotalModules, decideStrategy, getBoostDepsData }
3333
import { batchInitializeSubmodules, initializeSubmodules, initializeAllSubmodules } from './submodules';
3434
import { readExceptions, readGitmodules, scanBoostDependencies } from './header-scan';
3535
import { getArchiveUrl, downloadAndExtractArchive } from './archive';
36-
import { findGitFeatures, cloneBoostSuperproject, applyPatches } from './git-utils';
36+
import { findGitFeatures, cloneBoostSuperproject, applyPatches, getRepoName } from './git-utils';
3737

3838
// Re-export for external consumers
3939
export { generateCacheKey } from './cache';
@@ -207,6 +207,20 @@ async function executeGitStrategy(
207207
core.endGroup();
208208
}
209209

210+
// Collect patch module names so they can be treated as already-initialized
211+
// and scanned for their own transitive Boost dependencies
212+
const patchNames = new Set<string>();
213+
for (const patch of inputs.patches) {
214+
patchNames.add(getRepoName(patch));
215+
}
216+
217+
// Extend submodulePaths with patch names so the header scanner recognizes
218+
// them as valid modules (they aren't in .gitmodules but exist on disk)
219+
const allValidPaths = new Set(submodulePaths);
220+
for (const name of patchNames) {
221+
allValidPaths.add(`libs/${name}`);
222+
}
223+
210224
// Initialize submodules
211225
// Check if we have precomputed dependencies for this exact release tag
212226
const depsData = getBoostDepsData();
@@ -224,13 +238,13 @@ async function executeGitStrategy(
224238
// or release tags not in our precomputed data, we must use layer-by-layer discovery.
225239
core.startGroup('🔧 Batch Initialize Boost Submodules');
226240
core.info(`Using precomputed dependencies for batch initialization`);
227-
await batchInitializeSubmodules(inputs, estimation.allModules, gitFeatures);
241+
await batchInitializeSubmodules(inputs, estimation.allModules, gitFeatures, patchNames);
228242
core.endGroup();
229243
} else {
230244
// No precomputed data for this branch, use layer-by-layer discovery
231245
core.startGroup('🔧 Initialize Boost Submodules');
232246
core.info(`Using layer-by-layer dependency discovery`);
233-
await initializeSubmodules(inputs, directModules, gitFeatures, exceptions, submodulePaths);
247+
await initializeSubmodules(inputs, directModules, gitFeatures, exceptions, allValidPaths, patchNames);
234248
core.endGroup();
235249
}
236250
}

boost-clone/src/submodules.ts

Lines changed: 33 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,13 @@ export function numberOfCpus(): number {
3434
* @param inputs - User inputs
3535
* @param allModules - Complete set of modules to initialize (including transitive deps)
3636
* @param gitFeatures - Git capabilities
37+
* @param patchNames - Names of patch modules already cloned by applyPatches (excluded from git submodule init)
3738
*/
3839
export async function batchInitializeSubmodules(
3940
inputs: Inputs,
4041
allModules: Set<string>,
41-
gitFeatures: GitFeatures
42+
gitFeatures: GitFeatures,
43+
patchNames: Set<string> = new Set()
4244
): Promise<void> {
4345
function fnlog(msg: string): void {
4446
trace_commands.log(`batchInitializeSubmodules: ${msg}`);
@@ -52,25 +54,32 @@ export async function batchInitializeSubmodules(
5254
const essentialModules = ['config', 'headers'];
5355
const essentialTools = ['tools/boost_install', 'tools/build', 'tools/cmake'];
5456

57+
// Seed patch names so they aren't re-cloned via git submodule update
5558
const allModulesWithEssentials = new Set(allModules);
5659
for (const mod of essentialModules) {
5760
allModulesWithEssentials.add(mod);
5861
}
62+
for (const patchName of patchNames) {
63+
allModulesWithEssentials.add(patchName);
64+
}
5965

60-
// Build list of all submodule paths to initialize
61-
const submodulePaths: string[] = [];
66+
// Build list of all submodule paths to initialize, excluding patches
67+
// (they're already cloned by applyPatches and aren't registered submodules)
68+
const submoduleInitPaths: string[] = [];
6269
for (const mod of allModulesWithEssentials) {
63-
submodulePaths.push(`libs/${mod}`);
70+
if (!patchNames.has(mod)) {
71+
submoduleInitPaths.push(`libs/${mod}`);
72+
}
6473
}
6574
for (const tool of essentialTools) {
66-
submodulePaths.push(tool);
75+
submoduleInitPaths.push(tool);
6776
}
6877

69-
fnlog(`Batch initializing ${submodulePaths.length} submodules`);
78+
fnlog(`Batch initializing ${submoduleInitPaths.length} submodules`);
7079

7180
// Initialize all submodules in one command with multiple paths
7281
// This is more efficient than individual commands
73-
for (const submodulePath of submodulePaths) {
82+
for (const submodulePath of submoduleInitPaths) {
7483
const args = ['submodule', 'update'].concat(gitArgs).concat(['--init', submodulePath]);
7584
await exec.exec(`"${gitFeatures.gitPath}"`, args, { cwd: inputs.boost_dir });
7685
}
@@ -89,8 +98,9 @@ export async function batchInitializeSubmodules(
8998
* @param gitFeatures - Git executable capabilities
9099
* @param exceptions - Map of header exceptions to module names
91100
* @param submodulePaths - Set of valid submodule paths from .gitmodules
101+
* @param patchNames - Names of patch modules already cloned by applyPatches (excluded from git submodule init, seeded into scan loop)
92102
*/
93-
export async function initializeSubmodules(inputs: Inputs, allModules: Set<string>, gitFeatures: GitFeatures, exceptions: Record<string, string>, submodulePaths: Set<string>): Promise<void> {
103+
export async function initializeSubmodules(inputs: Inputs, allModules: Set<string>, gitFeatures: GitFeatures, exceptions: Record<string, string>, submodulePaths: Set<string>, patchNames: Set<string> = new Set()): Promise<void> {
94104
function fnlog(msg: string): void {
95105
trace_commands.log(`initializeSubmodules: ${msg}`);
96106
}
@@ -99,17 +109,26 @@ export async function initializeSubmodules(inputs: Inputs, allModules: Set<strin
99109
const depthArgs = gitFeatures.supportsDepth ? ['--depth', '1'] : [];
100110
const gitArgs = jobsArgs.concat(depthArgs).concat(['-q']);
101111

102-
const allModulesSubPaths = new Set(Array.from(allModules).map((module) => `libs/${module}`));
112+
// Filter patch modules out of submodule init (they're already cloned, not git submodules)
113+
const allModulesSubPaths = new Set(
114+
Array.from(allModules)
115+
.filter((module) => !patchNames.has(module))
116+
.map((module) => `libs/${module}`)
117+
);
103118
const essentialModuleSubPaths = new Set(['libs/config', 'libs/headers', 'tools/boost_install', 'tools/build', 'tools/cmake']);
104119
const initialModuleSubpaths = new Set(Array.from(allModulesSubPaths).concat(Array.from(essentialModuleSubPaths)));
105120
for (const moduleSubPath of initialModuleSubpaths) {
106121
const args = ['submodule', 'update'].concat(gitArgs).concat(['--init', moduleSubPath]);
107122
await exec.exec(`"${gitFeatures.gitPath}"`, args, { cwd: inputs.boost_dir });
108123
}
109124

125+
// Seed patch modules as already initialized so they enter the scan loop
110126
const initializedModules = new Set(allModules);
111127
initializedModules.add('config');
112128
initializedModules.add('headers');
129+
for (const patchName of patchNames) {
130+
initializedModules.add(patchName);
131+
}
113132
const scannedModules = new Set<string>();
114133
const remainingModules = new Set(initializedModules);
115134
while (remainingModules.size > 0) {
@@ -120,9 +139,12 @@ export async function initializeSubmodules(inputs: Inputs, allModules: Set<strin
120139

121140
const module = remainingModules.values().next().value as string;
122141
const modulePath = path.resolve(path.join(inputs.boost_dir, 'libs', module));
142+
// Preserve the user's scan_modules_ignore and add the current module
143+
const ignoreSet = new Set<string>(inputs.scan_modules_ignore);
144+
ignoreSet.add(module);
123145
const moduleInputs: Inputs = {
124146
...inputs,
125-
scan_modules_ignore: new Set<string>([module]),
147+
scan_modules_ignore: ignoreSet,
126148
modules_scan_paths: new Set<string>(),
127149
modules_exclude_paths: new Set<string>(['test', 'tests', 'example', 'examples'])
128150
};
@@ -141,7 +163,7 @@ export async function initializeSubmodules(inputs: Inputs, allModules: Set<strin
141163
} else {
142164
fnlog(`Submodule: ${submodule} has already been scanned`);
143165
}
144-
// Initialize submodule if not initialized yet
166+
// Initialize submodule if not initialized yet (skip patches, they're already cloned)
145167
if (!initializedModules.has(submodule)) {
146168
fnlog(`Initializing submodule: ${submodule}`);
147169
const moduleSubPath = `libs/${submodule}`;

0 commit comments

Comments
 (0)