diff --git a/.travis.yml b/.travis.yml index bc7dc7b..12c86c9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -19,7 +19,7 @@ notifications: script: sh build-package.sh env: - - APM_TEST_PACKAGES="linter atom-typescript language-marko language-tss language-html-swig" + - APM_TEST_PACKAGES="language-marko language-tss language-html-swig" cache: - pip diff --git a/appveyor.yml b/appveyor.yml index 5196036..d4f76b2 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -74,6 +74,7 @@ install: # pip will build them from source using the MSVC compiler matching the # target Python version and architecture - "%CMD_IN_ENV% pip install --upgrade autopep8" + - where autopep8 # Ruby & Gem - cinst ruby -y @@ -111,7 +112,7 @@ build_script: - cd %APPVEYOR_BUILD_FOLDER% # Install languages to Atom - - apm install linter atom-typescript language-marko language-tss language-html-swig + - apm install language-marko language-tss language-html-swig # Show current PATH - echo %PATH% # Run tests on package diff --git a/spec/beautifier-php-cs-fixer-spec.coffee b/spec/beautifier-php-cs-fixer-spec.coffee index e04d286..c512bee 100644 --- a/spec/beautifier-php-cs-fixer-spec.coffee +++ b/spec/beautifier-php-cs-fixer-spec.coffee @@ -1,5 +1,6 @@ PHPCSFixer = require "../src/beautifiers/php-cs-fixer" Beautifier = require "../src/beautifiers/beautifier" +path = require 'path' # Use the command `window:run-package-specs` (cmd-alt-ctrl-p) to run specs. # @@ -27,62 +28,109 @@ describe "PHP-CS-Fixer Beautifier", -> beforeEach -> beautifier = new PHPCSFixer() + # console.log('new beautifier') - it "should error when beautifier's program not found", -> - expect(beautifier).not.toBe(null) - expect(beautifier instanceof Beautifier).toBe(true) + OSSpecificSpecs = -> + text = "" - waitsForPromise shouldReject: true, -> - text = "" - language = "PHP" - options = { - fixers: "" - levels: "" - } - # Mock PATH - beautifier.getShellEnvironment = -> Promise.resolve({ - PATH: '' - }) - # - p = beautifier.beautify(text, language, options) - expect(p).not.toBe(null) - expect(p instanceof beautifier.Promise).toBe(true) - cb = (v) -> - # console.log(v) - expect(v).not.toBe(null) - expect(v instanceof Error).toBe(true, \ - "Expected #{v} to be instance of Error") - expect(v.code).toBe("CommandNotFound", \ - "Expected to be CommandNotFound") - return v - p.then(cb, cb) - return p + it "should error when beautifier's program not found", -> + expect(beautifier).not.toBe(null) + expect(beautifier instanceof Beautifier).toBe(true) - # it "should error with help description \ - # when beautifier's program not found", -> - # expect(beautifier).not.toBe(null) - # expect(beautifier instanceof Beautifier).toBe(true) - # - # waitsForPromise shouldReject: true, -> - # help = { - # link: "http://test.com" - # program: "test-program" - # pathOption: "Lang - Test Program Path" - # } - # p = beautifier.run("program", [], help: help) - # expect(p).not.toBe(null) - # expect(p instanceof beautifier.Promise).toBe(true) - # cb = (v) -> - # # console.log(v) - # expect(v).not.toBe(null) - # expect(v instanceof Error).toBe(true) - # expect(v.code).toBe("CommandNotFound") - # expect(v.description).not.toBe(null) - # expect(v.description.indexOf(help.link)).not.toBe(-1) - # expect(v.description.indexOf(help.program)).not.toBe(-1) - # expect(v.description - # .indexOf(help.pathOption)).not.toBe(-1, \ - # "Error should have a description.") - # return v - # p.then(cb, cb) - # return p + waitsForPromise shouldReject: true, -> + language = "PHP" + options = { + fixers: "" + levels: "" + } + # Mock PATH + beautifier.getShellEnvironment = -> Promise.resolve({ + PATH: '' + }) + # + p = beautifier.beautify(text, language, options) + expect(p).not.toBe(null) + expect(p instanceof beautifier.Promise).toBe(true) + cb = (v) -> + # console.log(v) + expect(v).not.toBe(null) + expect(v instanceof Error).toBe(true, \ + "Expected '#{v}' to be instance of Error") + expect(v.code).toBe("CommandNotFound", \ + "Expected to be CommandNotFound") + return v + p.then(cb, cb) + return p + + failWhichProgram = (failingProgram) -> + it "should error when '#{failingProgram}' not found", -> + expect(beautifier).not.toBe(null) + expect(beautifier instanceof Beautifier).toBe(true) + + if not beautifier.isWindows and failingProgram is "php" + # Only applicable on Windows + return + + waitsForPromise shouldReject: true, -> + language = "PHP" + options = { + fixers: "" + levels: "" + } + cb = (v) -> + # console.log('cb value', v) + expect(v).not.toBe(null) + expect(v instanceof Error).toBe(true, \ + "Expected '#{v}' to be instance of Error") + expect(v.code).toBe("CommandNotFound", \ + "Expected to be CommandNotFound") + expect(v.file).toBe(failingProgram) + return v + # which = beautifier.which.bind(beautifier) + beautifier.which = (exe, options) -> + return beautifier.Promise.resolve(null) \ + if not exe? + if exe is failingProgram + beautifier.Promise.resolve(failingProgram) + else + # which(exe, options) + # console.log('fake exe path', exe) + beautifier.Promise.resolve("/#{exe}") + + oldSpawn = beautifier.spawn.bind(beautifier) + beautifier.spawn = (exe, args, options) -> + # console.log('spawn', exe, args, options) + if exe is failingProgram + er = new Error('ENOENT') + er.code = 'ENOENT' + return beautifier.Promise.reject(er) + else + return beautifier.Promise.resolve({ + returnCode: 0, + stdout: 'stdout', + stderr: '' + }) + p = beautifier.beautify(text, language, options) + expect(p).not.toBe(null) + expect(p instanceof beautifier.Promise).toBe(true) + p.then(cb, cb) + return p + + failWhichProgram('php') + failWhichProgram('php-cs-fixer') + + describe "Mac/Linux", -> + + beforeEach -> + # console.log('mac/linx') + beautifier.isWindows = false + + do OSSpecificSpecs + + describe "Windows", -> + + beforeEach -> + # console.log('windows') + beautifier.isWindows = true + + do OSSpecificSpecs diff --git a/src/beautifiers/beautifier.coffee b/src/beautifiers/beautifier.coffee index 79380d8..105be75 100644 --- a/src/beautifiers/beautifier.coffee +++ b/src/beautifiers/beautifier.coffee @@ -243,41 +243,55 @@ module.exports = class Beautifier @debug('exePath, env:', exePath, env) exe = exePath ? exeName # Spawn command - stdout = "" - stderr = "" options = { env: env } - @debug('spawn', exe, args) - cmd = spawn(exe, args, options) - # add a 'data' event listener for the spawn instance - cmd.stdout.on('data', (data) -> stdout += data ) - cmd.stderr.on('data', (data) -> stderr += data ) - # when the spawn child process exits, - # check if there were any errors and - # close the writeable stream - cmd.on('exit', (returnCode) => - @debug('spawn done', returnCode, stderr, stdout) - # If return code is not 0 then error occured - if not ignoreReturnCode and returnCode isnt 0 - reject(stderr) - else - resolve(stdout) - ) - cmd.on('error', (err) => - @debug('error', err) - # Check if error is ENOENT - # (command could not be found) - if err.code is 'ENOENT' or err.errno is 'ENOENT' - reject(@commandNotFoundError(exeName, help)) - else - # continue as normal error - reject(err) - ) + cmd = @spawn(exe, args, options) + .then(({returnCode, stdout, stderr}) -> + # If return code is not 0 then error occured + if not ignoreReturnCode and returnCode isnt 0 + reject(stderr) + else + resolve(stdout) + ) + .catch((err) => + @debug('error', err) + # Check if error is ENOENT + # (command could not be found) + if err.code is 'ENOENT' or err.errno is 'ENOENT' + reject(@commandNotFoundError(exeName, help)) + else + # continue as normal error + reject(err) + ) ) ) ) + ### + Spawn + ### + spawn: (exe, args, options) -> + return new Promise((resolve, reject) => + @debug('spawn', exe, args) + cmd = spawn(exe, args, options) + # add a 'data' event listener for the spawn instance + stdout = "" + stderr = "" + cmd.stdout.on('data', (data) -> stdout += data ) + cmd.stderr.on('data', (data) -> stderr += data ) + # when the spawn child process exits, + # check if there were any errors and + # close the writeable stream + cmd.on('exit', (returnCode) => + @debug('spawn done', returnCode, stderr, stdout) + resolve({returnCode, stdout, stderr}) + ) + cmd.on('error', (err) => + @debug('error', err) + reject(err) + ) + ) ### Logger instance @@ -288,10 +302,10 @@ module.exports = class Beautifier ### setupLogger: -> @logger = require('../logger')(__filename) - # console.log(@logger) + # @verbose(@logger) # Merge logger methods into beautifier class for key, method of @logger - # console.log(key, method) + # @verbose(key, method) @[key] = method @verbose("Beautifier logger has been initialized.") diff --git a/src/beautifiers/php-cs-fixer.coffee b/src/beautifiers/php-cs-fixer.coffee index 14dbcaa..fd2386d 100644 --- a/src/beautifiers/php-cs-fixer.coffee +++ b/src/beautifiers/php-cs-fixer.coffee @@ -19,15 +19,15 @@ module.exports = class PHPCSFixer extends Beautifier if isWin # Find php-cs-fixer.phar script @Promise.all([ - @which(options.cs_fixer_path) + @which(options.cs_fixer_path) if options.cs_fixer_path @which('php-cs-fixer') - @which('php-cs-fixer.phar') - ]).then((paths...)=> + ]).then((paths) => @debug('php-cs-fixer paths', paths) - path = require('path') - # Get first valid path - phpCSFixerPath = _.find(paths, (p) -> path.isAbsolute(p) ) - @debug('phpCSFixerPath', phpCSFixerPath) + _ = require('lodash') + # Get first valid, absolute path + phpCSFixerPath = _.find(paths, (p) -> p and p.charAt(0) is '/' ) + @verbose('phpCSFixerPath', phpCSFixerPath) + @debug('phpCSFixerPath', phpCSFixerPath, paths) # Check if PHP-CS-Fixer path was found if phpCSFixerPath? # Found PHP-CS-Fixer path @@ -47,7 +47,8 @@ module.exports = class PHPCSFixer extends Beautifier @readFile(tempFile) ) else - # could not find PHP-CS-Fixer path + @verbose('php-cs-fixer not found!') + # Could not find PHP-CS-Fixer path @Promise.reject(@commandNotFoundError( 'php-cs-fixer' {