1- import { apiTest , getApiDriver } from 'gitlab-x' ;
2- import { load as loadYml , dump as dumpYml } from 'js-yaml' ;
1+ import {
2+ apiTest as gitlabApiTest ,
3+ getApiDriver as getGitlabApiDriver ,
4+ } from "gitlab-x" ;
5+ import {
6+ apiTest as githubApiTest ,
7+ getApiDriver as getGithubApiDriver ,
8+ } from "github-x" ;
9+ import { load as loadYml , dump as dumpYml } from "js-yaml" ;
310
411/*
512gitops patch function
@@ -19,105 +26,140 @@ required options:
1926export async function patch ( options ) {
2027 const verbose = options . verbose ;
2128
22- if ( verbose ) console . log ( `patch options: ${ JSON . stringify ( options , null , 2 ) } ` ) ;
29+ if ( verbose )
30+ console . log ( `patch options: ${ JSON . stringify ( options , null , 2 ) } ` ) ;
2331
24- if ( ! ( options . values_file . endsWith ( '.yml' ) || options . values_file . endsWith ( '.yaml' ) ) ) {
32+ if (
33+ ! (
34+ options . values_file . endsWith ( ".yml" ) ||
35+ options . values_file . endsWith ( ".yaml" )
36+ )
37+ ) {
2538 throw new Error ( `values_file must be a *.yml or *.yaml file` ) ;
2639 }
2740
2841 let gitProvider = await getGitProvider ( options ) ;
29- if ( verbose ) console . log ( `Git Provider: ${ gitProvider } ` ) ;
42+ if ( verbose ) console . log ( `Git Provider: ${ gitProvider } ` ) ;
3043 let apiDriver ;
31- if ( gitProvider === 'gitlab' ) {
32- apiDriver = getApiDriver ( options ) ;
44+ if ( gitProvider === "gitlab" ) {
45+ apiDriver = getGitlabApiDriver ( options ) ;
46+ } else if ( gitProvider === "github" ) {
47+ apiDriver = getGithubApiDriver ( options ) ;
48+ } else {
49+ throw new Error ( `Unsupported git provider: ${ gitProvider } ` ) ;
3350 }
3451
35- if ( ! await apiDriver . getVersion ( ) ) {
52+ if ( ! ( await apiDriver . getVersion ( ) ) ) {
3653 throw new Error ( `API check failed` ) ;
3754 }
3855
3956 const projectIdentifier = `/${ stripSlashes ( options . repo ) } ` ;
40-
41- let filePath = `/${ stripSlashes ( options . applications_dir ) } /${ stripSlashes ( options . application ) } /${ stripSlashes ( options . values_file ) } ` ;
42- if ( verbose ) console . log ( `file path: ${ filePath } ` ) ;
43- const fileExists = await apiDriver . fileExists ( projectIdentifier , filePath , options . branch ) ;
44-
45- if ( ! fileExists ) {
46- if ( verbose ) console . log ( `file '${ filePath } ' does not exist in branch '${ options . branch } '` ) ;
47- filePath = `/${ stripSlashes ( options . applications_dir ) } /${ stripSlashes ( options . application ) } /${ stripSlashes ( toggleYamlFileExtension ( options . values_file ) ) } ` ;
48- if ( verbose ) console . log ( `trying opposite yaml file extension '${ filePath } '` ) ;
49- const toggledYamlFileExists = await apiDriver . fileExists ( projectIdentifier , filePath , options . branch ) ;
50- if ( ! toggledYamlFileExists ) {
57+
58+ let filePath = `/${ stripSlashes ( options . applications_dir ) } /${ stripSlashes (
59+ options . application
60+ ) } /${ stripSlashes ( options . values_file ) } `;
61+ if ( verbose ) console . log ( `file path: ${ filePath } ` ) ;
62+ const fileExists = await apiDriver . fileExists (
63+ projectIdentifier ,
64+ filePath ,
65+ options . branch
66+ ) ;
67+
68+ if ( ! fileExists ) {
69+ if ( verbose )
70+ console . log (
71+ `file '${ filePath } ' does not exist in branch '${ options . branch } '`
72+ ) ;
73+ filePath = `/${ stripSlashes ( options . applications_dir ) } /${ stripSlashes (
74+ options . application
75+ ) } /${ stripSlashes ( toggleYamlFileExtension ( options . values_file ) ) } `;
76+ if ( verbose )
77+ console . log ( `trying opposite yaml file extension '${ filePath } '` ) ;
78+ const toggledYamlFileExists = await apiDriver . fileExists (
79+ projectIdentifier ,
80+ filePath ,
81+ options . branch
82+ ) ;
83+ if ( ! toggledYamlFileExists ) {
5184 throw new Error ( `file '${ filePath } ' does not exist` ) ;
5285 }
5386 }
54-
55- if ( verbose ) console . log ( `file '${ filePath } ' exists` ) ;
56-
57- const fileContent = await apiDriver . getRawFile ( projectIdentifier , filePath , options . branch ) ;
58- if ( verbose ) console . log ( `file contents: \n\n----\n${ fileContent } \n----\n\n` ) ;
59-
87+
88+ if ( verbose ) console . log ( `file '${ filePath } ' exists` ) ;
89+
90+ const fileContent = await apiDriver . getRawFile (
91+ projectIdentifier ,
92+ filePath ,
93+ options . branch
94+ ) ;
95+ if ( verbose ) console . log ( `file contents: \n\n----\n${ fileContent } \n----\n\n` ) ;
96+
6097 const yml = loadYml ( fileContent ) ;
6198 let patchFields = [ ] ;
62- if ( options . patch_field . startsWith ( '.' ) ) {
63- if ( verbose ) console . log ( `patch field is assumed to be a yaml path` ) ;
99+ if ( options . patch_field . startsWith ( "." ) ) {
100+ if ( verbose ) console . log ( `patch field is assumed to be a yaml path` ) ;
64101 patchFields = [ options . patch_field ] ;
65- }
66- else {
67- if ( verbose ) console . log ( `patch field is assumed to be a field name` ) ;
102+ } else {
103+ if ( verbose ) console . log ( `patch field is assumed to be a field name` ) ;
68104 patchFields = findYmlField ( yml , options . patch_field ) ;
69- if ( verbose ) console . log ( `found patch fields: ${ patchFields } ` ) ;
105+ if ( verbose ) console . log ( `found patch fields: ${ patchFields } ` ) ;
70106 }
71107
72108 let changes = false ;
73- for ( const patchField of patchFields ) {
74- if ( ! existsYmlField ( yml , patchField ) ) {
75- throw new Error ( `field '${ patchField } ' does not exist in file '${ filePath } '` ) ;
109+ for ( const patchField of patchFields ) {
110+ if ( ! existsYmlField ( yml , patchField ) ) {
111+ throw new Error (
112+ `field '${ patchField } ' does not exist in file '${ filePath } '`
113+ ) ;
76114 }
77-
78- if ( verbose ) console . log ( `patching field '${ patchField } '` ) ;
115+
116+ if ( verbose ) console . log ( `patching field '${ patchField } '` ) ;
79117 const patchValue = getYmlFieldValue ( yml , patchField ) ;
80- if ( verbose ) console . log ( `old value: ${ patchValue } ` ) ;
118+ if ( verbose ) console . log ( `old value: ${ patchValue } ` ) ;
81119 const newValue = options . patch_value ;
82- if ( verbose ) console . log ( `new value: ${ newValue } ` ) ;
83- if ( patchValue !== newValue ) {
120+ if ( verbose ) console . log ( `new value: ${ newValue } ` ) ;
121+ if ( patchValue !== newValue ) {
84122 changes = true ;
85123 setYmlFieldValue ( yml , patchField , newValue ) ;
86124 }
87125 }
88126
89- if ( ! changes ) {
127+ if ( ! changes ) {
90128 console . log ( `no changes to commit` ) ;
91129 return ;
92130 }
93131
94132 const ymlDump = dumpYml ( yml ) ;
95133
96- if ( verbose ) console . log ( `new file contents: \n\n----\n${ ymlDump } \n----\n\n` ) ;
134+ if ( verbose ) console . log ( `new file contents: \n\n----\n${ ymlDump } \n----\n\n` ) ;
97135
98- if ( verbose ) console . log ( ' creating commit' )
136+ if ( verbose ) console . log ( " creating commit" ) ;
99137 let targetBranch = options . branch ;
100- if ( typeof ref === ' undefined' ) {
138+ if ( typeof ref === " undefined" ) {
101139 // TODO add to defaultBranch function to gitlab-x
102- const defaultBranch = ( await apiDriver . getProject ( projectIdentifier ) ) . default_branch ;
103- if ( verbose ) console . log ( `'ref' is not specified. Using default branch '${ defaultBranch } '` ) ;
140+ const defaultBranch = ( await apiDriver . getProject ( projectIdentifier ) )
141+ . default_branch ;
142+ if ( verbose )
143+ console . log (
144+ `'ref' is not specified. Using default branch '${ defaultBranch } '`
145+ ) ;
104146 targetBranch = defaultBranch ;
105147 }
106148 let commitObject = {
107- " branch" : targetBranch ,
149+ branch : targetBranch ,
108150 // TODO add original author to commit message
109- " commit_message" : options . message || `Patched '${ filePath } '` ,
110- " actions" : [
151+ commit_message : options . message || `Patched '${ filePath } '` ,
152+ actions : [
111153 {
112- " action" : "update" ,
113- " file_path" : filePath ,
114- " content" : ymlDump ,
115- " encoding" : "text"
116- }
117- ]
154+ action : "update" ,
155+ file_path : filePath ,
156+ content : ymlDump ,
157+ encoding : "text" ,
158+ } ,
159+ ] ,
118160 } ;
119161 await apiDriver . postCommit ( projectIdentifier , commitObject ) ;
120- if ( verbose ) console . log ( ' commit done' ) ;
162+ if ( verbose ) console . log ( " commit done" ) ;
121163 return ;
122164}
123165
@@ -131,52 +173,66 @@ returns
131173 - 'gitlab' if the base url points to a gitlab url with activated api
132174*/
133175async function getGitProvider ( options ) {
134- if ( options . verbose ) console . log ( "checking for gitlab api" )
135- const gitlabApiResult = await apiTest ( options ) ;
136- if ( gitlabApiResult ) {
137- if ( options . verbose ) console . log ( "found gitlab api" ) ;
138- return 'gitlab' ;
176+ if ( options . verbose ) console . log ( "checking for gitlab api" ) ;
177+ try {
178+ const gitlabApiResult = await gitlabApiTest ( options ) ;
179+ if ( gitlabApiResult ) {
180+ if ( options . verbose ) console . log ( "found gitlab api" ) ;
181+ return "gitlab" ;
182+ }
183+ } catch ( e ) {
184+ // error is expected if the gitlab api is not present
139185 }
140-
141- if ( options . verbose ) console . log ( "checking for github api" ) ;
142- throw new Error ( "GitHub API not implemented yet" ) ;
143- // TODO
186+
187+ try {
188+ if ( options . verbose ) console . log ( "checking for github api" ) ;
189+ const githubApiResult = await githubApiTest ( options ) ;
190+ if ( githubApiResult ) {
191+ if ( options . verbose ) console . log ( "found github api" ) ;
192+ return "github" ;
193+ }
194+ } catch ( e ) {
195+ // error is expected if the github api is not present
196+ }
197+ return "" ;
144198}
145199
146200// strips tailing and leading slashes from a string
147201function stripSlashes ( str ) {
148- return str . replace ( / ^ \/ | \/ $ / g, '' ) ;
202+ return str . replace ( / ^ \/ | \/ $ / g, "" ) ;
149203}
150204
151205function toggleYamlFileExtension ( fileName ) {
152- if ( fileName . endsWith ( ' .yml' ) ) {
153- return fileName . replace ( ' .yml' , ' .yaml' ) ;
154- } else if ( fileName . endsWith ( ' .yaml' ) ) {
155- return fileName . replace ( ' .yaml' , ' .yml' ) ;
206+ if ( fileName . endsWith ( " .yml" ) ) {
207+ return fileName . replace ( " .yml" , " .yaml" ) ;
208+ } else if ( fileName . endsWith ( " .yaml" ) ) {
209+ return fileName . replace ( " .yaml" , " .yml" ) ;
156210 } else {
157211 return fileName ;
158212 }
159213}
160214
161- function findYmlField ( yml , fieldName , subPath = '' ) {
215+ function findYmlField ( yml , fieldName , subPath = "" ) {
162216 let occurences = [ ] ;
163- for ( let key in yml ) {
164- if ( key === fieldName ) {
217+ for ( let key in yml ) {
218+ if ( key === fieldName ) {
165219 occurences . push ( `${ subPath } .${ key } ` ) ;
166- } else if ( typeof yml [ key ] === 'object' ) {
167- occurences = occurences . concat ( findYmlField ( yml [ key ] , fieldName , `${ subPath } .${ key } ` ) ) ;
220+ } else if ( typeof yml [ key ] === "object" ) {
221+ occurences = occurences . concat (
222+ findYmlField ( yml [ key ] , fieldName , `${ subPath } .${ key } ` )
223+ ) ;
168224 }
169225 }
170226 return occurences ;
171227}
172228
173229function existsYmlField ( yml , fieldPath ) {
174- const fieldPathParts = fieldPath . split ( '.' ) ;
230+ const fieldPathParts = fieldPath . split ( "." ) ;
175231 let currentYml = yml ;
176- for ( let i = 0 ; i < fieldPathParts . length ; i ++ ) {
232+ for ( let i = 0 ; i < fieldPathParts . length ; i ++ ) {
177233 const fieldPathPart = fieldPathParts [ i ] ;
178- if ( fieldPathPart === '' ) continue ;
179- if ( ! currentYml [ fieldPathPart ] ) {
234+ if ( fieldPathPart === "" ) continue ;
235+ if ( ! currentYml [ fieldPathPart ] ) {
180236 return false ;
181237 }
182238 currentYml = currentYml [ fieldPathPart ] ;
@@ -185,30 +241,30 @@ function existsYmlField(yml, fieldPath) {
185241}
186242
187243function getYmlFieldValue ( yml , fieldPath ) {
188- const fieldPathParts = fieldPath . split ( '.' ) ;
244+ const fieldPathParts = fieldPath . split ( "." ) ;
189245 let currentYml = yml ;
190- for ( let i = 0 ; i < fieldPathParts . length ; i ++ ) {
246+ for ( let i = 0 ; i < fieldPathParts . length ; i ++ ) {
191247 const fieldPathPart = fieldPathParts [ i ] ;
192- if ( fieldPathPart === '' ) continue ;
248+ if ( fieldPathPart === "" ) continue ;
193249 currentYml = currentYml [ fieldPathPart ] ;
194250 }
195251 return currentYml ;
196252}
197253
198254function setYmlFieldValue ( yml , fieldPath , value ) {
199- const fieldPathParts = fieldPath . split ( '.' ) ;
255+ const fieldPathParts = fieldPath . split ( "." ) ;
200256 let currentYml = yml ;
201- for ( let i = 0 ; i < fieldPathParts . length ; i ++ ) {
257+ for ( let i = 0 ; i < fieldPathParts . length ; i ++ ) {
202258 const fieldPathPart = fieldPathParts [ i ] ;
203- if ( fieldPathPart === '' ) continue ;
204- if ( i === fieldPathParts . length - 1 ) {
259+ if ( fieldPathPart === "" ) continue ;
260+ if ( i === fieldPathParts . length - 1 ) {
205261 currentYml [ fieldPathPart ] = value ;
206262 } else {
207- if ( ! currentYml [ fieldPathPart ] ) {
263+ if ( ! currentYml [ fieldPathPart ] ) {
208264 currentYml [ fieldPathPart ] = { } ;
209265 }
210266 currentYml = currentYml [ fieldPathPart ] ;
211267 }
212268 }
213269 return yml ;
214- }
270+ }
0 commit comments