Skip to content

Commit

Permalink
Merge pull request #677 from primer/primer-migrate
Browse files Browse the repository at this point in the history
Add primer-migrate script
  • Loading branch information
shawnbot authored Feb 14, 2019
2 parents 45b932f + 5a70749 commit 1c9a042
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 7 deletions.
15 changes: 9 additions & 6 deletions MIGRATING.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,16 @@ If your text editor supports search and replace regular expressions, the followi

| find | replace |
| :--- | :--- |
| `primer-marketing-(\w+)/lib/` | `@primer/css/marketing/$1/` |
| `primer-marketing-(\w+)` | `@primer/css/marketing/$1` |
| `primer-(\w+)/lib/` | `@primer/css/$1/` |
| `primer-(\w+)` | `@primer/css/$1` |
| `primer/index.scss` | `@primer/css/index.scss` |
| `primer-marketing-(\w+)(\/lib)?` | `@primer/css/marketing/$1` |
| `primer-(\w+)(\/lib)?` | `@primer/css/$1` |
| `primer\b` | `@primer/css`

:warning: **If you use unqualified import paths** (e.g. `@import "primer-support"`), you will need to adjust these patterns accordingly.
#### `primer-migrate`
You can also use the included [`primer-migrate` script](bin/primer-migrate):

```sh
npx -p @primer/css primer-migrate path/to/**/*.scss
```

### Sass include paths
If you've installed Primer CSS with npm, you very likely already have `node_modules` listed in your Sass `includePaths` option, and you won't need to change anything. :tada:
Expand Down
86 changes: 86 additions & 0 deletions bin/primer-migrate
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
#!/usr/bin/env node

/**
* XXX: we use Node.js native modules only here to avoid
* requiring any runtime dependencies when folks install
* @primer/css
*/

const fs = require('fs')
const {promisify} = require('util')
const readFile = promisify(fs.readFile)
const writeFile = promisify(fs.writeFile)
const {dirname, join} = require('path')

const IMPORT_PATTERN = /\@import\s+['"]([^'"]+)['"]/g
const replacements = [
[/primer-marketing-(\w+)(\/lib)?/, '@primer/css/marketing/$1'],
[/primer-(\w+)(\/lib)?/, '@primer/css/$1'],
[/primer\b/, '@primer/css']
]

const paths = process.argv.slice(2)
const warn = (...args) => console.warn(...args)

if (paths.length) {
Promise.all(
paths.map(path => {
return migrate(path).then(reps => report(reps, path))
})
).catch(die)
} else {
readFile('/dev/stdin', 'utf8')
.then(input => {
const [output, reps] = replace(input)
report(reps, 'stdin')
process.stdout.write(output)
})
.catch(die)
}

function migrate(path) {
return readFile(path, 'utf8').then(input => {
if (!IMPORT_PATTERN.test(input)) {
warn(`No SCSS imports found in ${path}`)
return false
}

const [output, reps] = replace(input)
if (reps.length) {
return writeFile(path, output, 'utf8').then(() => reps)
} else {
return false
}
})
}

function replace(input) {
const reps = []
const output = input.replace(IMPORT_PATTERN, (str, path) => {
for (const [from, to] of replacements) {
if (from.test(path)) {
const replaced = str.replace(from, to)
reps.push([path, path.replace(from, to)])
return replaced
}
}
return str
})
return [output, reps]
}

function report(reps, path) {
if (reps.length) {
warn(`Replaced ${reps.length} imports in ${path}:`)
for (const [i, [from, to]] of Object.entries(reps)) {
warn(` ${Number(i) + 1}. (${from}) -> (${to})`)
}
} else {
warn(`No legacy imports found in ${path}`)
}
}

function die(error) {
console.error(error)
process.exitCode = 1
}
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
"github",
"design-system"
],
"bin": {
"primer-migrate": "bin/primer-migrate"
},
"scripts": {
"dist": "script/dist",
"build-storybook": "build-storybook -o build",
Expand All @@ -34,10 +37,11 @@
"start": "next dev",
"start-storybook": "start-storybook -p 8000 -c .storybook",
"sync": "script/sync",
"test": "npm-run-all -s test-jest test-urls",
"test": "npm-run-all -s test-jest test-urls test-migrate",
"test-all-modules": "ava --verbose tests/test-*.js",
"test-jest": "jest --passWithNoTests",
"test-urls": "npm run sync && node docs-test/urls.js",
"test-migrate": "script/test-migrate",
"watch": "script/sync --watch"
},
"devDependencies": {
Expand Down
35 changes: 35 additions & 0 deletions script/test-migrate
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/bin/bash
set -e

dir=$(mktemp -d)

cat << BEFORE > $dir/input.scss
@import 'primer-core/index.scss';
@import "primer/index.scss";
@import "primer-marketing-utilities/index.scss";
@import "primer-marketing-utilities/lib/layout.scss";
@import "../node_modules/primer-product/index.scss";
@import "primer-product";
@import "primer";
@import "primer-avatars/lib/avatar.scss";
@import "primer-navigation/lib/subnav.scss";
BEFORE

cat << AFTER > $dir/expected.scss
@import '@primer/css/core/index.scss';
@import "@primer/css/index.scss";
@import "@primer/css/marketing/utilities/index.scss";
@import "@primer/css/marketing/utilities/layout.scss";
@import "../node_modules/@primer/css/product/index.scss";
@import "@primer/css/product";
@import "@primer/css";
@import "@primer/css/avatars/avatar.scss";
@import "@primer/css/navigation/subnav.scss";
AFTER

cat $dir/input.scss | bin/primer-migrate > $dir/output.scss
diff $dir/{expected,output}.scss || (
echo "Uh-oh, there was a diff!"
exit 1
)
echo "Success!"

0 comments on commit 1c9a042

Please sign in to comment.