Skip to content

Commit 99127f7

Browse files
committed
Created Overrides module for handling externally defined settings.
1 parent d6946cc commit 99127f7

File tree

3 files changed

+58
-81
lines changed

3 files changed

+58
-81
lines changed

lib/plugins/branches.js

Lines changed: 4 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
const ErrorStash = require('./errorStash')
22
const NopCommand = require('../nopcommand')
33
const MergeDeep = require('../mergeDeep')
4+
const Overrides = require('./overrides')
45
const ignorableFields = []
56
const previewHeaders = { accept: 'application/vnd.github.hellcat-preview+json,application/vnd.github.luke-cage-preview+json,application/vnd.github.zzzax-preview+json' }
67
const overrides = [
7-
'required_status_checks.contexts',
8+
'contexts',
89
]
910

1011
module.exports = class Branches extends ErrorStash {
@@ -52,7 +53,7 @@ module.exports = class Branches extends ErrorStash {
5253
const params = Object.assign({}, p)
5354
return this.github.repos.getBranchProtection(params).then((result) => {
5455
const mergeDeep = new MergeDeep(this.log, this.github, ignorableFields)
55-
const changes = mergeDeep.compareDeep({ branch: { protection: this.reformatAndReturnBranchProtection(result.data) } }, { branch: { protection: this.removeOverrides(branch.protection, result.data) } })
56+
const changes = mergeDeep.compareDeep({ branch: { protection: this.reformatAndReturnBranchProtection(result.data) } }, { branch: { protection: Overrides.removeOverrides(overrides, branch.protection, result.data) } })
5657
const results = { msg: `Followings changes will be applied to the branch protection for ${params.branch.name} branch`, additions: changes.additions, modifications: changes.modifications, deletions: changes.deletions }
5758
this.log.debug(`Result of compareDeep = ${results}`)
5859

@@ -79,7 +80,7 @@ module.exports = class Branches extends ErrorStash {
7980
return this.github.repos.updateBranchProtection(params).then(res => this.log(`Branch protection applied successfully ${JSON.stringify(res.url)}`)).catch(e => { this.logError(`Error applying branch protection ${JSON.stringify(e)}`); return [] })
8081
}).catch((e) => {
8182
if (e.status === 404) {
82-
Object.assign(params, this.removeOverrides(branch.protection, {}), { headers: previewHeaders })
83+
Object.assign(params, Overrides.removeOverrides(overrides, branch.protection, {}), { headers: previewHeaders })
8384
if (this.nop) {
8485
resArray.push(new NopCommand(this.constructor.name, this.repo, this.github.repos.updateBranchProtection.endpoint(params), 'Add Branch Protection'))
8586
return Promise.resolve(resArray)
@@ -125,33 +126,4 @@ module.exports = class Branches extends ErrorStash {
125126
}
126127
return protection
127128
}
128-
129-
getLastKey (obj, property) {
130-
const keys = property.split('.')
131-
for (let i = 0; i < keys.length - 1; i++) {
132-
if (!obj[keys[i]]) return [null, null]
133-
obj = obj[keys[i]]
134-
}
135-
return [obj, keys[keys.length - 1]]
136-
}
137-
138-
removeOverrides (source, existing) {
139-
if (source) {
140-
overrides.forEach(override => {
141-
let [obj, lastKey] = this.getLastKey(source, override)
142-
if (!obj) return
143-
if ((Array.isArray(obj[lastKey]) || typeof obj[lastKey] === 'string') && obj[lastKey].includes('{{EXTERNALLY_DEFINED}}')) {
144-
let [obj2, lastKey2] = this.getLastKey(existing, override)
145-
if (obj2[lastKey2]) {
146-
obj[lastKey] = obj2[lastKey2]
147-
} else if (Array.isArray(obj[lastKey])) {
148-
obj[lastKey] = []
149-
} else {
150-
obj[lastKey] = ''
151-
}
152-
}
153-
})
154-
}
155-
return source
156-
}
157129
}

lib/plugins/overrides.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
const ErrorStash = require('./errorStash')
2+
3+
module.exports = class Overrides extends ErrorStash {
4+
static getObjectRef (data, dataKey) {
5+
const results = []
6+
const traverse = (obj) => {
7+
for (const key in obj) {
8+
if (key === dataKey) {
9+
results.push(obj)
10+
} else if (Array.isArray(obj[key])) {
11+
obj[key].forEach(element => traverse(element))
12+
} else if (typeof obj[key] === 'object' && obj[key]) {
13+
traverse(obj[key])
14+
}
15+
}
16+
}
17+
traverse(data)
18+
return results
19+
}
20+
21+
// When {{EXTERNALLY_DEFINED}} is found in the override value, retain the
22+
// existing value from GitHub.
23+
// Note:
24+
// - The admin settings could define multiple overrides, but the GitHub API
25+
// retains one only.
26+
// - The PUT method for rulesets (update) allows for multiple overrides.
27+
// - The POST method for rulesets (create) allows for one override only.
28+
static removeOverrides (overrides, source, existing) {
29+
overrides.forEach(override => {
30+
let sourceRefs = Overrides.getObjectRef(source, override)
31+
let data = JSON.stringify(sourceRefs, null, 2)
32+
if (data.includes('{{EXTERNALLY_DEFINED}}')) {
33+
let existingRefs = Overrides.getObjectRef(existing, override)
34+
sourceRefs.forEach(sourceRef => {
35+
if (existingRefs[0]) {
36+
sourceRef[override] = existingRefs[0][override]
37+
} else if (Array.isArray(sourceRef[override])) {
38+
sourceRef[override] = []
39+
} else if (typeof sourceRef[override] === 'object' && sourceRef[override]) {
40+
sourceRef[override] = {}
41+
} else {
42+
sourceRef[override] = ''
43+
}
44+
})
45+
}
46+
})
47+
return source
48+
}
49+
}

lib/plugins/rulesets.js

Lines changed: 5 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const Diffable = require('./diffable')
22
const NopCommand = require('../nopcommand')
33
const MergeDeep = require('../mergeDeep')
4+
const Overrides = require('./overrides')
45
const ignorableFields = []
56
const overrides = [
67
'required_status_checks',
@@ -95,51 +96,6 @@ module.exports = class Rulesets extends Diffable {
9596
return merged.hasChanges
9697
}
9798

98-
getObjectRef (data, dataKey) {
99-
const results = []
100-
const traverse = (obj) => {
101-
for (const key in obj) {
102-
if (key === dataKey) {
103-
results.push(obj)
104-
} else if (Array.isArray(obj[key])) {
105-
obj[key].forEach(element => traverse(element))
106-
} else if (typeof obj[key] === 'object' && obj[key]) {
107-
traverse(obj[key])
108-
}
109-
}
110-
}
111-
traverse(data)
112-
return results
113-
}
114-
115-
// When {{EXTERNALLY_DEFINED}} is found in the override value, retain the
116-
// existing value from GitHub.
117-
// Note:
118-
// - The admin settings could define multiple overrides, but the GitHub API
119-
// retains one only.
120-
// - The PUT method for rulesets (update) allows for multiple overrides.
121-
// - The POST method for rulesets (create) allows for one override only.
122-
removeOverrides (source, existing) {
123-
overrides.forEach(override => {
124-
let sourceRefs = this.getObjectRef(source, override)
125-
let data = JSON.stringify(sourceRefs, null, 2)
126-
if (data.includes('{{EXTERNALLY_DEFINED}}')) {
127-
let existingRefs = this.getObjectRef(existing, override)
128-
sourceRefs.forEach(sourceRef => {
129-
if (existingRefs[0]) {
130-
sourceRef[override] = existingRefs[0][override]
131-
} else if (Array.isArray(sourceRef[override])) {
132-
sourceRef[override] = []
133-
} else if (typeof sourceRef[override] === 'object' && sourceRef[override]) {
134-
sourceRef[override] = {}
135-
} else {
136-
sourceRef[override] = ''
137-
}
138-
})
139-
}
140-
})
141-
}
142-
14399
update (existing, attrs) {
144100
const parms = this.wrapAttrs(Object.assign({ id: existing.id }, attrs))
145101
if (this.scope === 'org') {
@@ -148,7 +104,7 @@ module.exports = class Rulesets extends Diffable {
148104
new NopCommand(this.constructor.name, this.repo, this.github.request.endpoint('PUT /orgs/{org}/rulesets/{id}', parms), 'Update Ruleset')
149105
])
150106
}
151-
this.removeOverrides(parms, existing)
107+
Overrides.removeOverrides(overrides, parms, existing)
152108
this.log.debug(`Updating Ruleset with the following values ${JSON.stringify(parms, null, 2)}`)
153109
return this.github.request('PUT /orgs/{org}/rulesets/{id}', parms).then(res => {
154110
this.log(`Ruleset updated successfully ${JSON.stringify(res.url)}`)
@@ -162,7 +118,7 @@ module.exports = class Rulesets extends Diffable {
162118
new NopCommand(this.constructor.name, this.repo, this.github.request.endpoint('PUT /repos/{owner}/{repo}/rulesets/{id}', parms), 'Update Ruleset')
163119
])
164120
}
165-
this.removeOverrides(parms, existing)
121+
Overrides.removeOverrides(overrides, parms, existing)
166122
this.log.debug(`Updating Ruleset with the following values ${JSON.stringify(parms, null, 2)}`)
167123
return this.github.request('PUT /repos/{owner}/{repo}/rulesets/{id}', parms).then(res => {
168124
this.log(`Ruleset updated successfully ${JSON.stringify(res.url)}`)
@@ -180,7 +136,7 @@ module.exports = class Rulesets extends Diffable {
180136
new NopCommand(this.constructor.name, this.repo, this.github.request.endpoint('POST /orgs/{org}/rulesets', this.wrapAttrs(attrs)), 'Create Ruleset')
181137
])
182138
}
183-
this.removeOverrides(attrs, {})
139+
Overrides.removeOverrides(overrides, attrs, {})
184140
this.log.debug(`Creating Rulesets with the following values ${JSON.stringify(attrs, null, 2)}`)
185141
return this.github.request('POST /orgs/{org}/rulesets', this.wrapAttrs(attrs)).then(res => {
186142
this.log(`Ruleset created successfully ${JSON.stringify(res.url)}`)
@@ -194,7 +150,7 @@ module.exports = class Rulesets extends Diffable {
194150
new NopCommand(this.constructor.name, this.repo, this.github.request.endpoint('POST /repos/{owner}/{repo}/rulesets', this.wrapAttrs(attrs)), 'Create Ruleset')
195151
])
196152
}
197-
this.removeOverrides(attrs, {})
153+
Overrides.removeOverrides(overrides, attrs, {})
198154
this.log.debug(`Creating Rulesets with the following values ${JSON.stringify(attrs, null, 2)}`)
199155
return this.github.request('POST /repos/{owner}/{repo}/rulesets', this.wrapAttrs(attrs)).then(res => {
200156
this.log(`Ruleset created successfully ${JSON.stringify(res.url)}`)

0 commit comments

Comments
 (0)