This commit is contained in:
Connor Peet 2019-05-08 13:06:07 -07:00
Коммит b0856fdbc2
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: CF8FD2EA0DBC61BD
14 изменённых файлов: 1268 добавлений и 0 удалений

82
.gitignore поставляемый Normal file
Просмотреть файл

@ -0,0 +1,82 @@
# Created by https://www.gitignore.io/api/node
### Node ###
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
# parcel-bundler cache (https://parceljs.org/)
.cache
# next.js build output
.next
# nuxt.js build output
.nuxt
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless
# End of https://www.gitignore.io/api/node
/dist

2
.npmignore Normal file
Просмотреть файл

@ -0,0 +1,2 @@
/*
!/dist

21
LICENSE Normal file
Просмотреть файл

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) Microsoft Corporation
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

692
package-lock.json сгенерированный Normal file
Просмотреть файл

@ -0,0 +1,692 @@
{
"name": "@mixer/parallel-prettier",
"version": "1.0.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
"@babel/code-frame": {
"version": "7.0.0",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/@babel/code-frame/-/code-frame-7.0.0.tgz",
"integrity": "sha1-BuKrGb21NThVWaq7W6WXKUgoAPg=",
"dev": true,
"requires": {
"@babel/highlight": "^7.0.0"
}
},
"@babel/highlight": {
"version": "7.0.0",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/@babel/highlight/-/highlight-7.0.0.tgz",
"integrity": "sha1-9xDDjI1Fjm3ZogGvtjf8t4HOmeQ=",
"dev": true,
"requires": {
"chalk": "^2.0.0",
"esutils": "^2.0.2",
"js-tokens": "^4.0.0"
}
},
"@types/events": {
"version": "3.0.0",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/@types/events/-/events-3.0.0.tgz",
"integrity": "sha1-KGLz9Yqaf3w+eNefEw3U1xwlwqc=",
"dev": true
},
"@types/glob": {
"version": "7.1.1",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/@types/glob/-/glob-7.1.1.tgz",
"integrity": "sha1-qlmhxuP7xCHgfM0xqUTDDrpSFXU=",
"dev": true,
"requires": {
"@types/events": "*",
"@types/minimatch": "*",
"@types/node": "*"
}
},
"@types/glob-stream": {
"version": "6.1.0",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/@types/glob-stream/-/glob-stream-6.1.0.tgz",
"integrity": "sha1-ft6KM+WRQFNPjYrfuKye37MYl7w=",
"dev": true,
"requires": {
"@types/glob": "*",
"@types/node": "*"
}
},
"@types/minimatch": {
"version": "3.0.3",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/@types/minimatch/-/minimatch-3.0.3.tgz",
"integrity": "sha1-PcoOPzOyAPx9ETnAzZbBJoyt/Z0=",
"dev": true
},
"@types/node": {
"version": "12.0.0",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/@types/node/-/node-12.0.0.tgz",
"integrity": "sha1-0RgTucD/iqyinwTLwSgX9MfWVuU=",
"dev": true
},
"@types/prettier": {
"version": "1.16.3",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/@types/prettier/-/prettier-1.16.3.tgz",
"integrity": "sha1-FBvfTcuqwG/Ss/BeIz/yO2aGb58=",
"dev": true
},
"ansi-regex": {
"version": "4.1.0",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/ansi-regex/-/ansi-regex-4.1.0.tgz",
"integrity": "sha1-i5+PCM8ay4Q3Vqg5yox+MWjFGZc="
},
"ansi-styles": {
"version": "3.2.1",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/ansi-styles/-/ansi-styles-3.2.1.tgz",
"integrity": "sha1-QfuyAkPlCxK+DwS43tvwdSDOhB0=",
"requires": {
"color-convert": "^1.9.0"
}
},
"argparse": {
"version": "1.0.10",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/argparse/-/argparse-1.0.10.tgz",
"integrity": "sha1-vNZ5HqWuCXJeF+WtmIE0zUCz2RE=",
"dev": true,
"requires": {
"sprintf-js": "~1.0.2"
}
},
"balanced-match": {
"version": "1.0.0",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
},
"brace-expansion": {
"version": "1.1.11",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0=",
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"builtin-modules": {
"version": "1.1.1",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/builtin-modules/-/builtin-modules-1.1.1.tgz",
"integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
"dev": true
},
"chalk": {
"version": "2.4.2",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/chalk/-/chalk-2.4.2.tgz",
"integrity": "sha1-zUJUFnelQzPPVBpJEIwUMrRMlCQ=",
"requires": {
"ansi-styles": "^3.2.1",
"escape-string-regexp": "^1.0.5",
"supports-color": "^5.3.0"
}
},
"cli-cursor": {
"version": "2.1.0",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/cli-cursor/-/cli-cursor-2.1.0.tgz",
"integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
"requires": {
"restore-cursor": "^2.0.0"
}
},
"cli-spinners": {
"version": "2.1.0",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/cli-spinners/-/cli-spinners-2.1.0.tgz",
"integrity": "sha1-IsNLTVH1cyQIhbIB79pOTsn/88c="
},
"clone": {
"version": "1.0.4",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/clone/-/clone-1.0.4.tgz",
"integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4="
},
"color-convert": {
"version": "1.9.3",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/color-convert/-/color-convert-1.9.3.tgz",
"integrity": "sha1-u3GFBpDh8TZWfeYp0tVHHe2kweg=",
"requires": {
"color-name": "1.1.3"
}
},
"color-name": {
"version": "1.1.3",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/color-name/-/color-name-1.1.3.tgz",
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU="
},
"commander": {
"version": "2.20.0",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/commander/-/commander-2.20.0.tgz",
"integrity": "sha1-1YuytcHuj4ew00ACfp6U4iLFpCI="
},
"concat-map": {
"version": "0.0.1",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
},
"core-util-is": {
"version": "1.0.2",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/core-util-is/-/core-util-is-1.0.2.tgz",
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
},
"defaults": {
"version": "1.0.3",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/defaults/-/defaults-1.0.3.tgz",
"integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=",
"requires": {
"clone": "^1.0.2"
}
},
"diff": {
"version": "3.5.0",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/diff/-/diff-3.5.0.tgz",
"integrity": "sha1-gAwN0eCov7yVg1wgKtIg/jF+WhI=",
"dev": true
},
"duplexify": {
"version": "3.7.1",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/duplexify/-/duplexify-3.7.1.tgz",
"integrity": "sha1-Kk31MX9sz9kfhtb9JdjYoQO4gwk=",
"requires": {
"end-of-stream": "^1.0.0",
"inherits": "^2.0.1",
"readable-stream": "^2.0.0",
"stream-shift": "^1.0.0"
}
},
"end-of-stream": {
"version": "1.4.1",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/end-of-stream/-/end-of-stream-1.4.1.tgz",
"integrity": "sha1-7SljTRm6ukY7bOa4CjchPqtx7EM=",
"requires": {
"once": "^1.4.0"
}
},
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
},
"esprima": {
"version": "4.0.1",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/esprima/-/esprima-4.0.1.tgz",
"integrity": "sha1-E7BM2z5sXRnfkatph6hpVhmwqnE=",
"dev": true
},
"esutils": {
"version": "2.0.2",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/esutils/-/esutils-2.0.2.tgz",
"integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
"dev": true
},
"extend": {
"version": "3.0.2",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/extend/-/extend-3.0.2.tgz",
"integrity": "sha1-+LETa0Bx+9jrFAr/hYsQGewpFfo="
},
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
},
"glob": {
"version": "7.1.4",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/glob/-/glob-7.1.4.tgz",
"integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
"requires": {
"fs.realpath": "^1.0.0",
"inflight": "^1.0.4",
"inherits": "2",
"minimatch": "^3.0.4",
"once": "^1.3.0",
"path-is-absolute": "^1.0.0"
}
},
"glob-parent": {
"version": "3.1.0",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/glob-parent/-/glob-parent-3.1.0.tgz",
"integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
"requires": {
"is-glob": "^3.1.0",
"path-dirname": "^1.0.0"
},
"dependencies": {
"is-glob": {
"version": "3.1.0",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/is-glob/-/is-glob-3.1.0.tgz",
"integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
"requires": {
"is-extglob": "^2.1.0"
}
}
}
},
"glob-stream": {
"version": "6.1.0",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/glob-stream/-/glob-stream-6.1.0.tgz",
"integrity": "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=",
"requires": {
"extend": "^3.0.0",
"glob": "^7.1.1",
"glob-parent": "^3.1.0",
"is-negated-glob": "^1.0.0",
"ordered-read-streams": "^1.0.0",
"pumpify": "^1.3.5",
"readable-stream": "^2.1.5",
"remove-trailing-separator": "^1.0.1",
"to-absolute-glob": "^2.0.0",
"unique-stream": "^2.0.2"
}
},
"has-flag": {
"version": "3.0.0",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
},
"inflight": {
"version": "1.0.6",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"requires": {
"once": "^1.3.0",
"wrappy": "1"
}
},
"inherits": {
"version": "2.0.3",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/inherits/-/inherits-2.0.3.tgz",
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
},
"is-absolute": {
"version": "1.0.0",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/is-absolute/-/is-absolute-1.0.0.tgz",
"integrity": "sha1-OV4a6EsR8mrReV5zwXN45IowFXY=",
"requires": {
"is-relative": "^1.0.0",
"is-windows": "^1.0.1"
}
},
"is-extglob": {
"version": "2.1.1",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI="
},
"is-negated-glob": {
"version": "1.0.0",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/is-negated-glob/-/is-negated-glob-1.0.0.tgz",
"integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI="
},
"is-relative": {
"version": "1.0.0",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/is-relative/-/is-relative-1.0.0.tgz",
"integrity": "sha1-obtpNc6MXboei5dUubLcwCDiJg0=",
"requires": {
"is-unc-path": "^1.0.0"
}
},
"is-unc-path": {
"version": "1.0.0",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/is-unc-path/-/is-unc-path-1.0.0.tgz",
"integrity": "sha1-1zHoiY7QkKEsNSrS6u1Qla0yLJ0=",
"requires": {
"unc-path-regex": "^0.1.2"
}
},
"is-windows": {
"version": "1.0.2",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/is-windows/-/is-windows-1.0.2.tgz",
"integrity": "sha1-0YUOuXkezRjmGCzhKjDzlmNLsZ0="
},
"isarray": {
"version": "1.0.0",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/isarray/-/isarray-1.0.0.tgz",
"integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
},
"js-tokens": {
"version": "4.0.0",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha1-GSA/tZmR35jjoocFDUZHzerzJJk=",
"dev": true
},
"js-yaml": {
"version": "3.13.1",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/js-yaml/-/js-yaml-3.13.1.tgz",
"integrity": "sha1-r/FRswv9+o5J4F2iLnQV6d+jeEc=",
"dev": true,
"requires": {
"argparse": "^1.0.7",
"esprima": "^4.0.0"
}
},
"json-stable-stringify-without-jsonify": {
"version": "1.0.1",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
"integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE="
},
"log-symbols": {
"version": "2.2.0",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/log-symbols/-/log-symbols-2.2.0.tgz",
"integrity": "sha1-V0Dhxdbw39pK2TI7UzIQfva0xAo=",
"requires": {
"chalk": "^2.0.1"
}
},
"mimic-fn": {
"version": "1.2.0",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/mimic-fn/-/mimic-fn-1.2.0.tgz",
"integrity": "sha1-ggyGo5M0ZA6ZUWkovQP8qIBX0CI="
},
"minimatch": {
"version": "3.0.4",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=",
"requires": {
"brace-expansion": "^1.1.7"
}
},
"mkdirp": {
"version": "0.5.1",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/mkdirp/-/mkdirp-0.5.1.tgz",
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
"dev": true,
"requires": {
"minimist": "0.0.8"
},
"dependencies": {
"minimist": {
"version": "0.0.8",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/minimist/-/minimist-0.0.8.tgz",
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
"dev": true
}
}
},
"once": {
"version": "1.4.0",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"requires": {
"wrappy": "1"
}
},
"onetime": {
"version": "2.0.1",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/onetime/-/onetime-2.0.1.tgz",
"integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
"requires": {
"mimic-fn": "^1.0.0"
}
},
"ora": {
"version": "3.4.0",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/ora/-/ora-3.4.0.tgz",
"integrity": "sha1-vwdSSRBZo+8+1MhQl1Md6f280xg=",
"requires": {
"chalk": "^2.4.2",
"cli-cursor": "^2.1.0",
"cli-spinners": "^2.0.0",
"log-symbols": "^2.2.0",
"strip-ansi": "^5.2.0",
"wcwidth": "^1.0.1"
}
},
"ordered-read-streams": {
"version": "1.0.1",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz",
"integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=",
"requires": {
"readable-stream": "^2.0.1"
}
},
"path-dirname": {
"version": "1.0.2",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/path-dirname/-/path-dirname-1.0.2.tgz",
"integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA="
},
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
},
"path-parse": {
"version": "1.0.6",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/path-parse/-/path-parse-1.0.6.tgz",
"integrity": "sha1-1i27VnlAXXLEc37FhgDp3c8G0kw=",
"dev": true
},
"prettier": {
"version": "1.17.0",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/prettier/-/prettier-1.17.0.tgz",
"integrity": "sha1-U7MDZ27tIswUqfDOwJtHezAmwAg="
},
"process-nextick-args": {
"version": "2.0.0",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
"integrity": "sha1-o31zL0JxtKsa0HDTVQjoKQeI/6o="
},
"pump": {
"version": "2.0.1",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/pump/-/pump-2.0.1.tgz",
"integrity": "sha1-Ejma3W5M91Jtlzy8i1zi4pCLOQk=",
"requires": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
}
},
"pumpify": {
"version": "1.5.1",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/pumpify/-/pumpify-1.5.1.tgz",
"integrity": "sha1-NlE74karJ1cLGjdKXOJ4v9dDcM4=",
"requires": {
"duplexify": "^3.6.0",
"inherits": "^2.0.3",
"pump": "^2.0.0"
}
},
"readable-stream": {
"version": "2.3.6",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/readable-stream/-/readable-stream-2.3.6.tgz",
"integrity": "sha1-sRwn2IuP8fvgcGQ8+UsMea4bCq8=",
"requires": {
"core-util-is": "~1.0.0",
"inherits": "~2.0.3",
"isarray": "~1.0.0",
"process-nextick-args": "~2.0.0",
"safe-buffer": "~5.1.1",
"string_decoder": "~1.1.1",
"util-deprecate": "~1.0.1"
}
},
"remove-trailing-separator": {
"version": "1.1.0",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
"integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8="
},
"resolve": {
"version": "1.10.1",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/resolve/-/resolve-1.10.1.tgz",
"integrity": "sha1-ZkhCrJYHlbvnWCIc3M2mH7ZLXxg=",
"dev": true,
"requires": {
"path-parse": "^1.0.6"
}
},
"restore-cursor": {
"version": "2.0.0",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/restore-cursor/-/restore-cursor-2.0.0.tgz",
"integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
"requires": {
"onetime": "^2.0.0",
"signal-exit": "^3.0.2"
}
},
"rxjs": {
"version": "6.5.1",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/rxjs/-/rxjs-6.5.1.tgz",
"integrity": "sha1-96AFqThjYZIbhSTzj1TL+A5dCPQ=",
"requires": {
"tslib": "^1.9.0"
}
},
"safe-buffer": {
"version": "5.1.2",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/safe-buffer/-/safe-buffer-5.1.2.tgz",
"integrity": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0="
},
"semver": {
"version": "5.7.0",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/semver/-/semver-5.7.0.tgz",
"integrity": "sha1-eQp89v6lRZuslhELKbYEEtyP+Ws=",
"dev": true
},
"signal-exit": {
"version": "3.0.2",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/signal-exit/-/signal-exit-3.0.2.tgz",
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
},
"sprintf-js": {
"version": "1.0.3",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/sprintf-js/-/sprintf-js-1.0.3.tgz",
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
"dev": true
},
"stream-shift": {
"version": "1.0.0",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/stream-shift/-/stream-shift-1.0.0.tgz",
"integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI="
},
"string_decoder": {
"version": "1.1.1",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/string_decoder/-/string_decoder-1.1.1.tgz",
"integrity": "sha1-nPFhG6YmhdcDCunkujQUnDrwP8g=",
"requires": {
"safe-buffer": "~5.1.0"
}
},
"strip-ansi": {
"version": "5.2.0",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/strip-ansi/-/strip-ansi-5.2.0.tgz",
"integrity": "sha1-jJpTb+tq/JYr36WxBKUJHBrZwK4=",
"requires": {
"ansi-regex": "^4.1.0"
}
},
"supports-color": {
"version": "5.5.0",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha1-4uaaRKyHcveKHsCzW2id9lMO/I8=",
"requires": {
"has-flag": "^3.0.0"
}
},
"through2": {
"version": "2.0.5",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/through2/-/through2-2.0.5.tgz",
"integrity": "sha1-AcHjnrMdB8t9A6lqcIIyYLIxMs0=",
"requires": {
"readable-stream": "~2.3.6",
"xtend": "~4.0.1"
}
},
"through2-filter": {
"version": "3.0.0",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/through2-filter/-/through2-filter-3.0.0.tgz",
"integrity": "sha1-cA54bfI2fCyIzYqlvkz5weeDElQ=",
"requires": {
"through2": "~2.0.0",
"xtend": "~4.0.0"
}
},
"to-absolute-glob": {
"version": "2.0.2",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz",
"integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=",
"requires": {
"is-absolute": "^1.0.0",
"is-negated-glob": "^1.0.0"
}
},
"tslib": {
"version": "1.9.3",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/tslib/-/tslib-1.9.3.tgz",
"integrity": "sha1-1+TdeSRdhUKMTX5IIqeZF5VMooY="
},
"tslint": {
"version": "5.16.0",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/tslint/-/tslint-5.16.0.tgz",
"integrity": "sha1-rmH5xamNKVuaT0VTsbHoMcGYTWc=",
"dev": true,
"requires": {
"@babel/code-frame": "^7.0.0",
"builtin-modules": "^1.1.1",
"chalk": "^2.3.0",
"commander": "^2.12.1",
"diff": "^3.2.0",
"glob": "^7.1.1",
"js-yaml": "^3.13.0",
"minimatch": "^3.0.4",
"mkdirp": "^0.5.1",
"resolve": "^1.3.2",
"semver": "^5.3.0",
"tslib": "^1.8.0",
"tsutils": "^2.29.0"
}
},
"tslint-config-prettier": {
"version": "1.18.0",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz",
"integrity": "sha1-dfFAvelH012PDSOODr+AnWRZLDc=",
"dev": true
},
"tsutils": {
"version": "2.29.0",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/tsutils/-/tsutils-2.29.0.tgz",
"integrity": "sha1-MrSIUBRnrL7dS4VJhnOggSrKC5k=",
"dev": true,
"requires": {
"tslib": "^1.8.1"
}
},
"typescript": {
"version": "3.4.5",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/typescript/-/typescript-3.4.5.tgz",
"integrity": "sha1-LSYY0Qu1ZlcrjXqtUYDYQlfXCpk=",
"dev": true
},
"unc-path-regex": {
"version": "0.1.2",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/unc-path-regex/-/unc-path-regex-0.1.2.tgz",
"integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo="
},
"unique-stream": {
"version": "2.3.1",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/unique-stream/-/unique-stream-2.3.1.tgz",
"integrity": "sha1-xl0RDppK35psWUiygFPZqNBMvqw=",
"requires": {
"json-stable-stringify-without-jsonify": "^1.0.1",
"through2-filter": "^3.0.0"
}
},
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/util-deprecate/-/util-deprecate-1.0.2.tgz",
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
},
"wcwidth": {
"version": "1.0.1",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/wcwidth/-/wcwidth-1.0.1.tgz",
"integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=",
"requires": {
"defaults": "^1.0.3"
}
},
"wrappy": {
"version": "1.0.2",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
},
"xtend": {
"version": "4.0.1",
"resolved": "https://watchmixer.pkgs.visualstudio.com/_packaging/mixer/npm/registry/xtend/-/xtend-4.0.1.tgz",
"integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68="
}
}
}

55
package.json Normal file
Просмотреть файл

@ -0,0 +1,55 @@
{
"name": "@mixer/parallel-prettier",
"version": "1.0.0",
"description": "Concurrent prettier runner",
"main": "./dist/index.js",
"bin": {
"pprettier": "./dist/index.js"
},
"scripts": {
"prepare": "tsc",
"build": "tsc",
"fmt": "node dist/index --write \"src/**/*.ts\" && npm run test:lint -- --fix",
"test": "npm run test:lint && npm run test:fmt",
"test:lint": "tslint --project tsconfig.json \"src/**/*.ts\"",
"test:fmt": "node dist/index \"src/**/*.ts\" --check"
},
"repository": {
"type": "git",
"url": "git+https://github.com/mixer/parallel-prettier.git"
},
"keywords": [
"prettier",
"parallel",
"concurrent",
"mixer"
],
"author": "Connor Peet <connor@peet.io>",
"license": "MIT",
"bugs": {
"url": "https://github.com/mixer/parallel-prettier/issues"
},
"homepage": "https://github.com/mixer/parallel-prettier#readme",
"dependencies": {
"chalk": "^2.4.2",
"commander": "^2.20.0",
"glob-stream": "^6.1.0",
"ora": "^3.4.0",
"prettier": "^1.17.0",
"rxjs": "^6.5.1"
},
"devDependencies": {
"@types/glob-stream": "^6.1.0",
"@types/node": "^12.0.0",
"@types/prettier": "^1.16.3",
"tslint": "^5.16.0",
"tslint-config-prettier": "^1.18.0",
"typescript": "^3.4.5"
},
"prettier": {
"trailingComma": "all",
"singleQuote": true,
"printWidth": 100,
"tabWidth": 2
}
}

