11#!/usr/bin/env node
22
3- const { Lexer , NodeType , Parser , TokenType } = require ( "@octopusdeploy/ocl" )
3+ const { parseOclWrapper } = require ( "@octopusdeploy/ocl/dist/wrapper " )
44const fs = require ( "fs" )
55const 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
689if ( 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+ }
0 commit comments