mirror of
https://github.com/twbs/bootstrap.git
synced 2025-09-01 01:21:49 +02:00
Try a new approach
This commit is contained in:
74
build/diff.mjs
Normal file
74
build/diff.mjs
Normal file
@@ -0,0 +1,74 @@
|
||||
// import * as path from 'path';
|
||||
import * as fs from 'fs/promises';
|
||||
import * as diff from 'fast-array-diff';
|
||||
// import { argv } from 'node:process';
|
||||
import { getCssClasses } from './getCssClasses.mjs';
|
||||
|
||||
// TODO: not run this script all the time
|
||||
// TODO: retrieve the lists of Bootstrap versions (with GitHub API)
|
||||
const versions = ["4.6.2", "5.0.0", "5.1.3"]
|
||||
const currentVersion = "5.3.0"
|
||||
const currentShortVersion = "5.3"
|
||||
|
||||
const currentVersionClasses = await getCssClasses('dist/css/bootstrap.css')
|
||||
|
||||
for (const version of versions) {
|
||||
const bootstrapCssPath = `https://cdn.jsdelivr.net/npm/bootstrap@${version}/dist/css/bootstrap.css`
|
||||
|
||||
const versionClasses = await getCssClasses(bootstrapCssPath)
|
||||
|
||||
const outputJSONContent = diff.diff(
|
||||
versionClasses.classes,
|
||||
currentVersionClasses.classes
|
||||
)
|
||||
|
||||
outputJSONContent['same'] = diff.same(
|
||||
versionClasses.classes,
|
||||
currentVersionClasses.classes
|
||||
)
|
||||
|
||||
const outputFileDir = `./site/static/docs/${currentShortVersion}/assets/json/diffs/`
|
||||
await fs.mkdir(outputFileDir, { recursive: true })
|
||||
|
||||
const outputFilePath = `${outputFileDir}/bootstrap-from-${version}-to-${currentVersion}.diff.json`
|
||||
await fs.writeFile(outputFilePath, JSON.stringify(outputJSONContent))
|
||||
}
|
||||
|
||||
/*
|
||||
try {
|
||||
const args = argv.slice(2);
|
||||
|
||||
// TODO: check the size of args: must be 2
|
||||
const fromPath = args[0]
|
||||
const toPath = args[1]
|
||||
|
||||
const from = await fs.readFile(fromPath, 'utf8');
|
||||
const to = await fs.readFile(toPath, 'utf8');
|
||||
|
||||
const fromClasses = JSON.parse(from)["classes"];
|
||||
const toClasses = JSON.parse(to)["classes"];
|
||||
|
||||
const outputJSONContent = diff.diff(
|
||||
fromClasses,
|
||||
toClasses
|
||||
)
|
||||
|
||||
outputJSONContent['same'] = diff.same(
|
||||
fromClasses,
|
||||
toClasses
|
||||
)
|
||||
|
||||
// TODO: add "from"/"to" keys?
|
||||
|
||||
const outputFilePath = args[2] ?? `from_${path.parse(fromPath).name}_to_${path.parse(toPath).name}.diff.json`
|
||||
await fs.writeFile(outputFilePath, JSON.stringify(outputJSONContent))
|
||||
}
|
||||
catch(error) {
|
||||
// console.log(error)
|
||||
console.log(`Usage: node diff.mjs <fromPath> <toPath> <outputPath>
|
||||
- fromPath: JSON file
|
||||
- toPath: JSON file
|
||||
- outputPath: JSON file (optional). Default value will be 'from_<fromPath>_to_<toPath>.diff.json'
|
||||
`)
|
||||
}
|
||||
*/
|
@@ -1,89 +0,0 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/*!
|
||||
* Script to update our glossary semi-automatically based on bootstrap.css.
|
||||
* Copyright 2017-2022 The Bootstrap Authors
|
||||
* Copyright 2017-2022 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
|
||||
*/
|
||||
|
||||
'use strict'
|
||||
|
||||
const fs = require('fs')
|
||||
|
||||
fs.readFile('../dist/css/bootstrap.css', 'utf8', (error, data) => {
|
||||
if (error) {
|
||||
throw error
|
||||
}
|
||||
|
||||
// TODO: bootstrap.css should be stripped of its comments to avoid having .map and other elements in the array
|
||||
|
||||
// TODO: previous re was /\.[a-zA-Z]([0-9a-zA-Z]*-)*[0-9a-zA-Z]*/gi, optimized
|
||||
const re = /\.[a-z]([\da-z]*-)*[\da-z]*/gi
|
||||
|
||||
const matches = [...data.matchAll(re)]
|
||||
|
||||
// Array.from will build an array with just the matching strings
|
||||
// .sort() will sort those matching strings in the array
|
||||
// Array.from(new Set(...)) will remove the duplicate entries
|
||||
const results = Array.from(new Set(Array.from(matches, m => m[0]).sort()))
|
||||
|
||||
let newContent = ''
|
||||
|
||||
for (const result of results) {
|
||||
newContent += result + ':\r\n'
|
||||
}
|
||||
|
||||
// Create a temp file containing all classes names as keys and empty values
|
||||
fs.writeFile('../site/static/docs/5.3/assets/data/glossary.data.temp', newContent, error => {
|
||||
if (error) {
|
||||
throw error
|
||||
}
|
||||
})
|
||||
|
||||
// Compare what's inside our glossary.data and the temp glossary to:
|
||||
// - remove in glossary.data what doesn't exist anymore
|
||||
// - add the keys in glossary.data that should be completed with the corresponding links manually
|
||||
fs.readFile('../site/static/docs/5.3/assets/data/glossary.data', 'utf8', (error, data) => {
|
||||
if (error) {
|
||||
throw error
|
||||
}
|
||||
|
||||
const newContentSplit = newContent.split('\r\n')
|
||||
const finalContentArray = []
|
||||
|
||||
// Find all elements that are already in our glossary
|
||||
// Remove elements that are not in the temp glossary
|
||||
for (const d of data.split('\r\n')) {
|
||||
const found = newContentSplit.find(elt => elt.split(':')[0] === d.split(':')[0])
|
||||
if (found) {
|
||||
// finalContent += d + '\r\n'
|
||||
finalContentArray.push(d + '\r\n')
|
||||
}
|
||||
}
|
||||
|
||||
// Add elements that are new in the temp glossary
|
||||
for (const d of newContentSplit) {
|
||||
// Avoid adding empty lines
|
||||
if (d) {
|
||||
const found = data.split('\r\n').find(elt => elt.split(':')[0] === d.split(':')[0])
|
||||
if (!found) {
|
||||
// finalContent += d + '\r\n'
|
||||
finalContentArray.push(d + '\r\n')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fs.writeFile('../site/static/docs/5.3/assets/data/glossary.data', finalContentArray.sort().join(''), { flag: 'w' }, error => {
|
||||
if (error) {
|
||||
throw error
|
||||
}
|
||||
})
|
||||
|
||||
fs.unlink('../site/static/docs/5.3/assets/data/glossary.data.temp', error => {
|
||||
if (error) {
|
||||
throw error
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
9
build/getCssClasses.mjs
Normal file
9
build/getCssClasses.mjs
Normal file
@@ -0,0 +1,9 @@
|
||||
import listSelectors from 'list-selectors';
|
||||
|
||||
export async function getCssClasses(filePath) {
|
||||
return new Promise((resolve, reject) => {
|
||||
listSelectors(filePath, { include: ['classes'] }, (result) => {
|
||||
resolve(result);
|
||||
});
|
||||
})
|
||||
}
|
22
build/glossary.mjs
Normal file
22
build/glossary.mjs
Normal file
@@ -0,0 +1,22 @@
|
||||
import * as path from 'path';
|
||||
import { argv } from 'node:process';
|
||||
import * as fs from 'fs/promises';
|
||||
import { getCssClasses } from './getCssClasses.mjs';
|
||||
|
||||
try {
|
||||
const args = argv.slice(2);
|
||||
|
||||
const fileClasses = await getCssClasses(args[0]);
|
||||
|
||||
const outputFilePath = args[1] ?? `${path.parse(args[0]).name}.json`
|
||||
|
||||
await fs.writeFile(outputFilePath, JSON.stringify(fileClasses))
|
||||
}
|
||||
catch (error) {
|
||||
// console.log(error)
|
||||
// TODO: inputPath could be an HTTP link
|
||||
console.log(`Usage: node glossary.mjs <inputPath> <outputPath>
|
||||
- inputPath: CSS file to parse
|
||||
- outputPath: JSON file (optional). Default value is: <inputPath>.json
|
||||
`)
|
||||
}
|
Reference in New Issue
Block a user