23
readme.md Normal file
Просмотреть файл

@ -0,0 +1,23 @@
# @mixer/parallel-prettier
A wrapper around [prettier]() that formats files in parallel to speed up large projects.
```
npm install -g @mixer/parallel-prettier
```
After installing the CLI, the `pprettier` command will be available to you.
### Ad-hoc Performance
```
# 300 file project:
prettier --write "src/**/*.{ts,tsx,json,scss}" 6.57s user 0.55s system 131% cpu 5.405 total
pprettier --write "src/**/*.{ts,tsx,json,scss}" 0.41s user 0.08s system 14% cpu 3.455 total
# 1200 file project:
prettier --write "src/**/*.{ts,tsx,json,scss}" 27.09s user 3.26s system 123% cpu 24.496 total
pprettier --write "src/**/*.{ts,tsx,json,scss}" 1.21s user 0.27s system 14% cpu 10.580 total
```

35
src/index.ts Normal file
Просмотреть файл

@ -0,0 +1,35 @@
#!/usr/bin/env node
import * as cluster from 'cluster';
import * as commander from 'commander';
import { cpus } from 'os';
import * as prettier from 'prettier';
const { version } = require('../package.json');
function startMaster() {
const program: any = commander
.option(
'--check, --list-different',
'Whether to list unformatted files, instead of writing them out',
)
.option('--write', 'Whether to write files to the output')
.option('--concurrency [value]', 'Maximum concurrency', cpus().length)
.option('--quiet, -q', 'If set, pprettier will not output progress')
.version(`@mixer/parallel-prettier version ${version} / prettier version ${prettier.version}`)
.parse(process.argv);
require('./master').spawnWorkers({
check: program.listDifferent,
concurrency: program.concurrency,
files: program.args,
quiet: program.quiet,
write: program.write,
});
}
if (module === require.main && cluster.isMaster) {
startMaster();
} else if (cluster.isWorker) {
require('./worker').startWorker();
}

