Skip to content

Commit

Permalink
Update Enterprise Liquid deprecation handling to use new versions (gi…
Browse files Browse the repository at this point in the history
…thub#15818)

* update Liquid deprecation fixtures to use new versions

* update module that removes deprecated GHES frontmatter for new versions

* update module that removes deprecated GHES conditionals for new versions

* update script to use new versions and also remove internal-developer checkout option

* update deprecated Liquid tests to use new versions

* remove unnecessary leading slash in getEnterpriseServerNumber pattern

* include a step that runs script/remove-unused-assets.js

* Update script/remove-deprecated-enterprise-version-markup.js

Co-authored-by: Jason Etcovitch <[email protected]>

* require script instead of execSync

Co-authored-by: Jason Etcovitch <[email protected]>
  • Loading branch information
sarahs and JasonEtco authored Sep 30, 2020
1 parent 81a1e59 commit 0b1c7ad
Show file tree
Hide file tree
Showing 14 changed files with 211 additions and 201 deletions.
2 changes: 1 addition & 1 deletion lib/patterns.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,5 @@ module.exports = {
// new versioning format patterns
adminProduct: /\/admin(\/|$|\?|#)/,
enterpriseServer: /\/enterprise-server@/,
getEnterpriseServerNumber: /\/enterprise-server@(\d+\.\d+)/
getEnterpriseServerNumber: /enterprise-server@(\d+\.\d+)/
}
37 changes: 17 additions & 20 deletions lib/remove-deprecated-frontmatter.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,22 @@
module.exports = function removeDeprecatedFrontmatter (data, devCheckout, versionToDeprecate, nextOldestVersion) {
// there are currently different frontmatter conventions for developer docs vs. help docs
if (devCheckout) {
// skip files with no exclude_version frontmatter
if (!data.exclude_version) return data
const { getEnterpriseServerNumber } = require('./patterns')

// remove frontmatter like exclude_version: - "2.13"
if (data.exclude_version.includes(`${versionToDeprecate}`)) {
data.exclude_version = data.exclude_version.filter(version => !version.match(versionToDeprecate))
module.exports = function removeDeprecatedFrontmatter (file, frontmatterVersions, versionToDeprecate, nextOldestVersion) {
// skip files with no versions or Enterprise Server versions frontmatter
if (!frontmatterVersions) return
if (!frontmatterVersions['enterprise-server']) return

if (!data.exclude_version.length) delete data.exclude_version
}
} else {
// skip files with no versions or Enterprise versions frontmatter
if (!data.versions) return data
if (!data.versions.enterprise) return data
const enterpriseRange = frontmatterVersions['enterprise-server']

// change frontmatter like enterprise: '>=2.13' to enterprise: '*'
if (data.versions.enterprise === `>=${versionToDeprecate}` || data.versions.enterprise === `>=${nextOldestVersion}`) {
data.versions.enterprise = '*'
}
}
// skip files with versions frontmatter that applies to all enterprise-server releases
if (enterpriseRange === '*') return

// get the release numbers alone
const releaseToDeprecate = versionToDeprecate.match(getEnterpriseServerNumber)[1]
const nextOldestRelease = nextOldestVersion.match(getEnterpriseServerNumber)[1]

return data
// if the release to deprecate is 2.13, and the FM is either '>=2.13' or '>=2.14',
// we can safely change the FM to enterprise-server: '*'
if (enterpriseRange === `>=${releaseToDeprecate}` || enterpriseRange === `>=${nextOldestRelease}`) {
frontmatterVersions['enterprise-server'] = '*'
}
}
10 changes: 5 additions & 5 deletions lib/remove-liquid-statements.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,11 @@ module.exports = function removeLiquidStatements (content, versionToDeprecate, n
// see tests/fixtures/remove-liquid-statements for examples
const regexes = {
// remove liquid only
greaterThanVersionToDeprecate: new RegExp(startTag.source + ` if ?(?: page.version == ('|")'?dotcom'?('|") ?or)? page.version ver_gte? ('|")${versionToDeprecate}('|") ` + endTag.source, 'gm'),
andGreaterThanVersionToDeprecate1: new RegExp('(' + startTag.source + ` if .*?) and page.version ver_gte? (?:'|")${versionToDeprecate}(?:'|")( ` + endTag.source + ')', 'gm'),
andGreaterThanVersionToDeprecate2: new RegExp('(' + startTag.source + ` if )page.version ver_gte? (?:'|")${versionToDeprecate}(?:'|") and (.*? ` + endTag.source + ')', 'gm'),
notEqualsVersionToDeprecate: new RegExp('(' + startTag.source + ` if)(?:( page.version .*?) or)? page.version != (?:'|")${versionToDeprecate}(?:'|")( ` + endTag.source + ')', 'gm'),
andNotEqualsVersionToDeprecate: new RegExp('(' + startTag.source + ` if .*?) and page.version != (?:'|")${versionToDeprecate}(?:'|")( ` + endTag.source + ')', 'gm'),
greaterThanVersionToDeprecate: new RegExp(startTag.source + ` if ?(?: currentVersion == ('|")'?free-pro-team@latest'?('|") ?or)? currentVersion ver_gt ('|")${versionToDeprecate}('|") ` + endTag.source, 'gm'),
andGreaterThanVersionToDeprecate1: new RegExp('(' + startTag.source + ` if .*?) and currentVersion ver_gt (?:'|")${versionToDeprecate}(?:'|")( ` + endTag.source + ')', 'gm'),
andGreaterThanVersionToDeprecate2: new RegExp('(' + startTag.source + ` if )currentVersion ver_gt (?:'|")${versionToDeprecate}(?:'|") and (.*? ` + endTag.source + ')', 'gm'),
notEqualsVersionToDeprecate: new RegExp('(' + startTag.source + ` if)(?:( currentVersion .*?) or)? currentVersion != (?:'|")${versionToDeprecate}(?:'|")( ` + endTag.source + ')', 'gm'),
andNotEqualsVersionToDeprecate: new RegExp('(' + startTag.source + ` if .*?) and currentVersion != (?:'|")${versionToDeprecate}(?:'|")( ` + endTag.source + ')', 'gm'),
// remove liquid and content
lessThanNextOldestVersion: new RegExp(startTag.source + ` if .*?ver_lt ('|")${nextOldestVersion}('|") ?` + endTag.source, 'm'),
equalsVersionToDeprecate: new RegExp(startTag.source + ` if .*?== ('|")${versionToDeprecate}('|") ?` + endTag.source, 'm')
Expand Down
113 changes: 62 additions & 51 deletions script/remove-deprecated-enterprise-version-markup.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,83 +4,92 @@ const fs = require('fs')
const path = require('path')
const walk = require('walk-sync')
const matter = require('gray-matter')
const readlineSync = require('readline-sync')
const program = require('commander')
const { indexOf, nth } = require('lodash')
const removeLiquidStatements = require('../lib/remove-liquid-statements')
const removeDeprecatedFrontmatter = require('../lib/remove-deprecated-frontmatter')
const versionToDeprecate = require('../lib/enterprise-server-releases').deprecated[0]
const nextOldestVersion = require('../lib/enterprise-server-releases').oldestSupported
const devCheckout = process.argv[2]
const prompt = `This script will run in the current checkout of help.github.com.
Is that what you want? Press Y to continue, or enter any other key to cancel: `
const enterpriseServerReleases = require('../lib/enterprise-server-releases')
const contentPath = path.join(__dirname, '../content')
const dataPath = path.join(__dirname, '../data')
const removeUnusedAssetsScript = 'script/remove-unused-assets'
const elseifRegex = /{-?% elsif/

// [start-readme]
//
// Run this script after an Enterprise deprecation to remove Liquid statements and frontmatter that contain the deprecated Enterprise version.
// See the Enterprise deprecation issue template for instructions.
//
// You can run this script on either the help docs or the developer docs. To run it on the help docs, enter:
//
// `script/remove-deprecated-enterprise-version-markup.js`
//
// To run it on the developer docs, provide a path to your developer docs checkout as an argument. You can use a tilde to represent your home directory. For example:
//
// `script/remove-deprecated-enterprise-version-markup.js ~/Desktop/internal-developer.github.com/`
//
// [end-readme]

let contentDir = path.join(__dirname, '../content')
let dataDir = path.join(__dirname, '../data')

const elseifRegex = /{-?% elsif/
program
.description('Remove Liquid conditionals and update versions frontmatter for a given Enterprise Server release.')
.option('-r, --release <NUMBER>', 'Enterprise Server release number. Example: 2.19')
.parse(process.argv)

// verify CLI options
if (!program.release) {
console.log(program.description() + '\n')
program.options.forEach(opt => {
console.log(opt.flags)
console.log(opt.description + '\n')
})
process.exit(1)
}

// determine whether to run the script on help docs or developer docs
if (devCheckout) {
try {
process.chdir(devCheckout)
console.log('OK, the script will run in ' + devCheckout)
contentDir = path.join(devCheckout, 'content')
dataDir = path.join(devCheckout, 'data')
} catch (err) {
console.log('No such directory! ' + devCheckout)
}
} else {
const answer = readlineSync.question(prompt)

if (!answer.match(/^Y$/mi)) {
console.log('Exiting!')
process.exit()
}
if (!enterpriseServerReleases.all.includes(program.release)) {
console.log(`You specified ${program.release}! Please specify a supported or deprecated release number from lib/enterprise-server-releases.js`)
process.exit(1)
}

const versionToDeprecate = `enterprise-server@${program.release}`
const currentIndex = indexOf(enterpriseServerReleases.all, program.release)
const nextOldestRelease = nth(enterpriseServerReleases.all, currentIndex - 1)
const nextOldestVersion = `enterprise-server@${nextOldestRelease}`

console.log(`Deprecating ${versionToDeprecate}!\n`)
console.log(`Next oldest version: ${nextOldestVersion}\n`)

// gather content and data files
const contentFiles = walk(contentDir, { includeBasePath: true })
.filter(relativePath => relativePath.endsWith('.md') && !relativePath.match(/README/i))
const contentFiles = walk(contentPath, { includeBasePath: true, directories: false })
.filter(file => file.endsWith('.md'))
.filter(file => !(file.endsWith('README.md') || file === 'LICENSE'))

const dataFiles = walk(dataDir, { includeBasePath: true })
.filter(relativePath => relativePath.endsWith('.yml') || relativePath.endsWith('.md'))
.filter(relativePath => !relativePath.includes('/graphql/'))
const dataFiles = walk(dataPath, { includeBasePath: true, directories: false })
.filter(file => file.includes('data/reusables') || file.includes('data/variables'))
.filter(file => !file.endsWith('README.md'))

const files = contentFiles.concat(dataFiles)
const allFiles = contentFiles.concat(dataFiles)

main()
console.log(`Removed ${versionToDeprecate} markup from content and data files! Review and run script/test.`)
console.log(`\nRunning ${removeUnusedAssetsScript}...`)
require(`../${removeUnusedAssetsScript}`)

function printElseIfFoundWarning (location) {
console.log(`${location} has an 'elsif' condition! Resolve all elsifs by hand, then rerun the script.`)
}

function main () {
files.forEach(file => {
allFiles.forEach(file => {
const oldContents = fs.readFileSync(file, 'utf8')
const { content, data } = matter(oldContents)

// can't safely handle elseifs programmatically, too many possible outcomes
// (only intro and title frontmatter are likely to contain elseif tags)
if (content.match(elseifRegex) || (data.intro && data.intro.match(elseifRegex)) || (data.title && data.title.match(elseifRegex))) {
console.log(`${file} has an 'elsif' condition! Resolve all elsifs by hand, then rerun the script.`)
// we can't safely handle elseifs programmatically, too many possible outcomes
if (elseifRegex.test(content)) {
printElseIfFoundWarning(`content in ${file}`)
process.exit()
}

// update frontmatter data (i.e., productVersions field)
const newData = removeDeprecatedFrontmatter(data, devCheckout, versionToDeprecate, nextOldestVersion)
Object.keys(data).forEach(key => {
if (elseifRegex.test(data[key])) {
printElseIfFoundWarning(`frontmatter '${key}' in ${file}`)
process.exit()
}
})

// update frontmatter versions prop
removeDeprecatedFrontmatter(file, data.versions, versionToDeprecate, nextOldestVersion)

// update liquid statements in body content
// update liquid statements in content and data
const newContent = removeLiquidStatements(content, versionToDeprecate, nextOldestVersion)

// make sure any intro fields that exist and are empty return an empty string, not null
Expand All @@ -89,8 +98,10 @@ function main () {
}

// put it all back together
const newContents = matter.stringify(newContent, newData, { lineWidth: 10000 })
const newContents = matter.stringify(newContent, data, { lineWidth: 10000 })

fs.writeFileSync(file, newContents)
})

console.log(`Removed ${versionToDeprecate} markup from content and data files! Review and run script/test.`)
}
Loading

0 comments on commit 0b1c7ad

Please sign in to comment.