Feature/use local prettier (#2360)

* pull upstream

* add initial attempt to load local prettier not global

* prioritise local prettier over global

* add local dependencies dont rely on global ones

* remove unnecessary fallback arg as fn already returns a fallback

* prettier
This commit is contained in:
Akin 2018-06-30 18:23:39 +01:00 committed by GitHub
parent a2cc7e9302
commit 3c054763a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 68 additions and 7 deletions

View File

@ -1,5 +1,5 @@
const path = require("path")
const prettier = require("prettier")
const { requireLocalPkg } = require("./requirePackage")
// Helper functions
const compose = (...fns) => argument => fns.reduceRight((arg, fn) => fn(arg), argument)
@ -19,17 +19,25 @@ const isCompatible = (allowedFiletypes, defaultFiletypes) => filePath => {
return filetypes.includes(extension)
}
const getSupportedLanguages = async () => {
const getSupportedLanguages = async prettier => {
const info = await prettier.getSupportInfo()
return flatten(info.languages.map(lang => lang.extensions))
}
const activate = async Oni => {
// Prettier Module to Use - local or oni-bundled
let PrettierModule = requireLocalPkg(process.cwd(), "prettier")
const config = Oni.configuration.getValue("oni.plugins.prettier")
const prettierItem = Oni.statusBar.createItem(0, "oni.plugins.prettier")
// Update Prettier Module to use when oni dir changes
Oni.workspace.onDirectoryChanged.subscribe(dir => {
PrettierModule = requireLocalPkg(dir, "prettier")
})
const applyPrettierWithState = applyPrettier()
const defaultFiletypes = await getSupportedLanguages()
const defaultFiletypes = await getSupportedLanguages(PrettierModule)
const callback = async () => {
const isNormalMode = Oni.editors.activeEditor.mode === "normal"
@ -48,7 +56,7 @@ const activate = async Oni => {
throw new Error(`No buffer path passed for prettier to check for a Prettierrc`)
}
try {
return await prettier.resolveConfig(bufferPath)
return await PrettierModule.resolveConfig(bufferPath)
} catch (e) {
throw new Error(`Error parsing config file, ${e}`)
}
@ -95,7 +103,7 @@ const activate = async Oni => {
const prettierConfig = eitherOr(prettierrc, config.settings)
// Pass in the file path so prettier can infer the correct parser to use
const { formatted, cursorOffset } = prettier.formatWithCursor(
const { formatted, cursorOffset } = PrettierModule.formatWithCursor(
join(arrayOfLines),
Object.assign({ filepath: activeBuffer.filePath }, prettierConfig, {
cursorOffset: activeBuffer.cursorOffset,
@ -158,7 +166,6 @@ function createPrettierComponent(Oni, onClick) {
paddingLeft: "8px",
paddingRight: "8px",
color: "white",
backgroundColor: foreground,
}
const prettierIcon = (type = "magic") =>

View File

@ -12,7 +12,9 @@
]
},
"dependencies": {
"prettier": "^1.11.1"
"prettier": "^1.13.6",
"read-pkg-up": "^4.0.0",
"resolve": "^1.8.1"
},
"devDependencies": {}
}

View File

@ -0,0 +1,52 @@
const path = require("path")
const resolve = require("resolve")
const readPkgUp = require("read-pkg-up")
// CREDIT: Shamelessly *borrowed* from prettier-vscode
/**
* Recursively search for a package.json upwards containing given package
* as a dependency or devDependency.
* @param {string} fspath file system path to start searching from
* @param {string} pkgName package's name to search for
* @returns {string} resolved path to prettier
*/
function findPkg(fspath = process.cwd(), pkgName) {
const res = readPkgUp.sync({ cwd: fspath, normalize: false })
const { root } = path.parse(fspath)
if (
res.pkg &&
((res.pkg.dependencies && res.pkg.dependencies[pkgName]) ||
(res.pkg.devDependencies && res.pkg.devDependencies[pkgName]))
) {
return resolve.sync(pkgName, { basedir: res.path })
} else if (res.path) {
const parent = path.resolve(path.dirname(res.path), "..")
if (parent !== root) {
return findPkg(parent, pkgName)
}
}
return
}
/**
* Require package explicitely installed relative to given path.
* Fallback to bundled one if no pacakge was found bottom up.
* @param {string} fspath file system path starting point to resolve package
* @param {string} pkgName package's name to require
* @returns module
*/
function requireLocalPkg(fspath, pkgName) {
const modulePath = findPkg(fspath, pkgName)
if (modulePath) {
try {
return require(modulePath)
} catch (e) {
console.warn(`Failed to load ${pkgName} from ${modulePath}. Using bundled`)
}
}
return require(pkgName)
}
module.exports = { requireLocalPkg }