45
src/master.ts Normal file
Просмотреть файл

@ -0,0 +1,45 @@
import * as globStream from 'glob-stream';
import { Observable } from 'rxjs';
import { bufferCount, mergeMap } from 'rxjs/operators';
import { ProgressReporter } from './progress-reporter';
import { IOptions } from './protocol';
import { WorkerPool } from './worker-pool';
const bufferSize = 50;
function runGlobs(files: string[]) {
return new Observable<string>(subscriber => {
const stream = globStream(files);
stream.addListener('data', data => subscriber.next(data));
stream.addListener('error', err => subscriber.error(err));
stream.addListener('finish', () => subscriber.complete());
stream.resume();
});
}
export function spawnWorkers(options: IOptions) {
const pool = new WorkerPool(options);
const progress = new ProgressReporter(options.quiet, options.check);
runGlobs(options.files)
.pipe(
bufferCount(bufferSize),
mergeMap(files => pool.format(files)),
)
.subscribe(
result => progress.update(result),
err => {
throw err;
},
() => {
progress.complete();
if (progress.reformatted && options.check) {
process.exit(1);
} else {
process.exit(0);
}
},
);
}

64
src/progress-reporter.ts Normal file
Просмотреть файл

@ -0,0 +1,64 @@
import * as ora from 'ora';
import { relative } from 'path';
import { IFormatResults } from './protocol';
/**
* Handles reporting progress of the formatting to the console.
*/
export class ProgressReporter {
public total = 0;
public reformatted = 0;
private spinner?: ora.Ora;
constructor(quiet: boolean, private readonly check: boolean) {
if (!quiet) {
this.spinner = ora('Starting...').start();
}
}
/**
* Increments the count of the total and reformatted files.
*/
public update(results: IFormatResults) {
this.total += results.files;
this.reformatted += results.formatted.length;
if (results.formatted.length) {
if (this.spinner) {
this.spinner.stop();
}
for (const file of results.formatted) {
process.stdout.write(`${relative(file.base, file.path)}\r\n`);
}
if (this.spinner) {
this.spinner.text = this.getMessage();
this.spinner.start();
}
} else if (this.spinner) {
this.spinner.text = this.getMessage();
}
}
/**
* Prints a completion message.
*/
public complete() {
if (!this.spinner) {
return;
}
if (this.check && this.reformatted) {
this.spinner.fail(`${this.reformatted} files were not formatted`);
} else {
this.spinner.succeed(this.getMessage());
}
}
private getMessage() {
return this.check
? `Checked ${this.total} files`
: `Reformatted ${this.reformatted} / ${this.total} files...`;
}
}

