Severely improved support for rustfmt 0.5
rustfmt will now be run within the actual working directory instead of a temporary one. This will allow rustfmt to correctly look up referenced modules.
This commit is contained in:
parent
852c356551
commit
458fdb62e2
|
@ -113,7 +113,7 @@ module.exports = class Beautifier
|
||||||
_envCacheDate: null
|
_envCacheDate: null
|
||||||
_envCacheExpiry: 10000 # 10 seconds
|
_envCacheExpiry: 10000 # 10 seconds
|
||||||
getShellEnvironment: ->
|
getShellEnvironment: ->
|
||||||
return new @Promise((resolve, reject) =>
|
return new Promise((resolve, reject) =>
|
||||||
# Check Cache
|
# Check Cache
|
||||||
if @_envCache? and @_envCacheDate?
|
if @_envCache? and @_envCacheDate?
|
||||||
# Check if Cache is old
|
# Check if Cache is old
|
||||||
|
@ -248,71 +248,78 @@ module.exports = class Beautifier
|
||||||
###
|
###
|
||||||
Run command-line interface command
|
Run command-line interface command
|
||||||
###
|
###
|
||||||
run: (executable, args, {ignoreReturnCode, help} = {}) ->
|
run: (executable, args, {cwd, ignoreReturnCode, help, onStdin} = {}) ->
|
||||||
# Flatten args first
|
# Flatten args first
|
||||||
args = _.flatten(args)
|
args = _.flatten(args)
|
||||||
|
|
||||||
# Resolve executable and all args
|
# Resolve executable and all args
|
||||||
Promise.all([executable, Promise.all(args)])
|
Promise.all([executable, Promise.all(args)])
|
||||||
.then(([exeName, args]) =>
|
.then(([exeName, args]) =>
|
||||||
@debug('exeName, args:', exeName, args)
|
@debug('exeName, args:', exeName, args)
|
||||||
return new Promise((resolve, reject) =>
|
|
||||||
# Remove undefined/null values
|
# Remove undefined/null values
|
||||||
args = _.without(args, undefined)
|
args = _.without(args, undefined)
|
||||||
args = _.without(args, null)
|
args = _.without(args, null)
|
||||||
|
|
||||||
# Get PATH and other environment variables
|
# Get PATH and other environment variables
|
||||||
Promise.all([@getShellEnvironment(), @which(exeName)])
|
Promise.all([exeName, @getShellEnvironment(), @which(exeName)])
|
||||||
.then(([env, exePath]) =>
|
)
|
||||||
@debug('exePath, env:', exePath, env)
|
.then(([exeName, env, exePath]) =>
|
||||||
exe = exePath ? exeName
|
@debug('exePath, env:', exePath, env)
|
||||||
# Spawn command
|
|
||||||
options = {
|
exe = exePath ? exeName
|
||||||
env: env
|
options = {
|
||||||
}
|
cwd: cwd
|
||||||
cmd = @spawn(exe, args, options)
|
env: env
|
||||||
.then(({returnCode, stdout, stderr}) =>
|
}
|
||||||
@verbose('spawn result', returnCode, stdout, stderr)
|
|
||||||
# If return code is not 0 then error occured
|
@spawn(exe, args, options, onStdin)
|
||||||
if not ignoreReturnCode and returnCode isnt 0
|
.then(({returnCode, stdout, stderr}) =>
|
||||||
err = new Error(stderr)
|
@verbose('spawn result', returnCode, stdout, stderr)
|
||||||
windowsProgramNotFoundMsg = "is not recognized as an \
|
|
||||||
internal or external command" # operable program or batch file
|
# If return code is not 0 then error occured
|
||||||
@verbose(stderr, windowsProgramNotFoundMsg)
|
if not ignoreReturnCode and returnCode isnt 0
|
||||||
if @isWindows and returnCode is 1 and \
|
# operable program or batch file
|
||||||
stderr.indexOf(windowsProgramNotFoundMsg) isnt -1
|
windowsProgramNotFoundMsg = "is not recognized as an internal or external command"
|
||||||
err = @commandNotFoundError(exeName, help)
|
|
||||||
reject(err)
|
@verbose(stderr, windowsProgramNotFoundMsg)
|
||||||
else
|
|
||||||
resolve(stdout)
|
if @isWindows and returnCode is 1 and stderr.indexOf(windowsProgramNotFoundMsg) isnt -1
|
||||||
)
|
throw @commandNotFoundError(exeName, help)
|
||||||
.catch((err) =>
|
else
|
||||||
@debug('error', err)
|
throw new Error(stderr)
|
||||||
# Check if error is ENOENT
|
else
|
||||||
# (command could not be found)
|
stdout
|
||||||
if err.code is 'ENOENT' or err.errno is 'ENOENT'
|
)
|
||||||
reject(@commandNotFoundError(exeName, help))
|
.catch((err) =>
|
||||||
else
|
@debug('error', err)
|
||||||
# continue as normal error
|
|
||||||
reject(err)
|
# Check if error is ENOENT (command could not be found)
|
||||||
)
|
if err.code is 'ENOENT' or err.errno is 'ENOENT'
|
||||||
)
|
throw @commandNotFoundError(exeName, help)
|
||||||
|
else
|
||||||
|
# continue as normal error
|
||||||
|
throw err
|
||||||
|
)
|
||||||
)
|
)
|
||||||
)
|
|
||||||
|
|
||||||
###
|
###
|
||||||
Spawn
|
Spawn
|
||||||
###
|
###
|
||||||
spawn: (exe, args, options) ->
|
spawn: (exe, args, options, onStdin) ->
|
||||||
return new Promise((resolve, reject) =>
|
return new Promise((resolve, reject) =>
|
||||||
@debug('spawn', exe, args)
|
@debug('spawn', exe, args)
|
||||||
|
|
||||||
cmd = spawn(exe, args, options)
|
cmd = spawn(exe, args, options)
|
||||||
# add a 'data' event listener for the spawn instance
|
|
||||||
stdout = ""
|
stdout = ""
|
||||||
stderr = ""
|
stderr = ""
|
||||||
cmd.stdout.on('data', (data) -> stdout += data )
|
|
||||||
cmd.stderr.on('data', (data) -> stderr += data )
|
cmd.stdout.on('data', (data) ->
|
||||||
# when the spawn child process exits,
|
stdout += data
|
||||||
# check if there were any errors and
|
)
|
||||||
# close the writeable stream
|
cmd.stderr.on('data', (data) ->
|
||||||
|
stderr += data
|
||||||
|
)
|
||||||
cmd.on('close', (returnCode) =>
|
cmd.on('close', (returnCode) =>
|
||||||
@debug('spawn done', returnCode, stderr, stdout)
|
@debug('spawn done', returnCode, stderr, stdout)
|
||||||
resolve({returnCode, stdout, stderr})
|
resolve({returnCode, stdout, stderr})
|
||||||
|
@ -321,6 +328,8 @@ module.exports = class Beautifier
|
||||||
@debug('error', err)
|
@debug('error', err)
|
||||||
reject(err)
|
reject(err)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
onStdin cmd.stdin if onStdin
|
||||||
)
|
)
|
||||||
|
|
||||||
###
|
###
|
||||||
|
|
|
@ -4,9 +4,11 @@ Requires https://github.com/nrc/rustfmt
|
||||||
|
|
||||||
"use strict"
|
"use strict"
|
||||||
Beautifier = require('./beautifier')
|
Beautifier = require('./beautifier')
|
||||||
|
path = require('path')
|
||||||
|
|
||||||
|
versionCheckState = false
|
||||||
|
|
||||||
module.exports = class Rustfmt extends Beautifier
|
module.exports = class Rustfmt extends Beautifier
|
||||||
|
|
||||||
name: "rustfmt"
|
name: "rustfmt"
|
||||||
|
|
||||||
options: {
|
options: {
|
||||||
|
@ -14,24 +16,38 @@ module.exports = class Rustfmt extends Beautifier
|
||||||
}
|
}
|
||||||
|
|
||||||
beautify: (text, language, options) ->
|
beautify: (text, language, options) ->
|
||||||
|
|
||||||
# get file path which is the search path for rustfmt.toml as
|
|
||||||
# the beautifier runs rustfmt in a tmp directory.
|
|
||||||
# This will pick up any rustfmt.toml defined in the crate root
|
|
||||||
|
|
||||||
editor = atom.workspace.getActivePaneItem()
|
editor = atom.workspace.getActivePaneItem()
|
||||||
file = editor?.buffer.file
|
buffer = editor.getBuffer?()
|
||||||
filePath = file?.path
|
filePath = buffer.getPath?()
|
||||||
|
cwd = if filePath then path.dirname filePath else undefined
|
||||||
program = options.rustfmt_path or "rustfmt"
|
program = options.rustfmt_path or "rustfmt"
|
||||||
@run(program, [
|
help = {
|
||||||
tmpFile = @tempFile("tmp", text)
|
link: "https://github.com/nrc/rustfmt"
|
||||||
["--write-mode", "overwrite"]
|
program: "rustfmt"
|
||||||
["--config-path", filePath]
|
pathOption: "Rust - Rustfmt Path"
|
||||||
], help: {
|
}
|
||||||
link: "https://github.com/nrc/rustfmt"
|
|
||||||
program: "rustfmt"
|
# 0.5.0 is a relatively new version at the point of writing,
|
||||||
pathOption: "Rust - Rustfmt Path"
|
# but is essential for this to work with stdin.
|
||||||
|
# => Check for it specifically.
|
||||||
|
p = if versionCheckState == program
|
||||||
|
@Promise.resolve()
|
||||||
|
else
|
||||||
|
@run(program, ["--version"], help: help)
|
||||||
|
.then((stdout) ->
|
||||||
|
if /^0\.(?:[0-4]\.[0-9])/.test(stdout.trim())
|
||||||
|
versionCheckState = false
|
||||||
|
throw new Error("rustfmt version 0.5.0 or newer required")
|
||||||
|
else
|
||||||
|
versionCheckState = program
|
||||||
|
undefined
|
||||||
|
)
|
||||||
|
|
||||||
|
p.then(=>
|
||||||
|
@run(program, [], {
|
||||||
|
cwd: cwd
|
||||||
|
help: help
|
||||||
|
onStdin: (stdin) ->
|
||||||
|
stdin.end text
|
||||||
})
|
})
|
||||||
.then(=>
|
)
|
||||||
@readFile(tmpFile)
|
|
||||||
)
|
|
||||||
|
|
Loading…
Reference in New Issue