Skip to content

Commit 02980b9

Browse files
committed
--overwrite for nodejsapp
1 parent 7e2513c commit 02980b9

File tree

8 files changed

+258
-23
lines changed

8 files changed

+258
-23
lines changed

__tests__/api/BundleContent/Bundle.test.ts

Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,152 @@ describe("Bundle01", () => {
338338
expect(err).toBeDefined();
339339
expect(err.message).toMatchSnapshot();
340340
});
341+
it("should tolerate absence of .nodejsapp directory", () => {
342+
343+
// Create a Bundle
344+
const bund = new Bundle("__tests__/__resources__/ExampleBundle03", false, false);
345+
346+
// Mocks for the manifest
347+
const spy1 = jest.spyOn(fs, "existsSync").mockImplementationOnce(() => ( true ));
348+
const spy2 = jest.spyOn(fs, "accessSync").mockImplementationOnce(() => ( true ));
349+
const spy3 = jest.spyOn(fs, "existsSync").mockImplementationOnce(() => ( false ));
350+
// Mocks for the Nodejsapp - startscript exists
351+
const spy4 = jest.spyOn(fs, "existsSync").mockImplementationOnce(() => ( true ));
352+
// Mocks for the Nodejsapp - dir exists
353+
const spy5 = jest.spyOn(fs, "existsSync").mockImplementationOnce(() => ( false ));
354+
355+
bund.addNodejsappDefinition("NodeName", "__tests__/__resources__/ExampleBundle03/Artefact1", 1000);
356+
bund.prepareForSave();
357+
358+
// Check the output as JSON
359+
expect(JSON.stringify(bund.getManifest())).toMatchSnapshot();
360+
});
361+
it("should detect unwritable .nodejsapp directory", () => {
362+
363+
// Create a Bundle
364+
const bund = new Bundle("__tests__/__resources__/ExampleBundle03", false, false);
365+
366+
// Mocks for the manifest
367+
const spy1 = jest.spyOn(fs, "existsSync").mockImplementationOnce(() => ( true ));
368+
const spy2 = jest.spyOn(fs, "accessSync").mockImplementationOnce(() => ( true ));
369+
const spy3 = jest.spyOn(fs, "existsSync").mockImplementationOnce(() => ( false ));
370+
// Mocks for the Nodejsapp - startscript exists
371+
const spy4 = jest.spyOn(fs, "existsSync").mockImplementationOnce(() => ( true ));
372+
// Mocks for the Nodejsapp - dir exists
373+
const spy5 = jest.spyOn(fs, "existsSync").mockImplementationOnce(() => ( false ));
374+
// Mocks for the Nodejsapp - dir not writable
375+
const spy6 = jest.spyOn(fs, "accessSync").mockImplementationOnce(() => { throw new Error("Wibble"); });
376+
377+
bund.addNodejsappDefinition("NodeName", "__tests__/__resources__/ExampleBundle03/Artefact1", 1000);
378+
let err: Error;
379+
try {
380+
bund.prepareForSave();
381+
}
382+
catch (error) {
383+
err = error;
384+
}
385+
386+
expect(err).toBeDefined();
387+
expect(err.message).toMatchSnapshot();
388+
});
389+
it("should complain if existing .nodejsapp file isn't overwritable", () => {
390+
391+
// Create a Bundle
392+
const bund = new Bundle("__tests__/__resources__/ExampleBundle03", false, false);
393+
394+
// Mocks for the manifest
395+
const spy1 = jest.spyOn(fs, "existsSync").mockImplementationOnce(() => ( true ));
396+
const spy2 = jest.spyOn(fs, "accessSync").mockImplementationOnce(() => ( true ));
397+
const spy3 = jest.spyOn(fs, "existsSync").mockImplementationOnce(() => ( false ));
398+
// Mocks for the Nodejsapp - startscript exists
399+
const spy4 = jest.spyOn(fs, "existsSync").mockImplementationOnce(() => ( true ));
400+
// Mocks for the Nodejsapp - dir exists
401+
const spy5 = jest.spyOn(fs, "existsSync").mockImplementationOnce(() => ( true ));
402+
// Mocks for the Nodejsapp - dir writable
403+
const spy6 = jest.spyOn(fs, "accessSync").mockImplementationOnce(() => ( true ));
404+
// Mocks for the Nodejsapp - .nodejsapp exists
405+
const spy7 = jest.spyOn(fs, "existsSync").mockImplementationOnce(() => ( true ));
406+
407+
bund.addNodejsappDefinition("NodeName", "__tests__/__resources__/ExampleBundle03/Artefact1", 1000);
408+
let err: Error;
409+
try {
410+
bund.prepareForSave();
411+
}
412+
catch (error) {
413+
err = error;
414+
}
415+
416+
expect(err).toBeDefined();
417+
expect(err.message).toMatchSnapshot();
418+
});
419+
it("should complain if no write permission to existing .nodejsapp", () => {
420+
421+
// Create a Bundle
422+
const bund = new Bundle("__tests__/__resources__/ExampleBundle03", false, true);
423+
424+
// Mocks for the manifest
425+
const spy1 = jest.spyOn(fs, "existsSync").mockImplementationOnce(() => ( true ));
426+
const spy2 = jest.spyOn(fs, "accessSync").mockImplementationOnce(() => ( true ));
427+
const spy3 = jest.spyOn(fs, "existsSync").mockImplementationOnce(() => ( false ));
428+
// Mocks for the Nodejsapp - startscript exists
429+
const spy4 = jest.spyOn(fs, "existsSync").mockImplementationOnce(() => ( true ));
430+
// Mocks for the Nodejsapp - dir exists
431+
const spy5 = jest.spyOn(fs, "existsSync").mockImplementationOnce(() => ( true ));
432+
// Mocks for the Nodejsapp - dir writable
433+
const spy6 = jest.spyOn(fs, "accessSync").mockImplementationOnce(() => ( true ));
434+
// Mocks for the Nodejsapp - .nodejsapp exists
435+
const spy7 = jest.spyOn(fs, "existsSync").mockImplementationOnce(() => ( true ));
436+
// Mocks for the Nodejsapp - .nodejsapp not writable
437+
const spy8 = jest.spyOn(fs, "accessSync").mockImplementationOnce(() => { throw new Error("Wibble"); });
438+
439+
bund.addNodejsappDefinition("NodeName", "__tests__/__resources__/ExampleBundle03/Artefact1", 1000);
440+
let err: Error;
441+
try {
442+
bund.prepareForSave();
443+
}
444+
catch (error) {
445+
err = error;
446+
}
447+
448+
expect(err).toBeDefined();
449+
expect(err.message).toMatchSnapshot();
450+
});
451+
it("should complain if no write permission to existing .profile", () => {
452+
453+
// Create a Bundle
454+
const bund = new Bundle("__tests__/__resources__/ExampleBundle03", false, true);
455+
456+
// Mocks for the manifest
457+
const spy1 = jest.spyOn(fs, "existsSync").mockImplementationOnce(() => ( true ));
458+
const spy2 = jest.spyOn(fs, "accessSync").mockImplementationOnce(() => ( true ));
459+
const spy3 = jest.spyOn(fs, "existsSync").mockImplementationOnce(() => ( false ));
460+
// Mocks for the Nodejsapp - startscript exists
461+
const spy4 = jest.spyOn(fs, "existsSync").mockImplementationOnce(() => ( true ));
462+
// Mocks for the Nodejsapp - dir exists
463+
const spy5 = jest.spyOn(fs, "existsSync").mockImplementationOnce(() => ( true ));
464+
// Mocks for the Nodejsapp - dir writable
465+
const spy6 = jest.spyOn(fs, "accessSync").mockImplementationOnce(() => ( true ));
466+
// Mocks for the Nodejsapp - .nodejsapp exists
467+
const spy7 = jest.spyOn(fs, "existsSync").mockImplementationOnce(() => ( true ));
468+
// Mocks for the Nodejsapp - .nodejsapp writable
469+
const spy8 = jest.spyOn(fs, "accessSync").mockImplementationOnce(() => ( true ));
470+
// Mocks for the Nodejsapp - .profile exists
471+
const spy9 = jest.spyOn(fs, "existsSync").mockImplementationOnce(() => ( true ));
472+
// Mocks for the Nodejsapp - .profile writable
473+
const spy10 = jest.spyOn(fs, "accessSync").mockImplementationOnce(() => { throw new Error("Wibble"); });
474+
475+
bund.addNodejsappDefinition("NodeName", "__tests__/__resources__/ExampleBundle03/Artefact1", 1000);
476+
let err: Error;
477+
try {
478+
bund.prepareForSave();
479+
}
480+
catch (error) {
481+
err = error;
482+
}
483+
484+
expect(err).toBeDefined();
485+
expect(err.message).toMatchSnapshot();
486+
});
341487
it("should complain if exceptions are thrown during manifest parsing", () => {
342488

343489
const spy1 = jest.spyOn(JSON, "parse").mockImplementationOnce(() => { throw new Error("Wibble"); });

__tests__/api/BundleContent/Nodejsapp.test.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ describe("NodejsappBundlePart01", () => {
1414
it("Create a NodejsappBundlePart", () => {
1515

1616
// Create a Nodejsapp
17-
const njs = new NodejsappBundlePart("__tests__/__resources__/ExampleBundle03", "NodeName", "__tests__/__resources__/ExampleBundle03/Artefact1", 1000);
17+
const njs = new NodejsappBundlePart("__tests__/__resources__/ExampleBundle03", "NodeName", "__tests__/__resources__/ExampleBundle03/Artefact1", 1000, false);
1818

1919
expect(JSON.stringify(njs.getPart())).toMatchSnapshot();
2020
expect(njs.getPartXML()).toMatchSnapshot();
@@ -24,7 +24,7 @@ describe("NodejsappBundlePart01", () => {
2424
it("Create a NodejsappBundlePart with bad chars", () => {
2525

2626
// Create a Nodejsapp
27-
const njs = new NodejsappBundlePart("__tests__/__resources__/ExampleBundle03", "NodeName is invalid!!!", "__tests__/__resources__/ExampleBundle03/Artefact1", 1000);
27+
const njs = new NodejsappBundlePart("__tests__/__resources__/ExampleBundle03", "NodeName is invalid!!!", "__tests__/__resources__/ExampleBundle03/Artefact1", 1000, false);
2828

2929
expect(JSON.stringify(njs.getPart())).toMatchSnapshot();
3030
expect(njs.getPartXML()).toMatchSnapshot();
@@ -34,7 +34,7 @@ describe("NodejsappBundlePart01", () => {
3434
it("Create a NodejsappBundlePart with long name", () => {
3535

3636
// Create a Nodejsapp
37-
const njs = new NodejsappBundlePart("__tests__/__resources__/ExampleBundle03", "123456789012345678901234567890123", "__tests__/__resources__/ExampleBundle03/Artefact1", 1000);
37+
const njs = new NodejsappBundlePart("__tests__/__resources__/ExampleBundle03", "123456789012345678901234567890123", "__tests__/__resources__/ExampleBundle03/Artefact1", 1000, false);
3838

3939
expect(JSON.stringify(njs.getPart())).toMatchSnapshot();
4040
expect(njs.getPartXML()).toMatchSnapshot();
@@ -45,7 +45,7 @@ describe("NodejsappBundlePart01", () => {
4545

4646
let err: Error;
4747
try {
48-
const njs = new NodejsappBundlePart("__tests__/__resources__/ExampleBundle03", undefined, "", 1000);
48+
const njs = new NodejsappBundlePart("__tests__/__resources__/ExampleBundle03", undefined, "", 1000, false);
4949
}
5050
catch (error) {
5151
err = error;
@@ -58,7 +58,7 @@ describe("NodejsappBundlePart01", () => {
5858

5959
let err: Error;
6060
try {
61-
const njs = new NodejsappBundlePart("__tests__/__resources__/ExampleBundle03", "test", "__tests__/__resources__/ExampleBundle03/Artefact2", 1000);
61+
const njs = new NodejsappBundlePart("__tests__/__resources__/ExampleBundle03", "test", "__tests__/__resources__/ExampleBundle03/Artefact2", 1000, false);
6262
}
6363
catch (error) {
6464
err = error;
@@ -71,7 +71,7 @@ describe("NodejsappBundlePart01", () => {
7171

7272
let err: Error;
7373
try {
74-
const njs = new NodejsappBundlePart("__tests__/__resources__/ExampleBundle03", "test", undefined, 1000);
74+
const njs = new NodejsappBundlePart("__tests__/__resources__/ExampleBundle03", "test", undefined, 1000, false);
7575
}
7676
catch (error) {
7777
err = error;
@@ -84,7 +84,7 @@ describe("NodejsappBundlePart01", () => {
8484

8585
let err: Error;
8686
try {
87-
const njs = new NodejsappBundlePart("__tests__/__resources__/ExampleBundle03", "test", "__tests__/__resources__/ExampleBundle03/Artefact1", -1);
87+
const njs = new NodejsappBundlePart("__tests__/__resources__/ExampleBundle03", "test", "__tests__/__resources__/ExampleBundle03/Artefact1", -1, false);
8888
}
8989
catch (error) {
9090
err = error;
@@ -97,7 +97,7 @@ describe("NodejsappBundlePart01", () => {
9797

9898
let err: Error;
9999
try {
100-
const njs = new NodejsappBundlePart("__tests__/__resources__/ExampleBundle03", "test", "__tests__/__resources__/ExampleBundle03/Artefact1", 1000.1);
100+
const njs = new NodejsappBundlePart("__tests__/__resources__/ExampleBundle03", "test", "__tests__/__resources__/ExampleBundle03/Artefact1", 1000.1, false);
101101
}
102102
catch (error) {
103103
err = error;
@@ -109,7 +109,7 @@ describe("NodejsappBundlePart01", () => {
109109
it("Create a NodejsappBundlePart with missing port number", () => {
110110

111111
// Create a Nodejsapp
112-
const njs = new NodejsappBundlePart("__tests__/__resources__/ExampleBundle03", "NodeName", "__tests__/__resources__/ExampleBundle03/Artefact1", undefined);
112+
const njs = new NodejsappBundlePart("__tests__/__resources__/ExampleBundle03", "NodeName", "__tests__/__resources__/ExampleBundle03/Artefact1", undefined, false);
113113

114114
// Check the bundle part as JSON
115115
expect(JSON.stringify(njs.getPart())).toMatchSnapshot();
@@ -121,7 +121,7 @@ describe("NodejsappBundlePart01", () => {
121121

122122
let err: Error;
123123
try {
124-
const njs = new NodejsappBundlePart("__tests__/__resources__/ExampleBundle03", undefined, "__tests__/__resources__/ExampleBundle03/Artefact1", 1000);
124+
const njs = new NodejsappBundlePart("__tests__/__resources__/ExampleBundle03", undefined, "__tests__/__resources__/ExampleBundle03/Artefact1", 1000, false);
125125
}
126126
catch (error) {
127127
err = error;

__tests__/api/BundleDeploy/BundleDeployer.test.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,15 @@ describe("BundleDeployer01", () => {
207207
"// MSGCLASS=X,TIME=NOLIMIT";
208208
await testDeployJCL(parms);
209209
});
210+
it("should support multi-line jobcard with embedded new lines", async () => {
211+
212+
let parms: IHandlerParameters;
213+
parms = DEFAULT_PARAMTERS;
214+
setCommonParmsForDeployTests(parms);
215+
parms.arguments.resgroup = "12345678";
216+
parms.arguments.jobcard = "//DFHDPLOY JOB DFHDPLOY,CLASS=A,\\n// MSGCLASS=X,TIME=NOLIMIT";
217+
await testDeployJCL(parms);
218+
});
210219
it("should support long line jobcard", async () => {
211220

212221
let parms: IHandlerParameters;

__tests__/api/BundleDeploy/__snapshots__/BundleDeployer.test.ts.snap

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,26 @@ DEPLOY BUNDLE(12345678)
430430
"
431431
`;
432432

433+
exports[`BundleDeployer01 should support multi-line jobcard with embedded new lines 1`] = `
434+
"//DFHDPLOY JOB DFHDPLOY,CLASS=A,
435+
// MSGCLASS=X,TIME=NOLIMIT
436+
//DFHDPLOY EXEC PGM=DFHDPLOY,REGION=100M
437+
//STEPLIB DD DISP=SHR,DSN=12345678901234567890123456789012345.SDFHLOAD
438+
// DD DISP=SHR,DSN=abcde12345abcde12345abcde12345abcde.SEYUAUTH
439+
//SYSTSPRT DD SYSOUT=*
440+
//SYSIN DD *
441+
*
442+
SET CICSPLEX(12345678);
443+
*
444+
DEPLOY BUNDLE(12345678)
445+
BUNDLEDIR(1234567890)
446+
SCOPE(12345678)
447+
STATE(ENABLED)
448+
RESGROUP(12345678);
449+
/*
450+
"
451+
`;
452+
433453
exports[`BundleDeployer01 should support really long line jobcard 1`] = `
434454
"//DFHDPLOY JOB DFHDPLOY,CLASS=A,MSGCLASS=X,TIME=NOLIMIT,
435455
// NOEL=ABCDEFGHIJKMNOPQRSTUVWXYZ,

src/api/BundleContent/Bundle.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,7 @@ export class Bundle {
130130
*/
131131
public addNodejsappDefinition(name: string, startscript: string, port: number) {
132132
this.preparedToSave = false;
133-
const nj = new NodejsappBundlePart(this.bundleDirectory, name, startscript, port);
133+
const nj = new NodejsappBundlePart(this.bundleDirectory, name, startscript, port, this.overwrite);
134134
this.manifest.addDefinition(nj);
135135
this.definedParts.push(nj);
136136
}
@@ -147,10 +147,11 @@ export class Bundle {
147147
* @memberof Bundle
148148
*/
149149
public prepareForSave() {
150+
this.manifest.prepareForSave();
151+
150152
this.definedParts.forEach( (value) => {
151153
value.prepareForSave();
152154
});
153-
this.manifest.prepareForSave();
154155

155156
this.preparedToSave = true;
156157
}

src/api/BundleContent/BundlePart.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,31 @@ export class BundlePart {
146146
return file;
147147
}
148148

149+
/**
150+
* Perform checks to determine whether it is likely that a file can be written.
151+
*
152+
* @param {string} filename - The file to check
153+
* @returns {boolean}
154+
* @throws ImperativeError
155+
* @memberof BundlePart
156+
*/
157+
protected ensureFileSaveable(filename: string, overwrite: boolean): boolean {
158+
// Does the file already exist?
159+
if (this.fs.existsSync(filename) && overwrite === false) {
160+
throw new Error("File " + filename + " already exists. Specify --overwrite to replace it.");
161+
}
162+
163+
// Do we have write permission to the file?
164+
try {
165+
this.fs.accessSync(filename, this.fs.constants.W_OK);
166+
}
167+
catch (err) {
168+
throw new Error("cics-deploy requires write permission to: " + filename);
169+
}
170+
171+
return true;
172+
}
173+
149174
private validateName() {
150175
if (this.partData.name === undefined) {
151176
throw new Error(this.simpleType + " name is not set.");

src/api/BundleContent/Manifest.ts

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -131,16 +131,18 @@ export class Manifest {
131131
}
132132

133133
// Does a manifest file already exist?
134-
if (this.fs.existsSync(this.manifestFile) && this.overwrite === false) {
135-
throw new Error("A bundle manifest file already exists. Specify --overwrite to replace it, or --merge to merge changes into it.");
136-
}
134+
if (this.fs.existsSync(this.manifestFile)) {
135+
if (this.overwrite === false) {
136+
throw new Error("A bundle manifest file already exists. Specify --overwrite to replace it, or --merge to merge changes into it.");
137+
}
137138

138-
// Do we have write permission to the manifest?
139-
try {
140-
this.fs.accessSync(this.manifestFile, this.fs.constants.W_OK);
141-
}
142-
catch (err) {
143-
throw new Error("cics-deploy requires write permission to: " + this.manifestFile);
139+
// Do we have write permission to the manifest?
140+
try {
141+
this.fs.accessSync(this.manifestFile, this.fs.constants.W_OK);
142+
}
143+
catch (err) {
144+
throw new Error("cics-deploy requires write permission to: " + this.manifestFile);
145+
}
144146
}
145147
}
146148

0 commit comments

Comments
 (0)