79
src/protocol.ts Normal file
Просмотреть файл

@ -0,0 +1,79 @@
/**
* MessageType delimits the kind of message sent in the formatter IPC.
*/
export const enum MessageType {
WorkerInitialization,
WorkerFiles,
Formatted,
Complete,
}
export const enum WorkerMode {
Write,
Print,
Assert,
}
/**
* An InitializationMessage is sent from
* the master to queue work on its workers.
*/
export interface IInitializationMessage {
type: MessageType.WorkerInitialization;
mode: WorkerMode.Write;
}
/**
* IFiles is sent to queue files to format on the worker.
*/
export interface IFilesMessage {
type: MessageType.WorkerFiles;
files: IDiscoveredFile[];
id: number;
}
/**
* MasterMessage is sent from the cluster master to its workers.
*/
export type MasterMessage = IInitializationMessage | IFilesMessage;
/**
* Results returned from formatting files.
*/
export interface IFormatResults {
files: number;
formatted: IDiscoveredFile[];
}
/**
* Format message received from a worker.
*/
export interface IFormattedMessage extends IFormatResults {
type: MessageType.Formatted;
id: number;
}
/**
* Discovered file item.
*/
export interface IDiscoveredFile {
cwd: string;
base: string;
path: string;
}
/**
* Mesage is sent from the worker to the parent process.
*/
export type WorkerMessage = IFormattedMessage;
/**
* Top-level options for the formatter.
*/
export interface IOptions {
check: boolean;
write: boolean;
concurrency: number;
quiet: boolean;
files: string[];
}

