Skip to content

Commit e50b53f

Browse files
committed
Use the new OCL parsing wrapper to clean up the check
1 parent 6ffe999 commit e50b53f

File tree

5 files changed

+90
-269
lines changed

5 files changed

+90
-269
lines changed

.idea/misc.xml

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

pr_ocl_check/check.js

Lines changed: 17 additions & 145 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,9 @@
11
#!/usr/bin/env node
22

3-
const {Lexer, NodeType, Parser, TokenType} = require("@octopusdeploy/ocl")
3+
const {parseOclWrapper} = require("@octopusdeploy/ocl/dist/wrapper")
44
const fs = require("fs")
55
const path =require("path")
6-
7-
const FirstStepName = "Manual Intervention"
8-
const ManualInterventionType = "Octopus.Manual"
9-
10-
/**
11-
* This function performs the validation of the Octopus CaC OCL file
12-
* @param ocl The OCL file to parse
13-
* @returns {Promise<unknown>} A promise with true if the validation succeeded, and false otherwise
14-
*/
15-
function checkPr(ocl) {
16-
return new Promise((resolve, reject) => {
17-
// Read the deployment process OCL file
18-
fs.readFile(ocl, 'utf8', (err, data) => {
19-
// Any error reading the file fails the script
20-
if (err) {
21-
console.error(err)
22-
resolve(false)
23-
return
24-
}
25-
26-
// These come from the @octopusdeploy/ocl dependency
27-
const lexer = new Lexer(data)
28-
const parser = new Parser(lexer)
29-
const steps = parser.getAST()
30-
31-
// Test that we have any steps at all
32-
if (steps.length === 0) {
33-
console.log("Deployment process can not be empty")
34-
resolve(false)
35-
return
36-
}
37-
38-
const firstStepName = getUnquotedPropertyValue(getProperty(steps[0], "name"))
39-
40-
if (!firstStepName) {
41-
console.log("Failed to find the name of the first step")
42-
resolve(false)
43-
return
44-
}
45-
46-
if (firstStepName !== FirstStepName) {
47-
console.log("First step must be called " + FirstStepName + " (was " + firstStepName + ")")
48-
resolve(false)
49-
return
50-
}
51-
52-
const action = getBlock(steps[0], "action")
53-
const actionType = getUnquotedPropertyValue(getProperty(action, "action_type"))
54-
55-
if (actionType !== ManualInterventionType) {
56-
console.log("First step must be a manual intervention step (was " + actionType + ")")
57-
resolve(false)
58-
return
59-
}
60-
61-
console.log("All tests passed!")
62-
resolve(true)
63-
})
64-
})
65-
}
6+
const {expect} = require("expect");
667

678
// This is the entry point when the file is run by Node.js
689
if (require.main === module) {
@@ -81,90 +22,21 @@ if (require.main === module) {
8122
})
8223
}
8324

84-
/**
85-
* Returns the attribute node with the supplied name
86-
* @param ast The block to search
87-
* @param name The attribute name
88-
* @returns {undefined|any} The attribute node, or undefined if no match was found
89-
*/
90-
function getProperty(ast, name) {
91-
if (!ast) {
92-
return undefined
93-
}
94-
95-
return ast.children
96-
.filter(c =>
97-
c.type === NodeType.ATTRIBUTE_NODE &&
98-
c.name.value === name)
99-
.pop()
100-
}
25+
exports.checkPr = checkPr
10126

10227
/**
103-
* Returns the block node with the supplied name
104-
* @param ast The block to search
105-
* @param name The block name
106-
* @returns {undefined|any} The block node, or undefined if no match was found
107-
*/
108-
function getBlock(ast, name) {
109-
if (!ast) {
110-
return undefined
111-
}
112-
113-
return ast.children
114-
.filter(c =>
115-
c.type === NodeType.BLOCK_NODE &&
116-
c.name.value === name)
117-
.pop()
118-
}
119-
120-
/**
121-
* Returns the attribute node with the supplied name and value
122-
* @param ast The block to search
123-
* @param name The attribute name
124-
* @value name The attribute value
125-
* @returns {undefined|any} The attribute node, or undefined if no match was found
126-
*/
127-
function getPropertyWithValue(ast, name, value) {
128-
if (!ast) {
129-
return undefined
130-
}
131-
132-
return ast.children
133-
.filter(c =>
134-
c.type === NodeType.ATTRIBUTE_NODE &&
135-
c.name.value === name &&
136-
c.value.value.value === value)
137-
.pop()
138-
}
139-
140-
141-
/**
142-
* Gets the value of the attribute node
143-
* @param ast The attribute node
144-
* @returns {undefined|*} The attribute node value, or undefined if ast was falsy or not an attribute
145-
*/
146-
function getPropertyValue(ast) {
147-
if (!ast || !ast.type === NodeType.ATTRIBUTE_NODE) {
148-
return undefined
149-
}
150-
151-
return ast.value.value.value
152-
}
153-
154-
/**
155-
* Gets the unquoted value of the attribute node
156-
* @param ast The attribute node
157-
* @returns {undefined|*} The attribute node value with surrounding quotes removed, or undefined if ast was falsy or not an attribute
28+
* This function performs the validation of the Octopus CaC OCL file
29+
* @param ocl The OCL file to parse
30+
* @returns {Promise<unknown>} A promise with true if the validation succeeded, and false otherwise
15831
*/
159-
function getUnquotedPropertyValue(ast) {
160-
if (!ast || !ast.type === NodeType.ATTRIBUTE_NODE) {
161-
return undefined
162-
}
163-
164-
const value = ast.value.value.value
165-
const result = value.match(`"(.*?)"`)
166-
167-
return result === null ? value : result[1]
168-
}
169-
170-
exports.checkPr = checkPr
32+
function checkPr(ocl) {
33+
// Read the file
34+
const fileContents = fs.readFileSync(ocl, 'utf-8')
35+
// Parse the file
36+
const deploymentProcess = parseOclWrapper(fileContents)
37+
38+
// Verify the contents
39+
expect(deploymentProcess.step).not.toHaveLength(0)
40+
expect(deploymentProcess.step[0].name).toBe("Manual Intervention")
41+
expect(deploymentProcess.step[0].action[0].action_type).toBe("Octopus.Manual")
42+
}

pr_ocl_check/check.test.js

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
const {checkPr} = require('./check')
22

33
test('fail a process definition where the first step does not have the correct name', async () => {
4-
const result = await checkPr('./test_deployment_processes/wrong_name.ocl')
5-
expect(result).toBe(false)
4+
expect(() => checkPr('./test_deployment_processes/wrong_name.ocl')).toThrow()
65
})
76

87
test('pass a process definition where the first step does not have the correct name', async () => {
9-
const result = await checkPr('./test_deployment_processes/correct_name.ocl')
10-
expect(result).toBe(true)
8+
expect(() => checkPr('./test_deployment_processes/correct_name.ocl')).not.toThrow()
119
})
1210

1311
test('fail a process definition where the first step does not have the correct type', async () => {
14-
const result = await checkPr('./test_deployment_processes/correct_name_wrong_type.ocl')
15-
expect(result).toBe(false)
12+
expect(() =>checkPr('./test_deployment_processes/correct_name_wrong_type.ocl')).toThrow()
1613
})

0 commit comments

Comments
 (0)