Skip to content

Commit

Permalink
Fix TextBox vs Textbox filename collision on case-insensitive filesys…
Browse files Browse the repository at this point in the history
…tems. #30
  • Loading branch information
leMaik committed Apr 8, 2020
1 parent eb96a43 commit bd12f50
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 9 deletions.
6 changes: 6 additions & 0 deletions filenameMap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// There are icons names that, when converted to PascalCase, only differ in casing. This is
// problematic on file systems that are not case-sensitive.
// See TeamWertarbyte/mdi-material-ui#30 for more information
module.exports = {
TextBox: 'Text-Box' // textbox vs. text-box
}
39 changes: 31 additions & 8 deletions generate-module.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,60 +4,83 @@ const path = require('path')
const pascalCase = require('pascal-case')
const babel = require('babel-core')
const pick = require('lodash.pick')
const filenameMap = require('./filenameMap')

;(async () => {
function checkNameClashes (icons) {
const caseNameClashes = icons.filter(
(icon) =>
icon.filename == null &&
icons.filter(
(icon2) =>
icon2.filename == null &&
icon2.name.toLowerCase() === icon.name.toLowerCase()
).length > 1
)
if (caseNameClashes.length > 0) {
throw new Error(
`The following icons have the same file name (case insensitive): ${caseNameClashes
.map((icon) => icon.name)
.join(', ')}`
)
}
}

(async () => {
const icons = Object.entries(require('@mdi/js'))
.filter(([name]) => name.indexOf('mdi') === 0)
.map(([name, path]) => ({
name: pascalCase(name.substr(3)), // remove mdi prefix
filename: filenameMap[name.substr(3)],
svgPath: path
}))
checkNameClashes(icons)

const lightIcons = Object.entries(require('@mdi/light-js'))
.filter(([name]) => name.indexOf('mdil') === 0)
.map(([name, path]) => ({
name: pascalCase(name.substr(4)), // remove mdil prefix
svgPath: path
}))
checkNameClashes(lightIcons)

fse.removeSync(path.join(__dirname, 'package'))
fse.mkdirpSync(path.join(__dirname, 'package', 'light'))

for (const { name, svgPath } of icons) {
for (const { name, filename, svgPath } of icons) {
const code = `import createIcon from './util/createIcon'
export default createIcon('${svgPath}')
`

// commonjs module syntax
fse.writeFileSync(path.join(__dirname, 'package', `${name}.js`), babel.transform(code, {
fse.writeFileSync(path.join(__dirname, 'package', `${filename || name}.js`), babel.transform(code, {
presets: ['es2015', 'react', 'stage-0'],
compact: process.env.NODE_ENV === 'production'
}).code)

// typescript definition
fse.writeFileSync(path.join(__dirname, 'package', `${name}.d.ts`), `export { default } from '@material-ui/core/SvgIcon'
fse.writeFileSync(path.join(__dirname, 'package', `${filename || name}.d.ts`), `export { default } from '@material-ui/core/SvgIcon'
`)
}

for (const { name, svgPath } of lightIcons) {
for (const { name, filename, svgPath } of lightIcons) {
const code = `import createIcon from '../util/createIcon'
export default createIcon('${svgPath}')
`

// commonjs module syntax
fse.writeFileSync(path.join(__dirname, 'package', 'light', `${name}.js`), babel.transform(code, {
fse.writeFileSync(path.join(__dirname, 'package', 'light', `${filename || name}.js`), babel.transform(code, {
presets: ['es2015', 'react', 'stage-0'],
compact: process.env.NODE_ENV === 'production'
}).code)

// typescript definition
fse.writeFileSync(path.join(__dirname, 'package', 'light', `${name}.d.ts`), `export { default } from '@material-ui/core/SvgIcon'
fse.writeFileSync(path.join(__dirname, 'package', 'light', `${filename || name}.d.ts`), `export { default } from '@material-ui/core/SvgIcon'
`)
}

const generateIndexFiles = (destination, icons) => {
// es2015 module syntax
const allExports = icons.map(({ name }) => `export { default as ${name} } from './${name}'`).join('\n')
const allExports = icons.map(({ name, filename }) => `export { default as ${name} } from './${filename || name}'`).join('\n')
fse.writeFileSync(path.join(destination, 'index.es.js'), allExports)

// typescript index definition (looks exactly the same)
Expand Down
3 changes: 2 additions & 1 deletion test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import test from 'ava'
import React from 'react'
import renderer from 'react-test-renderer'
import fs from 'fs'
const filenameMap = require('./filenameMap')
const commonjsIcons = require('./package/index')
const commonjsIconsLight = require('./package/light/index')

Expand All @@ -27,7 +28,7 @@ test('ES module index file', (t) => {

for (const line of esmReExports) {
const match = line.match(/^export \{ default as (.+?) \} from '\.\/(.+?)'$/)
t.is(match[1], match[2])
t.is(filenameMap[match[1]] || match[1], match[2])
t.truthy(commonjsIcons[match[1]])
}
})
Expand Down
1 change: 1 addition & 0 deletions update.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#!/bin/sh
npm i --save-dev @mdi/js@latest @mdi/light-js@latest
./generate-module.js
npm test

VERSION=`cat node_modules/@mdi/js/package.json | jq -r .version`
git add --all
Expand Down

0 comments on commit bd12f50

Please sign in to comment.