63
src/worker-pool.ts Normal file
Просмотреть файл

@ -0,0 +1,63 @@
import * as cluster from 'cluster';
import { fromEvent, Observable } from 'rxjs';
import { filter, map, take, tap } from 'rxjs/operators';
import {
IFormatResults,
IInitializationMessage,
IOptions,
MessageType,
WorkerMessage,
WorkerMode,
} from './protocol';
/**
* Pool of workers.
*/
export class WorkerPool {
private readonly workers: Array<{ worker: cluster.Worker; active: number }> = [];
private workIdCounter: number = 0;
constructor(private readonly options: IOptions) {}
/**
* Schedules the given files to be formatted.
*/
public format(files: string[]): Observable<IFormatResults> {
if (this.workers.length < this.options.concurrency) {
this.spawnWorker();
}
const target = this.workers[0];
const id = this.workIdCounter++;
target.active++;
target.worker.send({ type: MessageType.WorkerFiles, files, id });
this.sortWorkers();
return fromEvent<[WorkerMessage]>(target.worker, 'message').pipe(
map(([m]) => m),
filter(m => m.id === id),
take(1),
tap(() => {
target.active--;
this.sortWorkers();
}),
);
}
private sortWorkers() {
this.workers.sort((a, b) => a.active - b.active);
}
private spawnWorker() {
const worker = { worker: cluster.fork(), active: 0 };
this.workers.unshift(worker);
worker.worker.send({
mode: this.options.check
? WorkerMode.Assert
: this.options.write
? WorkerMode.Write
: WorkerMode.Print,
type: MessageType.WorkerInitialization,
} as IInitializationMessage);
}
}

