Skip to content

Commit 687a37d

Browse files
authored
Merge pull request #157 from IBM/feature/with_parents_children
Add `-wpc` (with parents' children) parameter
2 parents e047cc3 + 04d36d4 commit 687a37d

File tree

11 files changed

+193
-60
lines changed

11 files changed

+193
-60
lines changed

cli/src/builders/make/index.ts

Lines changed: 45 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,19 @@ interface Step {
2424
* parents: this property controls the all target. It will include all the parents of partial build objects.
2525
* partial: if this property is true, the makefile will only include targets for the partial build objects (and optionally their parents)
2626
*/
27-
type PartialOptions = { partial: boolean, parents: boolean };
27+
type PartialOptions = {
28+
parents?: boolean,
29+
withChildren?: boolean,
30+
parentsChildren?: boolean
31+
};
2832

2933
interface PartialTargets {
30-
partial: ILEObject[];
31-
children?: ILEObject[];
34+
targets: ILEObject[];
35+
children: ILEObject[];
3236
}
3337

3438
export class MakeProject {
35-
private partialOptions: PartialOptions = { partial: false, parents: false };
39+
private partialOptions: PartialOptions|undefined
3640
private settings: iProject = new iProject();
3741
private projectActions: ProjectActions;
3842
private actionsEnabled: boolean = false;
@@ -235,32 +239,37 @@ export class MakeProject {
235239
return;
236240
}
237241

238-
let allParents: ILEObject[]|undefined;
242+
let children: ILEObject[] = [];
239243

240244
// we also want to build their parents too. We update `partialBuild`
241245
// to include all the parents of the specific objects.
242-
if (this.partialOptions.parents) {
243-
allParents = [];
244-
const impacts = partialBuild.map(o => this.targets.getImpactFor(o));
245-
246-
const addImpact = (impactedObj: ImpactedObject) => {
247-
if (!allParents.some(o => o.systemName === impactedObj.ileObject.systemName && o.type === impactedObj.ileObject.type)) {
248-
allParents.push(impactedObj.ileObject);
249-
}
246+
247+
const allParents: ILEObject[] = [];
248+
const impacts = partialBuild.map(o => this.targets.getImpactFor(o));
250249

251-
impactedObj.children.forEach(child => addImpact(child));
250+
const addImpact = (impactedObj: ImpactedObject) => {
251+
if (!allParents.some(o => o.systemName === impactedObj.ileObject.systemName && o.type === impactedObj.ileObject.type)) {
252+
allParents.push(impactedObj.ileObject);
252253
}
253254

254-
impacts.forEach(impact => addImpact(impact));
255+
impactedObj.children.forEach(child => addImpact(child));
256+
}
255257

256-
partialBuild = allParents;
258+
impacts.forEach(impact => addImpact(impact));
259+
260+
if (this.partialOptions.parentsChildren) {
261+
children = this.targets.getRequiredChildren(allParents);
262+
} else if (this.partialOptions.withChildren) {
263+
children = this.targets.getRequiredChildren(partialBuild);
257264
}
258265

259-
let allChildren: ILEObject[]|undefined = this.partialOptions.partial ? this.targets.getRequiredObjects(partialBuild) : undefined;
266+
if (this.partialOptions.parents) {
267+
partialBuild = allParents;
268+
}
260269

261270
return {
262-
partial: partialBuild,
263-
children: allChildren
271+
targets: partialBuild,
272+
children: children
264273
}
265274
}
266275

@@ -271,7 +280,7 @@ export class MakeProject {
271280
const buildObjects = this.getPartialTargets(partialBuild);
272281

273282
if (buildObjects) {
274-
partialBuild = buildObjects.partial;
283+
partialBuild = buildObjects.targets;
275284
}
276285

277286
// If we are in partial mode, we only want to generate targets for the specific objects
@@ -288,9 +297,19 @@ export class MakeProject {
288297
)
289298
}
290299

291-
if (buildObjects && buildObjects.children) {
300+
let allTargetObjects: ILEObject[]|undefined = undefined;
301+
if (this.partialOptions && buildObjects) {
302+
allTargetObjects = [];
303+
if (this.partialOptions.parentsChildren) {
304+
allTargetObjects = partialBuild.concat(buildObjects.children || []).filter((t, i, self) => self.indexOf(t) === i);
305+
} else if (this.partialOptions.withChildren) {
306+
allTargetObjects = buildObjects.children.filter((t, i, self) => self.indexOf(t) === i);
307+
}
308+
}
309+
310+
if (allTargetObjects) {
292311
// 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) {
312+
for (const obj of allTargetObjects) {
294313
if (obj.reference) continue; // Skip references
295314

296315
const target = this.targets.getTarget(obj);
@@ -324,13 +343,13 @@ export class MakeProject {
324343
return lines;
325344
}
326345

327-
public generateGenericRules(partialBuild?: ILEObject[]): string[] {
346+
public generateGenericRules(buildFor?: ILEObject[]): string[] {
328347
let lines = [];
329348

330-
const buildObjects = this.getPartialTargets(partialBuild);
349+
const buildObjects = this.getPartialTargets(buildFor);
331350

332351
if (buildObjects) {
333-
partialBuild = buildObjects.partial;
352+
buildFor = buildObjects.children.concat(buildObjects.targets);
334353
}
335354

336355
for (const entry of Object.entries(this.settings.compiles)) {
@@ -376,7 +395,7 @@ export class MakeProject {
376395
for (const ileObject of objects) {
377396
if (ileObject.reference) continue;
378397

379-
if (buildObjects && buildObjects.children && !buildObjects.children.some(o => o.systemName === ileObject.systemName && o.type === ileObject.type)) {
398+
if (buildFor && !buildFor.some(o => o.systemName === ileObject.systemName && o.type === ileObject.type)) {
380399
continue; // Skip this object
381400
}
382401

cli/src/cli.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,9 @@ export let cliSettings = {
1010
autoRename: false,
1111
lookupFiles: undefined as string[]|undefined,
1212
userBranch: ``,
13-
makefileIsPartial: false,
13+
makefileWithChildren: true,
1414
makefileWithParents: false,
15+
makefileWithParentsChildren: false,
1516
assumeSourcesArePrograms: false,
1617
};
1718

cli/src/index.ts

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -64,19 +64,19 @@ async function main() {
6464

6565
case '-nc':
6666
case '--no-children':
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;
67+
cliSettings.makefileWithChildren = false;
7368
break;
7469

7570
case `-wp`:
7671
case `--with-parents`:
7772
cliSettings.makefileWithParents = true;
7873
break;
7974

75+
case `-wpc`:
76+
case `--with-parents-children`:
77+
cliSettings.makefileWithParentsChildren = true;
78+
break;
79+
8080
case '-ap':
8181
case '--assume-programs':
8282
cliSettings.assumeSourcesArePrograms = true;
@@ -137,12 +137,16 @@ async function main() {
137137
console.log(``);
138138
console.log(`Options specific to '-bf make':`);
139139
console.log(``);
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(``);
144140
console.log(`\t-wp`);
145-
console.log(`\t--with-parents\tUsed with '-bf make' and will add parents of`);
141+
console.log(`\t--with-parents\tWill add parents of`);
142+
console.log(`\t\t\tobjects being partially built to the makefile.`);
143+
console.log(``);
144+
console.log(`\t-wpc`);
145+
console.log(`\t--with-parents-children\tWill add children of parents`);
146+
console.log(`\t\t\t\tto makefile.`);
147+
console.log(``);
148+
console.log(`\t-nc`);
149+
console.log(`\t--no-children\tWill not add children of`);
146150
console.log(`\t\t\tobjects being partially built to the makefile.`);
147151
console.log(``);
148152
process.exit(0);
@@ -246,10 +250,13 @@ async function main() {
246250

247251
await makeProj.setupSettings();
248252

249-
makeProj.setPartialOptions({
250-
partial: cliSettings.makefileIsPartial,
251-
parents: cliSettings.makefileWithParents
252-
})
253+
if (cliSettings.lookupFiles) {
254+
makeProj.setPartialOptions({
255+
withChildren: cliSettings.makefileWithChildren,
256+
parents: cliSettings.makefileWithParents,
257+
parentsChildren: cliSettings.makefileWithParentsChildren
258+
});
259+
}
253260

254261
let specificObjects: ILEObject[] | undefined = cliSettings.lookupFiles ? cliSettings.lookupFiles.map(f => targets.getResolvedObject(path.join(cwd, f))).filter(o => o) : undefined;
255262
writeFileSync(path.join(cwd, `makefile`), makeProj.getMakefile(specificObjects).join(`\n`));

cli/src/targets/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -762,7 +762,7 @@ export class Targets {
762762
/**
763763
* Returns a list of all the required objects to build this target
764764
*/
765-
public getRequiredObjects(bases: (ILEObject|ILEObjectTarget)[]) {
765+
public getRequiredChildren(bases: (ILEObject|ILEObjectTarget)[]) {
766766
let deps: ILEObject[] = [];
767767

768768
const addDep = (dep: ILEObject|ILEObjectTarget) => {

cli/src/targets/languages/rpgle.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,6 @@ function setupParser(targets: Targets): Parser {
437437
}
438438
} else if (!includeFile.includes(`/`)) {
439439
const parent = path.basename(path.dirname(baseFile));
440-
console.log(parent);
441440
includeFile = `${parent}/${includeFile}`;
442441

443442

cli/test/cs_srvpgm.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ describe(`pseudo tests`, () => {
5454
expect(empdet.deps.find(f => f.systemName === `EMPLOYEE`)).toBeDefined();
5555
expect(empdet.deps.find(f => f.systemName === `DEPARTMENT`)).toBeDefined();
5656

57-
const allRequirements = targets.getRequiredObjects([empdet]);
57+
const allRequirements = targets.getRequiredChildren([empdet]);
5858
expect(allRequirements.length).toBe(3);
5959
expect(allRequirements.find(f => f.systemName === `EMPLOYEE` && f.type === `FILE`)).toBeDefined();
6060
expect(allRequirements.find(f => f.systemName === `DEPARTMENT` && f.type === `FILE`)).toBeDefined();
@@ -69,7 +69,7 @@ describe(`pseudo tests`, () => {
6969
expect(employees.deps.find(f => f.systemName === `EMPS` && f.type === `FILE`)).toBeDefined();
7070
expect(employees.deps.find(f => f.systemName === `EMPLOYEE` && f.type === `FILE`)).toBeDefined();
7171

72-
const requiredForEmployees = targets.getRequiredObjects([employees]);
72+
const requiredForEmployees = targets.getRequiredChildren([employees]);
7373
expect(requiredForEmployees.length).toBe(6);
7474

7575
expect(requiredForEmployees.find(f => f.systemName === `EMPLOYEES` && f.type === `PGM`)).toBeDefined();

cli/test/cs_with_bnddir.test.ts

Lines changed: 108 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ describe(`pseudo tests`, () => {
7575
expect(employees.deps.find(f => f.systemName === `EMPLOYEE` && f.type === `FILE`)).toBeDefined();
7676
});
7777

78-
test('makefile', async () => {
78+
test('makefile', async () => {
7979
const makefile = new MakeProject(targets.getCwd(), targets, fs);
8080
await makefile.setupSettings();
8181

@@ -96,6 +96,113 @@ describe(`pseudo tests`, () => {
9696
expect(steps.length).toBe(8);
9797
});
9898

99+
test('makefile partial (without parents, object has no children)', async () => {
100+
const makefile = new MakeProject(targets.getCwd(), targets, fs);
101+
makefile.setPartialOptions({parents: false});
102+
await makefile.setupSettings();
103+
104+
const resolvedObjects = targets.getResolvedObjects();
105+
106+
const nept = resolvedObjects.find(f => f.systemName === `NEMP` && f.type === `FILE`);
107+
const targetsOut = makefile.generateTargets([nept]).join(`\n`);
108+
console.log(targetsOut);
109+
110+
expect(targetsOut).toContain(`all: .logs .evfevent library $(PREPATH)/NEMP.FILE`);
111+
expect(targetsOut).not.toContain(`$(PREPATH)/NEWEMP.PGM:`);
112+
113+
const rules = makefile.generateGenericRules([nept]).join(`\n`);
114+
console.log(rules);
115+
116+
expect(rules).toContain(`$(PREPATH)/NEMP.FILE:`);
117+
});
118+
119+
test('makefile partial (without parents, object with children)', async () => {
120+
const makefile = new MakeProject(targets.getCwd(), targets, fs);
121+
makefile.setPartialOptions({parents: false, withChildren: true});
122+
await makefile.setupSettings();
123+
124+
const resolvedObjects = targets.getResolvedObjects();
125+
126+
const nept = resolvedObjects.find(f => f.systemName === `NEWEMP` && f.type === `PGM`);
127+
const targetsOut = makefile.generateTargets([nept]).join(`\n`);
128+
console.log(targetsOut);
129+
130+
expect(targetsOut).toContain(`all: .logs .evfevent library $(PREPATH)/NEWEMP.PGM`);
131+
expect(targetsOut).toContain(`$(PREPATH)/NEWEMP.PGM:`);
132+
133+
const rules = makefile.generateGenericRules([nept]).join(`\n`);
134+
console.log(rules);
135+
136+
expect(rules).toContain(`$(PREPATH)/NEMP.FILE:`);
137+
});
138+
139+
test('makefile partial (without parents, object with children, but using withChildren false)', async () => {
140+
const makefile = new MakeProject(targets.getCwd(), targets, fs);
141+
makefile.setPartialOptions({parents: false, withChildren: false});
142+
await makefile.setupSettings();
143+
144+
const resolvedObjects = targets.getResolvedObjects();
145+
146+
const nept = resolvedObjects.find(f => f.systemName === `NEWEMP` && f.type === `PGM`);
147+
const targetsOut = makefile.generateTargets([nept]).join(`\n`);
148+
console.log(targetsOut);
149+
150+
expect(targetsOut).toContain(`all: .logs .evfevent library $(PREPATH)/NEWEMP.PGM`);
151+
expect(targetsOut).not.toContain(`$(PREPATH)/NEWEMP.PGM:`);
152+
153+
const rules = makefile.generateGenericRules([nept]).join(`\n`);
154+
console.log(rules);
155+
156+
expect(rules).not.toContain(`$(PREPATH)/NEMP.FILE:`);
157+
expect(rules).toContain(`$(PREPATH)/NEWEMP.PGM: qrpglesrc/newemp.pgm.sqlrpgle`);
158+
});
159+
160+
test('makefile partial (with parents)', async () => {
161+
const makefile = new MakeProject(targets.getCwd(), targets, fs);
162+
makefile.setPartialOptions({parents: true});
163+
await makefile.setupSettings();
164+
165+
const resolvedObjects = targets.getResolvedObjects();
166+
167+
const nept = resolvedObjects.find(f => f.systemName === `NEMP` && f.type === `FILE`);
168+
const targetsOut = makefile.generateTargets([nept]).join(`\n`);
169+
console.log(targetsOut);
170+
171+
expect(targetsOut).toContain(`all: .logs .evfevent library $(PREPATH)/NEMP.FILE $(PREPATH)/NEWEMP.PGM $(PREPATH)/DEPTS.PGM`);
172+
expect(targetsOut).not.toContain(`$(PREPATH)/NEWEMP.PGM:`);
173+
174+
const rules = makefile.generateGenericRules([nept]).join(`\n`);
175+
console.log(rules);
176+
177+
expect(rules).toContain(`$(PREPATH)/NEMP.FILE:`);
178+
expect(rules).toContain(`$(PREPATH)/NEWEMP.PGM:`);
179+
expect(rules).toContain(`$(PREPATH)/DEPTS.PGM:`);
180+
expect(rules).not.toContain(`$(PREPATH)/EMPLOYEES.PGM:`);
181+
});
182+
183+
test('makefile partial (with parents, and children parent)', async () => {
184+
const makefile = new MakeProject(targets.getCwd(), targets, fs);
185+
makefile.setPartialOptions({parents: true, parentsChildren: true});
186+
await makefile.setupSettings();
187+
188+
const resolvedObjects = targets.getResolvedObjects();
189+
190+
const nept = resolvedObjects.find(f => f.systemName === `NEMP` && f.type === `FILE`);
191+
const targetsOut = makefile.generateTargets([nept]).join(`\n`);
192+
console.log(targetsOut);
193+
194+
expect(targetsOut).toContain(`all: .logs .evfevent library $(PREPATH)/NEMP.FILE $(PREPATH)/NEWEMP.PGM $(PREPATH)/DEPTS.PGM`);
195+
expect(targetsOut).toContain(`$(PREPATH)/NEWEMP.PGM: $(PREPATH)/EMPLOYEE.FILE $(PREPATH)/NEMP.FILE`);
196+
197+
const rules = makefile.generateGenericRules([nept]).join(`\n`);
198+
console.log(rules);
199+
200+
expect(rules).toContain(`$(PREPATH)/NEMP.FILE:`);
201+
expect(rules).toContain(`$(PREPATH)/NEWEMP.PGM:`);
202+
expect(rules).toContain(`$(PREPATH)/DEPTS.PGM:`);
203+
expect(rules).toContain(`$(PREPATH)/EMPLOYEES.PGM:`);
204+
});
205+
99206
test('ibmi-bob rules', () => {
100207
const bobProject = new BobProject(targets);
101208

cli/test/make.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -191,15 +191,15 @@ test('generateTargets (post-resolve)', async () => {
191191
const project = new MakeProject(cwd, targets, new ReadFileSystem());
192192

193193
const srvpgma = targets.getTarget({systemName: `SRVPGMA`, type: `SRVPGM`});
194-
const srvpgmaRequirements = targets.getRequiredObjects([srvpgma]);
194+
const srvpgmaRequirements = targets.getRequiredChildren([srvpgma]);
195195
expect(srvpgmaRequirements.length).toBe(3);
196196
expect(srvpgmaRequirements.map(r => r.systemName)).toEqual([
197197
`FILEB`,
198198
`MODULEB`,
199199
`SRVPGMA`
200200
]);
201201

202-
project.setPartialOptions({partial: true, parents: false});
202+
project.setPartialOptions({withChildren: true});
203203

204204
const targetContent = project.generateTargets([srvpgma]);
205205

0 commit comments

Comments
 (0)