]> git.ipfire.org Git - thirdparty/bootstrap.git/commitdiff
Improve change-version.js (#33148)
authorXhmikosR <xhmikosr@gmail.com>
Thu, 11 Mar 2021 09:37:52 +0000 (11:37 +0200)
committerXhmikosR <xhmikosr@gmail.com>
Mon, 5 Apr 2021 04:44:39 +0000 (07:44 +0300)
* switch to async/await
* remove shelljs
* switch to globby; supports .gitignore out of the box
* don't write any files to the disk if they are indentical
* add two more cmd switches: --dry and --verbose
* strip leading "v" from version arguments so that we don't end up with duplicate `v`s

build/change-version.js
package.json

index 1fd0c77fe5166ad5dbaef45e7a1a054dd873b551..08313c1e815eb8877218d1e17a394c4afe9b5480 100755 (executable)
@@ -9,11 +9,21 @@
 
 'use strict'
 
-const fs = require('fs')
+const fs = require('fs').promises
 const path = require('path')
-const sh = require('shelljs')
-
-sh.config.fatal = true
+const globby = require('globby')
+
+const VERBOSE = process.argv.includes('--verbose')
+const DRY_RUN = process.argv.includes('--dry') || process.argv.includes('--dry-run')
+
+// These are the filetypes we only care about replacing the version
+const GLOB = [
+  '**/*.{css,html,js,json,md,scss,txt,yml}'
+]
+const GLOBBY_OPTIONS = {
+  cwd: path.join(__dirname, '..'),
+  gitignore: true
+}
 
 // Blame TC39... https://github.com/benjamingr/RegExp.escape/issues/37
 function regExpQuote(string) {
@@ -24,87 +34,48 @@ function regExpQuoteReplacement(string) {
   return string.replace(/\$/g, '$$')
 }
 
-const DRY_RUN = false
+async function replaceRecursively(file, oldVersion, newVersion) {
+  const originalString = await fs.readFile(file, 'utf8')
+  const newString = originalString.replace(
+    new RegExp(regExpQuote(oldVersion), 'g'), regExpQuoteReplacement(newVersion)
+  )
 
-function walkAsync(directory, excludedDirectories, fileCallback, errback) {
-  if (excludedDirectories.has(path.parse(directory).base)) {
+  // No need to move any further if the strings are identical
+  if (originalString === newString) {
     return
   }
 
-  fs.readdir(directory, (err, names) => {
-    if (err) {
-      errback(err)
-      return
-    }
-
-    names.forEach(name => {
-      const filepath = path.join(directory, name)
-      fs.lstat(filepath, (err, stats) => {
-        if (err) {
-          process.nextTick(errback, err)
-          return
-        }
-
-        if (stats.isDirectory()) {
-          process.nextTick(walkAsync, filepath, excludedDirectories, fileCallback, errback)
-        } else if (stats.isFile()) {
-          process.nextTick(fileCallback, filepath)
-        }
-      })
-    })
-  })
-}
+  if (VERBOSE) {
+    console.log(`FILE: ${file}`)
+  }
 
-function replaceRecursively(directory, excludedDirectories, allowedExtensions, original, replacement) {
-  original = new RegExp(regExpQuote(original), 'g')
-  replacement = regExpQuoteReplacement(replacement)
-  const updateFile = DRY_RUN ? filepath => {
-    if (allowedExtensions.has(path.parse(filepath).ext)) {
-      console.log(`FILE: ${filepath}`)
-    } else {
-      console.log(`EXCLUDED:${filepath}`)
-    }
-  } : filepath => {
-    if (allowedExtensions.has(path.parse(filepath).ext)) {
-      sh.sed('-i', original, replacement, filepath)
-    }
+  if (DRY_RUN) {
+    return
   }
 
-  walkAsync(directory, excludedDirectories, updateFile, err => {
-    console.error('ERROR while traversing directory!:')
-    console.error(err)
-    process.exit(1)
-  })
+  await fs.writeFile(file, newString, 'utf8')
 }
 
-function main(args) {
-  if (args.length !== 2) {
-    console.error('USAGE: change-version old_version new_version')
+async function main(args) {
+  const [oldVersion, newVersion] = args
+
+  if (!oldVersion || !newVersion) {
+    console.error('USAGE: change-version old_version new_version [--verbose] [--dry[-run]]')
     console.error('Got arguments:', args)
     process.exit(1)
   }
 
-  const oldVersion = args[0]
-  const newVersion = args[1]
-  const EXCLUDED_DIRS = new Set([
-    '.git',
-    '_site',
-    'node_modules',
-    'resources'
-  ])
-  const INCLUDED_EXTENSIONS = new Set([
-    // This extension whitelist is how we avoid modifying binary files
-    '',
-    '.css',
-    '.html',
-    '.js',
-    '.json',
-    '.md',
-    '.scss',
-    '.txt',
-    '.yml'
-  ])
-  replaceRecursively('.', EXCLUDED_DIRS, INCLUDED_EXTENSIONS, oldVersion, newVersion)
+  // Strip any leading `v` from arguments because otherwise we will end up with duplicate `v`s
+  [oldVersion, newVersion].map(arg => arg.startsWith('v') ? arg.slice(1) : arg)
+
+  try {
+    const files = await globby(GLOB, GLOBBY_OPTIONS)
+
+    await Promise.all(files.map(file => replaceRecursively(file, oldVersion, newVersion)))
+  } catch (error) {
+    console.error(error)
+    process.exit(1)
+  }
 }
 
 main(process.argv.slice(2))
index 142e09afd91ada3901f858d17bd008c80274e58f..15c7d84797509a30ff78367a549160c8f4b5b3fd 100644 (file)
     "eslint-plugin-unicorn": "^28.0.2",
     "find-unused-sass-variables": "^3.1.0",
     "glob": "^7.1.6",
+    "globby": "^11.0.2",
     "hammer-simulator": "0.0.1",
     "hugo-bin": "^0.69.0",
     "ip": "^1.1.5",