Skip to content

Commit aaaa79e

Browse files
Merge branch 'master' into help
2 parents 8c8d23b + 8f99fa2 commit aaaa79e

File tree

4 files changed

+159
-18
lines changed

4 files changed

+159
-18
lines changed

__tests__/api/BundleDeploy/BundleDeployer.test.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,44 @@ describe("BundleDeployer01", () => {
200200
"// MSGCLASS=X,TIME=NOLIMIT";
201201
await testDeployJCL(parms);
202202
});
203+
it("should support long line jobcard", async () => {
204+
205+
let parms: IHandlerParameters;
206+
parms = DEFAULT_PARAMTERS;
207+
setCommonParmsForDeployTests(parms);
208+
parms.arguments.resgroup = "12345678";
209+
parms.arguments.jobcard = "//DFHDPLOY JOB DFHDPLOY,CLASS=A,MSGCLASS=X,TIME=NOLIMIT,NOEL=ABCDEFGHIJKMNOPQRSTUVWXYZ";
210+
await testDeployJCL(parms);
211+
});
212+
it("should support really long line jobcard", async () => {
213+
214+
let parms: IHandlerParameters;
215+
parms = DEFAULT_PARAMTERS;
216+
setCommonParmsForDeployTests(parms);
217+
parms.arguments.resgroup = "12345678";
218+
parms.arguments.jobcard = "//DFHDPLOY JOB DFHDPLOY,CLASS=A,MSGCLASS=X,TIME=NOLIMIT,NOEL=ABCDEFGHIJKMNOPQRSTUVWXYZ," +
219+
"72CHARS=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz," +
220+
"ALPHABETIC=ABCDEFGHIJKLMNOPQRSTUVWXYZ";
221+
await testDeployJCL(parms);
222+
});
223+
it("should fail with overlong jobcard", async () => {
224+
225+
let parms: IHandlerParameters;
226+
parms = DEFAULT_PARAMTERS;
227+
setCommonParmsForDeployTests(parms);
228+
parms.arguments.resgroup = "12345678";
229+
parms.arguments.jobcard = "//DFHDPLOY JOB DFHDPLOY,CLASS=A,MSGCLASS=X,TIME=NOLIMIT,NOEL=ABCDEFGHIJKMNOPQRSTUVWXYZ," +
230+
"ALPHABETIC=ABCDEFGHIJKLMNOPQRSTUVWXYZ," +
231+
"73CHARS=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1";
232+
let err: Error;
233+
try {
234+
await testDeployJCL(parms);
235+
} catch (e) {
236+
err = e;
237+
}
238+
expect(err).toBeDefined();
239+
expect(err.message).toMatchSnapshot();
240+
});
203241
it("should support long bundledir", async () => {
204242

205243
let parms: IHandlerParameters;

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

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ exports[`BundleDeployer01 should deploy successfully 1`] = `"DFHRL2012I"`;
3030

3131
exports[`BundleDeployer01 should deploy successfully 2`] = `"DFHDPLOY DEPLOY command successful."`;
3232

33+
exports[`BundleDeployer01 should fail with overlong jobcard 1`] = `"--jobcard parameter section cannot be split into 72 character lines: '// 73CHARS=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1'."`;
34+
3335
exports[`BundleDeployer01 should generate deploy JCL for csdgroup 1`] = `"DFHRL2037I"`;
3436

3537
exports[`BundleDeployer01 should generate deploy JCL for csdgroup 2`] = `
@@ -240,7 +242,38 @@ UNDEPLOY BUNDLE(12345678)
240242
RESGROUP(12345678);
241243
*
242244
DEPLOY BUNDLE(12345678)
243-
BUNDLEDIR(123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345)
245+
BUNDLEDIR(123456789012345678901234567890123456789012345678901234
246+
567890123456789012345678901234567890123456789012345678901234567
247+
890123456789012345678901234567890123456789012345678901234567890
248+
123456789012345678901234567890123456789012345678901234567890123
249+
456789012345)
250+
SCOPE(12345678)
251+
STATE(AVAILABLE)
252+
RESGROUP(12345678);
253+
/*
254+
"
255+
`;
256+
257+
exports[`BundleDeployer01 should support long line jobcard 1`] = `"DFHRL2037I"`;
258+
259+
exports[`BundleDeployer01 should support long line jobcard 2`] = `
260+
"//DFHDPLOY JOB DFHDPLOY,CLASS=A,MSGCLASS=X,TIME=NOLIMIT,
261+
// NOEL=ABCDEFGHIJKMNOPQRSTUVWXYZ
262+
//DFHDPLOY EXEC PGM=DFHDPLOY,REGION=100M
263+
//STEPLIB DD DISP=SHR,DSN=12345678901234567890123456789012345.SDFHLOAD
264+
// DD DISP=SHR,DSN=abcde12345abcde12345abcde12345abcde.SEYUAUTH
265+
//SYSTSPRT DD SYSOUT=*
266+
//SYSIN DD *
267+
*
268+
SET CICSPLEX(12345678);
269+
*
270+
UNDEPLOY BUNDLE(12345678)
271+
SCOPE(12345678)
272+
STATE(DISCARDED)
273+
RESGROUP(12345678);
274+
*
275+
DEPLOY BUNDLE(12345678)
276+
BUNDLEDIR(1234567890)
244277
SCOPE(12345678)
245278
STATE(AVAILABLE)
246279
RESGROUP(12345678);
@@ -275,6 +308,35 @@ DEPLOY BUNDLE(12345678)
275308
"
276309
`;
277310

311+
exports[`BundleDeployer01 should support really long line jobcard 1`] = `"DFHRL2037I"`;
312+
313+
exports[`BundleDeployer01 should support really long line jobcard 2`] = `
314+
"//DFHDPLOY JOB DFHDPLOY,CLASS=A,MSGCLASS=X,TIME=NOLIMIT,
315+
// NOEL=ABCDEFGHIJKMNOPQRSTUVWXYZ,
316+
// 72CHARS=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz,
317+
// ALPHABETIC=ABCDEFGHIJKLMNOPQRSTUVWXYZ
318+
//DFHDPLOY EXEC PGM=DFHDPLOY,REGION=100M
319+
//STEPLIB DD DISP=SHR,DSN=12345678901234567890123456789012345.SDFHLOAD
320+
// DD DISP=SHR,DSN=abcde12345abcde12345abcde12345abcde.SEYUAUTH
321+
//SYSTSPRT DD SYSOUT=*
322+
//SYSIN DD *
323+
*
324+
SET CICSPLEX(12345678);
325+
*
326+
UNDEPLOY BUNDLE(12345678)
327+
SCOPE(12345678)
328+
STATE(DISCARDED)
329+
RESGROUP(12345678);
330+
*
331+
DEPLOY BUNDLE(12345678)
332+
BUNDLEDIR(1234567890)
333+
SCOPE(12345678)
334+
STATE(AVAILABLE)
335+
RESGROUP(12345678);
336+
/*
337+
"
338+
`;
339+
278340
exports[`BundleDeployer01 should tolerate empty output from DFHDPLOY 1`] = `"undefined"`;
279341

280342
exports[`BundleDeployer01 should tolerate empty output from DFHDPLOY 2`] = `"DFHDPLOY did not generate any output. Most recent status update: 'Submitting DFHDPLOY JCL'."`;

src/api/BundleDeploy/BundleDeployer.ts

Lines changed: 28 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,19 @@ export class BundleDeployer {
8686
return this.submitJCL(jcl, session);
8787
}
8888

89+
private wrapLongLineForJCL(lineOfText: string): string {
90+
const MAX_LINE_LEN = 71;
91+
92+
let tempVal = lineOfText;
93+
let returnVal = "";
94+
while (tempVal.length > MAX_LINE_LEN) {
95+
returnVal = returnVal + tempVal.substring(0, MAX_LINE_LEN) + "\n";
96+
tempVal = " " + tempVal.substring(MAX_LINE_LEN);
97+
}
98+
returnVal = returnVal + tempVal;
99+
return returnVal;
100+
}
101+
89102
/**
90103
* Construct the DFHDPLOY DEPLOY BUNDLE JCL.
91104
* @returns {string}
@@ -101,19 +114,19 @@ export class BundleDeployer {
101114
jcl = jcl + "*\n";
102115

103116
// Now generate the deploy statement.
104-
jcl = jcl + "DEPLOY BUNDLE(" + this.params.arguments.name + ")\n" +
105-
" BUNDLEDIR(" + this.params.arguments.bundledir + ")\n" +
106-
" SCOPE(" + this.params.arguments.scope + ")\n" +
107-
" STATE(AVAILABLE)\n";
117+
jcl = jcl + this.wrapLongLineForJCL("DEPLOY BUNDLE(" + this.params.arguments.name + ")\n") +
118+
this.wrapLongLineForJCL(" BUNDLEDIR(" + this.params.arguments.bundledir + ")\n") +
119+
this.wrapLongLineForJCL(" SCOPE(" + this.params.arguments.scope + ")\n") +
120+
this.wrapLongLineForJCL(" STATE(AVAILABLE)\n");
108121

109122
if (this.params.arguments.timeout !== undefined) {
110-
jcl = jcl + " TIMEOUT(" + this.params.arguments.timeout + ")\n";
123+
jcl = jcl + this.wrapLongLineForJCL(" TIMEOUT(" + this.params.arguments.timeout + ")\n");
111124
}
112125
if (this.params.arguments.csdgroup !== undefined) {
113-
jcl = jcl + " CSDGROUP(" + this.params.arguments.csdgroup + ");\n";
126+
jcl = jcl + this.wrapLongLineForJCL(" CSDGROUP(" + this.params.arguments.csdgroup + ");\n");
114127
}
115128
if (this.params.arguments.resgroup !== undefined) {
116-
jcl = jcl + " RESGROUP(" + this.params.arguments.resgroup + ");\n";
129+
jcl = jcl + this.wrapLongLineForJCL(" RESGROUP(" + this.params.arguments.resgroup + ");\n");
117130
}
118131

119132
// finally add a terminator
@@ -147,20 +160,20 @@ export class BundleDeployer {
147160
"//SYSTSPRT DD SYSOUT=*\n" +
148161
"//SYSIN DD *\n" +
149162
"*\n" +
150-
"SET CICSPLEX(" + this.params.arguments.cicsplex + ");\n" +
151-
"*\n" +
152-
"UNDEPLOY BUNDLE(" + this.params.arguments.name + ")\n" +
153-
" SCOPE(" + this.params.arguments.scope + ")\n" +
154-
" STATE(DISCARDED)\n";
163+
this.wrapLongLineForJCL("SET CICSPLEX(" + this.params.arguments.cicsplex + ");\n") +
164+
this.wrapLongLineForJCL("*\n") +
165+
this.wrapLongLineForJCL("UNDEPLOY BUNDLE(" + this.params.arguments.name + ")\n") +
166+
this.wrapLongLineForJCL(" SCOPE(" + this.params.arguments.scope + ")\n") +
167+
this.wrapLongLineForJCL(" STATE(DISCARDED)\n");
155168

156169
if (this.params.arguments.timeout !== undefined) {
157-
jcl = jcl + " TIMEOUT(" + this.params.arguments.timeout + ")\n";
170+
jcl = jcl + this.wrapLongLineForJCL(" TIMEOUT(" + this.params.arguments.timeout + ")\n");
158171
}
159172
if (this.params.arguments.csdgroup !== undefined) {
160-
jcl = jcl + " CSDGROUP(" + this.params.arguments.csdgroup + ");\n";
173+
jcl = jcl + this.wrapLongLineForJCL(" CSDGROUP(" + this.params.arguments.csdgroup + ");\n");
161174
}
162175
if (this.params.arguments.resgroup !== undefined) {
163-
jcl = jcl + " RESGROUP(" + this.params.arguments.resgroup + ");\n";
176+
jcl = jcl + this.wrapLongLineForJCL(" RESGROUP(" + this.params.arguments.resgroup + ");\n");
164177
}
165178

166179
return jcl;

src/api/BundleDeploy/ParmValidator.ts

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,34 @@ export class ParmValidator {
267267
}
268268
}
269269

270+
private static wrapJobcard(params: IHandlerParameters) {
271+
if (params.arguments.jobcard.indexOf("\\n") === -1) {
272+
// if the user hasn't embedded new-line characters into the jobcard
273+
// then we'll have to do that ourselves if the value is too long
274+
let jobcardLocal = params.arguments.jobcard;
275+
let jobcardNew = "";
276+
const MAX_JCL_LINE = 71;
277+
while (jobcardLocal.length > MAX_JCL_LINE) {
278+
const indexOflastComma = jobcardLocal.lastIndexOf(",", MAX_JCL_LINE);
279+
280+
if (indexOflastComma === -1) {
281+
throw new Error("--jobcard parameter section cannot be split into 72 character lines: '" + jobcardLocal + "'.");
282+
}
283+
284+
jobcardNew = jobcardNew + jobcardLocal.substring(0, indexOflastComma + 1) + "\n";
285+
jobcardLocal = "// " + jobcardLocal.substring(indexOflastComma + 1);
286+
}
287+
jobcardNew = jobcardNew + jobcardLocal;
288+
params.arguments.jobcard = jobcardNew;
289+
}
290+
else {
291+
// if the user has embedded new-line characters within the jobcard
292+
// then resolve them, the user has taken responsibility for ensuring
293+
// line breaks are in suitable places.
294+
params.arguments.jobcard = params.arguments.jobcard.replace("\\n", "\n");
295+
}
296+
}
297+
270298
private static validateJobcard(params: IHandlerParameters) {
271299
// jobcard is mandatory
272300
if (params.arguments.jobcard === undefined) {
@@ -281,8 +309,8 @@ export class ParmValidator {
281309
throw new Error("--jobcard parameter is empty");
282310
}
283311

284-
// resolve any new line escape sequences embedded in the jobcard
285-
params.arguments.jobcard = params.arguments.jobcard.replace("\\n", "\n");
312+
// handle long jobcards
313+
ParmValidator.wrapJobcard(params);
286314

287315
// split the jobcard into a comma separated list
288316
const jobcardParts = params.arguments.jobcard.split(",");

0 commit comments

Comments
 (0)