83
src/worker.ts Normal file
Просмотреть файл

@ -0,0 +1,83 @@
import { readFile, writeFile } from 'fs';
import * as prettier from 'prettier';
import { combineLatest, Observable, of, Subject } from 'rxjs';
import { last, mergeMap } from 'rxjs/operators';
import { promisify } from 'util';
import {
IFilesMessage,
IFormattedMessage,
IInitializationMessage,
MasterMessage,
MessageType,
WorkerMessage,
WorkerMode,
} from './protocol';
const readFileAsync = promisify(readFile);
const writeFileAsync = promisify(writeFile);
/**
* Reads the files from the observable stream and, with the specified
* concurrency, formats them. Returns a stream of results to send back
* to the master.
*/
function runFormatting(
settings: IInitializationMessage,
files: IFilesMessage,
): Observable<WorkerMessage> {
const output: IFormattedMessage = {
files: files.files.length,
formatted: [],
id: files.id,
type: MessageType.Formatted,
};
return of(...files.files).pipe(
mergeMap(async file => {
const contents = await readFileAsync(file.path, 'utf-8');
const formatted = prettier.format(contents, {
...(await prettier.resolveConfig(file.path)),
filepath: file.path,
});
if (formatted === contents) {
return output;
}
if (settings.mode === WorkerMode.Write) {
await writeFileAsync(file.path, formatted);
} else if (settings.mode === WorkerMode.Print) {
process.stdout.write(formatted);
}
output.formatted.push(file);
return output;
}),
last(),
);
}
export function startWorker() {
const settings = new Subject<IInitializationMessage>();
const files = new Subject<IFilesMessage>();
process.on('message', (data: MasterMessage) => {
switch (data.type) {
case MessageType.WorkerInitialization:
settings.next(data);
break;
case MessageType.WorkerFiles:
files.next(data);
break;
}
});
combineLatest(settings, files)
.pipe(mergeMap(([s, f]) => runFormatting(s, f)))
.subscribe(
message => process.send!(message),
err => {
throw err;
},
);
}

17
tsconfig.json Normal file
Просмотреть файл

@ -0,0 +1,17 @@
{
"compilerOptions": {
"forceConsistentCasingInFileNames": true,
"sourceMap": true,
"noImplicitReturns": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"strict": true,
"moduleResolution": "node",
"newLine": "LF",
"module": "commonjs",
"target": "es6",
"lib": ["es6", "es7"],
"outDir": "dist",
"types": ["node"]
}
}

7
tslint.json Normal file
Просмотреть файл

@ -0,0 +1,7 @@
{
"$schema": "http://json.schemastore.org/tslint",
"extends": ["tslint:recommended", "tslint-config-prettier"],
"rules": {
"no-var-requires": false
}
}