Skip to content
This repository has been archived by the owner on Apr 1, 2020. It is now read-only.

Commit

Permalink
Feature/use local prettier (#2360)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
akinsho authored Jun 30, 2018
1 parent a2cc7e9 commit 3c05476
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 7 deletions.
19 changes: 13 additions & 6 deletions extensions/oni-plugin-prettier/index.js
Original file line number Diff line number Diff line change
@@ -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)
Expand All @@ -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"
Expand All @@ -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}`)
}
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -158,7 +166,6 @@ function createPrettierComponent(Oni, onClick) {
paddingLeft: "8px",
paddingRight: "8px",
color: "white",
backgroundColor: foreground,
}

const prettierIcon = (type = "magic") =>
Expand Down
4 changes: 3 additions & 1 deletion extensions/oni-plugin-prettier/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
]
},
"dependencies": {
"prettier": "^1.11.1"
"prettier": "^1.13.6",
"read-pkg-up": "^4.0.0",
"resolve": "^1.8.1"
},
"devDependencies": {}
}
52 changes: 52 additions & 0 deletions extensions/oni-plugin-prettier/requirePackage.js
Original file line number Diff line number Diff line change
@@ -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 }

0 comments on commit 3c05476

Please sign in to comment.