Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prettier reporter #321

Merged
merged 9 commits into from
Jul 9, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 22 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,34 @@
#!/usr/bin/env node

const { inspect } = require('util')
const files = require('./src/files')
const config = require('./src/files')
const analyse = require('./src/analyse')
const cli = require('./src/reporters/cli')
const reporter = require('./src/reporter')
const build = require('./src/build')

reporter(files)
const report = analyse(config)
cli.report(report)
// broke this
// reporter(report.files)

process.on('unhandledRejection', function(reason) {
console.log('Unhandled Promise')
console.log(inspect(reason))
build.error()
})

/*
This is the ideal structure to get to:

- utilities function
- pipe results down

start()
.then(getConfig)
.then(attachFiles)
.then(attachSize)
.then(attachComparison)
.then(reportOnCli)
.then(reportOnBuild)
*/
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,13 @@
"ci-env": "^1.4.0",
"commander": "^2.20.0",
"cosmiconfig": "^5.2.1",
"figures": "^3.0.0",
"github-build": "^1.2.0",
"glob": "^7.1.4",
"gzip-size": "^4.0.0",
"prettycli": "^1.4.3"
"plur": "^3.1.1",
"prettycli": "^1.4.3",
"right-pad": "^1.0.1"
},
"lint-staged": {
"*.js": [
Expand Down
18 changes: 18 additions & 0 deletions src/analyse.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/*
loop through files and add
pass: true|false
*/

const bytes = require('bytes')

function analyse(config) {
return config.files.map(function(row) {
row.filesMatched.map(function(file) {
if (bytes.parse(file.size) > bytes.parse(row.maxSize)) file.pass = false
else file.pass = true
})
return row
})
}

module.exports = analyse
6 changes: 3 additions & 3 deletions src/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,10 @@ if (!configFromFile && !configFromCli) {
)
}

const config = configFromCli || configFromFile
const files = configFromCli || configFromFile

debug('cli config', configFromCli)
debug('file config', configFromFile)
debug('selected config', config)
debug('selected config', files)

module.exports = config
module.exports = { files }
29 changes: 15 additions & 14 deletions src/files.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,25 @@ const { error } = require('prettycli')
const config = require('./config')
const debug = require('./debug')
const compressedSize = require('./compressed-size')
const files = []

config.map(file => {
const paths = glob.sync(file.path)
if (!paths.length) {
error(`There is no matching file for ${file.path} in ${process.cwd()}`, {
config.files.map(row => {
row.filesMatched = []

const files = glob.sync(row.path)

files.map(path => {
const compression = row.compression || 'gzip'
const size = compressedSize(fs.readFileSync(path, 'utf8'), compression)
row.filesMatched.push({ path, size })
})

if (!row.filesMatched.length) {
error(`There is no matching file for ${row.path} in ${process.cwd()}`, {
silent: true
})
} else {
paths.map(path => {
const maxSize = bytes(file.maxSize) || Infinity
const compression = file.compression || 'gzip'
const size = compressedSize(fs.readFileSync(path, 'utf8'), compression)
files.push({ maxSize, path, size, compression })
})
}
})

debug('files', files)
debug('files', config)

module.exports = files
module.exports = config
16 changes: 11 additions & 5 deletions src/reporter.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,13 @@ const getGlobalMessage = ({
const prettyChange =
change === 0
? 'no change'
: change > 0 ? `+${bytes(change)}` : `-${bytes(Math.abs(change))}`
: change > 0
? `+${bytes(change)}`
: `-${bytes(Math.abs(change))}`

globalMessage = `${failures} out of ${results.length} bundles are too big! (${prettyChange})`
globalMessage = `${failures} out of ${
results.length
} bundles are too big! (${prettyChange})`
} else {
// multiple files, no failures
const prettySize = bytes(totalSize)
Expand All @@ -64,7 +68,9 @@ const getGlobalMessage = ({
const prettyChange =
change === 0
? 'no change'
: change > 0 ? `+${bytes(change)}` : `-${bytes(Math.abs(change))}`
: change > 0
? `+${bytes(change)}`
: `-${bytes(Math.abs(change))}`

globalMessage = `Total bundle size is ${prettySize}/${prettyMaxSize} (${prettyChange})`
}
Expand Down Expand Up @@ -127,7 +133,7 @@ const analyse = ({ files, masterValues }) => {
})
}

const report = ({ files, globalMessage, fail }) => {
const globalReport = ({ files, globalMessage, fail }) => {
/* prepare the build page */
const params = encodeURIComponent(
JSON.stringify({ files, repo, branch, commit_message, sha })
Expand Down Expand Up @@ -160,7 +166,7 @@ const compare = (files, masterValues = {}) => {
})

let fail = results.filter(result => result.fail).length > 0
report({ files, globalMessage, fail })
globalReport({ files, globalMessage, fail })
}

const reporter = files => {
Expand Down
85 changes: 85 additions & 0 deletions src/reporters/cli.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
const rightpad = require('right-pad')
const figures = require('figures')
const bytes = require('bytes')
const plur = require('plur')

const colors = require('../utils/colors')

function report(results) {
const maxFileLength = getMaxFileLenght(results)

const counter = { pass: 0, fail: 0 }

results.forEach(function(row) {
printBlockHeader(row)

row.filesMatched.forEach(function(file) {
printRow(file, row, maxFileLength)

if (file.pass) counter.pass++
else counter.fail++
})
})

printSummary(counter)

// exit with error code 1 if there are any failed checks
if (counter.fail) process.exit(1)
}

module.exports = { report }

function getMaxFileLenght(results) {
let maxFileLength = 0

results.forEach(function(row) {
row.filesMatched.forEach(function(file) {
if (file.path.length > maxFileLength) maxFileLength = file.path.length
})
})

return maxFileLength
}

function printBlockHeader(row) {
console.log()
console.log(colors.subtle(`${figures.line} ${row.path}`))
}

function printRow(file, row, maxFileLength) {
const symbol = getSymbol(file)
const operator = getOperator(file, row)

console.log(
' ',
symbol,
rightpad(file.path, maxFileLength),
' ',
bytes(file.size),
operator,
row.maxSize,
colors.subtle(row.compression || 'gzip')
)
}

function printSummary({ pass, fail }) {
console.log()

if (pass) console.log(colors.pass(' ', pass, plur('check', pass), 'passed'))
if (fail) console.log(colors.fail(' ', fail, plur('check', fail), 'failed'))

console.log()
}

function getSymbol(file) {
return file.pass ? colors.pass(figures.tick) : colors.fail(figures.cross)
}

function getOperator(file, row) {
const fileSize = bytes.parse(file.size)
const maxSize = bytes.parse(row.maxSize)

if (fileSize > maxSize) return colors.fail('>')
if (fileSize === maxSize) return colors.pass('=')
return colors.pass('<')
}
9 changes: 9 additions & 0 deletions src/utils/colors.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
const chalk = require('chalk')

module.exports = {
subtle: chalk.gray,
pass: chalk.green,
fail: chalk.red,
title: chalk.bold,
info: chalk.magenta
}
64 changes: 49 additions & 15 deletions tests/snapshots/index.js.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,68 +8,102 @@ Generated by [AVA](https://ava.li).

> Snapshot 1

'PASS file-1.js: 270B < maxSize 300B (gzip)'
`─ file-1.js␊
✔ file-1.js 270B < 300B gzip␊
1 check passed`

## 10. pass: match by fuzzy name

> Snapshot 1

`PASS build/vendor-ha5h.js: 270B < maxSize 350B (gzip) ␊
`─ build/vendor-*.js␊
✔ build/vendor-ha5h.js 270B < 350B gzip␊
─ build/**/chunk-*.js␊
✔ build/chunks/chunk-ch0nk.js 270B < 300B gzip␊
PASS build/chunks/chunk-ch0nk.js: 270B < maxSize 300B (gzip)`
2 checks passed`

## 2. fail: single file larger than limit

> Snapshot 1

'FAIL file-2.js: 270B > maxSize 250B (gzip)'
`─ file-2.js␊
✖ file-2.js 270B > 250B gzip␊
1 check failed`

## 3. pass: use brotli

> Snapshot 1

'PASS file-3.js: 245B < maxSize 250B (brotli)'
`─ file-3.js␊
✔ file-3.js 245B < 250B brotli␊
1 check passed`

## 4. fail: dont use compression

> Snapshot 1

'FAIL file-4.js: 437B > maxSize 300B (no compression)'
`─ file-4.js␊
✖ file-4.js 437B > 300B none␊
1 check failed`

## 5. pass: custom config file

> Snapshot 1

'PASS file-5.js: 270B < maxSize 300B (gzip)'
`─ file-5.js␊
✔ file-5.js 270B < 300B gzip␊
1 check passed`

## 6. pass: multiple files, both smaller than limit

> Snapshot 1

`PASS file-61.js: 270B < maxSize 300B (gzip) ␊
`─ file-61.js␊
✔ file-61.js 270B < 300B gzip␊
─ file-62.js␊
✔ file-62.js 270B < 300B gzip␊
PASS file-62.js: 270B < maxSize 300B (gzip)`
2 checks passed`

## 7. fail: multiple files, both bigger than limit

> Snapshot 1

`FAIL file-61.js: 270B > maxSize 200B (gzip) ␊
`─ file-61.js␊
✖ file-61.js 270B > 200B gzip␊
FAIL file-62.js: 270B > maxSize 200B (gzip)`
─ file-62.js␊
✖ file-62.js 270B > 200B gzip␊
2 checks failed`

## 8. fail: multiple files, 1 smaller + 1 bigger than limit

> Snapshot 1

`PASS file-61.js: 270B < maxSize 300B (gzip) ␊
`─ file-61.js␊
✔ file-61.js 270B < 300B gzip␊
─ file-62.js␊
✖ file-62.js 270B > 200B gzip␊
FAIL file-62.js: 270B > maxSize 200B (gzip)`
1 check passed␊
1 check failed`

## 9. pass: catch all js files

> Snapshot 1

`PASS build/chunks/chunk-ch0nk.js: 270B < maxSize 300B (gzip) ␊
`─ build/**/*.js␊
✔ build/chunks/chunk-ch0nk.js 270B < 300B gzip␊
✔ build/vendor-ha5h.js 270B < 300B gzip␊
PASS build/vendor-ha5h.js: 270B < maxSize 300B (gzip)`
2 checks passed`
Binary file modified tests/snapshots/index.js.snap
Binary file not shown.