Skip to content

Commit b0305eb

Browse files
authored
Merge pull request #141 from IBM/feature/makefile_partial_builds
Smaller makefiles for partial builds
2 parents a09a99a + d8cf613 commit b0305eb

File tree

10 files changed

+302
-113
lines changed

10 files changed

+302
-113
lines changed

cli/.vscode/launch.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"cwd": "${workspaceFolder:cli}",
2525
"program": "${workspaceFolder:cli}/dist/index.js",
2626
"sourceMaps": true,
27-
"args": ["-d", "/Users/barry/Repos/ibmi-company_system", "--verbose", "-bf", "make"],
27+
"args": ["-d", "/Users/barry/Repos/ibmi-company_system", "--verbose", "-bf", "make", "-f", "qrpglesrc/employees.pgm.sqlrpgle"],
2828
"preLaunchTask": {
2929
"type": "npm",
3030
"script": "webpack:dev"

cli/src/builders/make/index.ts

Lines changed: 76 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import path from 'path';
33
import { ILEObject, ILEObjectTarget, ImpactedObject, ObjectType, Targets } from '../../targets';
44
import { asPosix, fromCl, getFiles, toCl } from '../../utils';
55
import { warningOut } from '../../cli';
6-
import { name } from '../../../webpack.config';
6+
import { name, target } from '../../../webpack.config';
77
import { FolderOptions, getFolderOptions } from './folderSettings';
88
import { readAllRules } from './customRules';
99
import { CompileData, CommandParameters, getTrueBasename } from '../environment';
@@ -20,8 +20,19 @@ interface Step {
2020
command: string;
2121
}
2222

23+
/**
24+
* parents: this property controls the all target. It will include all the parents of partial build objects.
25+
* partial: if this property is true, the makefile will only include targets for the partial build objects (and optionally their parents)
26+
*/
27+
type PartialOptions = { partial: boolean, parents: boolean };
28+
29+
interface PartialTargets {
30+
partial: ILEObject[];
31+
children?: ILEObject[];
32+
}
33+
2334
export class MakeProject {
24-
private noChildren: boolean = false;
35+
private partialOptions: PartialOptions = { partial: false, parents: false };
2536
private settings: iProject = new iProject();
2637
private projectActions: ProjectActions;
2738
private actionsEnabled: boolean = false;
@@ -32,8 +43,8 @@ export class MakeProject {
3243
this.projectActions = new ProjectActions(this.targets, this.rfs);
3344
}
3445

35-
public setNoChildrenInBuild(noChildren: boolean) {
36-
this.noChildren = noChildren;
46+
public setPartialOptions(options: PartialOptions) {
47+
this.partialOptions = options;
3748
}
3849

3950
public useActions() {
@@ -188,7 +199,7 @@ export class MakeProject {
188199
``,
189200
...this.generateTargets(specificObjects),
190201
``,
191-
...this.generateGenericRules()
202+
...this.generateGenericRules(specificObjects)
192203
];
193204
}
194205

@@ -214,30 +225,56 @@ export class MakeProject {
214225
];
215226
}
216227

217-
public generateTargets(partialBuild?: ILEObject[]): string[] {
218-
let lines = [];
228+
/**
229+
* Used to return the objects required to do a partial build.
230+
* If `partial` is true, it will return the object and all objects depending on it recursively.
231+
* If `parents` is true, it will return all parent objects of the partial build objects, and their children/
232+
*/
233+
private getPartialTargets(partialBuild?: ILEObject[]): PartialTargets|undefined {
234+
if (partialBuild === undefined) {
235+
return;
236+
}
219237

220-
// A 'partial build' means we only want to build specific objects
221-
// and we also want to build their parents too. We update `partialBuild`
238+
let allParents: ILEObject[]|undefined;
239+
240+
// we also want to build their parents too. We update `partialBuild`
222241
// to include all the parents of the specific objects.
223-
if (partialBuild) {
242+
if (this.partialOptions.parents) {
243+
allParents = [];
224244
const impacts = partialBuild.map(o => this.targets.getImpactFor(o));
225245

226-
let allAffected: ILEObject[] = [];
227-
228246
const addImpact = (impactedObj: ImpactedObject) => {
229-
if (!allAffected.some(o => o.systemName === impactedObj.ileObject.systemName && o.type === impactedObj.ileObject.type)) {
230-
allAffected.push(impactedObj.ileObject);
247+
if (!allParents.some(o => o.systemName === impactedObj.ileObject.systemName && o.type === impactedObj.ileObject.type)) {
248+
allParents.push(impactedObj.ileObject);
231249
}
232250

233251
impactedObj.children.forEach(child => addImpact(child));
234252
}
235253

236254
impacts.forEach(impact => addImpact(impact));
237255

238-
partialBuild = allAffected;
256+
partialBuild = allParents;
257+
}
258+
259+
let allChildren: ILEObject[]|undefined = this.partialOptions.partial ? this.targets.getRequiredObjects(partialBuild) : undefined;
260+
261+
return {
262+
partial: partialBuild,
263+
children: allChildren
239264
}
265+
}
266+
267+
public generateTargets(partialBuild?: ILEObject[]): string[] {
268+
let lines = [];
240269

270+
// A 'partial build' means we only want to build specific objects
271+
const buildObjects = this.getPartialTargets(partialBuild);
272+
273+
if (buildObjects) {
274+
partialBuild = buildObjects.partial;
275+
}
276+
277+
// If we are in partial mode, we only want to generate targets for the specific objects
241278
const all = partialBuild || [
242279
...(this.targets.binderRequired() ? [this.targets.getBinderTarget()] : []),
243280
...this.targets.getTargetsOfType(`PGM`),
@@ -251,7 +288,19 @@ export class MakeProject {
251288
)
252289
}
253290

254-
if (!this.noChildren) {
291+
if (buildObjects && buildObjects.children) {
292+
// If we don't want the children to get built, we only generate the targets for the specific objects
293+
for (const obj of buildObjects.children) {
294+
if (obj.reference) continue; // Skip references
295+
296+
const target = this.targets.getTarget(obj);
297+
if (target && target.deps && target.deps.length > 0) {
298+
lines.push(
299+
`$(PREPATH)/${target.systemName}.${target.type}: ${target.deps.filter(d => d.reference !== true).map(dep => `$(PREPATH)/${dep.systemName}.${dep.type}`).join(` `)}`
300+
)
301+
}
302+
}
303+
} else {
255304
// If we don't want the children to get built, we don't generate the dependency targets
256305
for (const target of this.targets.getTargets()) {
257306
if (target && target.deps.length > 0) {
@@ -275,9 +324,15 @@ export class MakeProject {
275324
return lines;
276325
}
277326

278-
public generateGenericRules(): string[] {
327+
public generateGenericRules(partialBuild?: ILEObject[]): string[] {
279328
let lines = [];
280329

330+
const buildObjects = this.getPartialTargets(partialBuild);
331+
332+
if (buildObjects) {
333+
partialBuild = buildObjects.partial;
334+
}
335+
281336
for (const entry of Object.entries(this.settings.compiles)) {
282337
let [type, data] = entry;
283338

@@ -320,6 +375,10 @@ export class MakeProject {
320375
if (objects.length > 0) {
321376
for (const ileObject of objects) {
322377
if (ileObject.reference) continue;
378+
379+
if (buildObjects && buildObjects.children && !buildObjects.children.some(o => o.systemName === ileObject.systemName && o.type === ileObject.type)) {
380+
continue; // Skip this object
381+
}
323382

324383
// This is used when your object really has source
325384

cli/src/cli.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ export let cliSettings = {
88
withActions: false,
99
fixIncludes: false,
1010
autoRename: false,
11-
fileList: false,
12-
lookupFiles: [] as string[],
11+
lookupFiles: undefined as string[]|undefined,
1312
userBranch: ``,
14-
makeFileNoChildren: false,
13+
makefileIsPartial: false,
14+
makefileWithParents: false,
1515
assumeSourcesArePrograms: false,
1616
};
1717

cli/src/index.ts

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,17 @@ async function main() {
6464

6565
case '-nc':
6666
case '--no-children':
67-
cliSettings.makeFileNoChildren = true;
67+
warningOut(`--no-children is deprecated and is default when doing partial builds.`);
68+
break;
69+
70+
case `-ip`:
71+
case `--is-partial`:
72+
cliSettings.makefileIsPartial = true;
73+
break;
74+
75+
case `-wp`:
76+
case `--with-parents`:
77+
cliSettings.makefileWithParents = true;
6878
break;
6979

7080
case '-ap':
@@ -79,7 +89,7 @@ async function main() {
7989
case `-f`:
8090
case `--files`:
8191
case `-l`:
82-
cliSettings.fileList = true;
92+
cliSettings.lookupFiles = [];
8393
break;
8494

8595
case `-h`:
@@ -127,15 +137,19 @@ async function main() {
127137
console.log(``);
128138
console.log(`Options specific to '-bf make':`);
129139
console.log(``);
130-
console.log(`\t-nc`);
131-
console.log(`\t--no-children\tUsed with '-bf make' and won't include children of`);
132-
console.log(`\t\t\tobjects in the makefile. Useful in conjuction with '-f'.`);
140+
console.log(`\t-ip`);
141+
console.log(`\t--is-partial\tWill only generate targets that are needed for`);
142+
console.log(`\t\t\tthe objects that are being built.`);
143+
console.log(``);
144+
console.log(`\t-wp`);
145+
console.log(`\t--with-parents\tUsed with '-bf make' and will add parents of`);
146+
console.log(`\t\t\tobjects being partially built to the makefile.`);
133147
console.log(``);
134148
process.exit(0);
135149
break;
136150

137151
default:
138-
if (cliSettings.fileList) {
152+
if (cliSettings.lookupFiles !== undefined) {
139153
cliSettings.lookupFiles.push(parms[i]);
140154
}
141155
break;
@@ -232,9 +246,12 @@ async function main() {
232246

233247
await makeProj.setupSettings();
234248

235-
makeProj.setNoChildrenInBuild(cliSettings.makeFileNoChildren);
249+
makeProj.setPartialOptions({
250+
partial: cliSettings.makefileIsPartial,
251+
parents: cliSettings.makefileWithParents
252+
})
236253

237-
let specificObjects: ILEObject[] | undefined = cliSettings.fileList ? cliSettings.lookupFiles.map(f => targets.getResolvedObject(path.join(cwd, f))).filter(o => o) : undefined;
254+
let specificObjects: ILEObject[] | undefined = cliSettings.lookupFiles ? cliSettings.lookupFiles.map(f => targets.getResolvedObject(path.join(cwd, f))).filter(o => o) : undefined;
238255
writeFileSync(path.join(cwd, `makefile`), makeProj.getMakefile(specificObjects).join(`\n`));
239256

240257
break;

0 commit comments

Comments
 (0)