launcher: lint and format TS files using prettier, close #132 (#143)

This commit is contained in:
Gleb Bahmutov
2017-06-07 14:28:20 -04:00
committed by GitHub
parent 7ae22114a6
commit 479c013749
10 changed files with 151 additions and 110 deletions

View File

@@ -1,13 +1,17 @@
import {log} from './log'
import {find, map} from 'lodash'
import cp = require('child_process')
import {Browser, FoundBrowser, BrowserNotFoundError} from './types'
import { log } from './log'
import { find, map } from 'lodash'
import * as cp from 'child_process'
import { Browser, FoundBrowser, BrowserNotFoundError } from './types'
const browserNotFoundErr = (browsers: FoundBrowser[], name: string): BrowserNotFoundError => {
const browserNotFoundErr = (
browsers: FoundBrowser[],
name: string
): BrowserNotFoundError => {
const available = map(browsers, 'name').join(', ')
const err: BrowserNotFoundError
= new Error(`Browser: '${name}' not found. Available browsers are: [${available}]`) as BrowserNotFoundError
const err: BrowserNotFoundError = new Error(
`Browser: '${name}' not found. Available browsers are: [${available}]`
) as BrowserNotFoundError
err.specificBrowserNotFound = true
return err
}
@@ -34,13 +38,15 @@ export const browsers: Browser[] = [
versionRegex: /Google Chrome (\S+)/,
profile: true,
binary: 'google-chrome'
},{
},
{
name: 'chromium',
displayName: 'Chromium',
versionRegex: /Chromium (\S+)/,
profile: true,
binary: 'chromium-browser'
},{
},
{
name: 'canary',
displayName: 'Canary',
versionRegex: /Google Chrome Canary (\S+)/,
@@ -53,10 +59,14 @@ export const browsers: Browser[] = [
]
/** starts a browser by name and opens URL if given one */
export function launch (browsers: FoundBrowser[],
name: string, url?: string, args: string[] = []) {
export function launch(
browsers: FoundBrowser[],
name: string,
url?: string,
args: string[] = []
) {
log('launching browser %s to open %s', name, url)
const browser = find(browsers, {name})
const browser = find(browsers, { name })
if (!browser) {
throw browserNotFoundErr(browsers, name)
@@ -71,5 +81,5 @@ export function launch (browsers: FoundBrowser[],
}
log('spawning browser %s with args %s', browser.path, args.join(' '))
return cp.spawn(browser.path, args, {stdio: 'ignore'})
return cp.spawn(browser.path, args, { stdio: 'ignore' })
}

View File

@@ -1,15 +1,24 @@
import {findApp} from './util'
import {Browser} from '../types'
import {detectBrowserLinux} from '../linux'
import {log} from '../log'
import {merge, partial} from 'ramda'
import { findApp } from './util'
import { Browser } from '../types'
import { detectBrowserLinux } from '../linux'
import { log } from '../log'
import { merge, partial } from 'ramda'
const detectCanary = partial(findApp,
['Contents/MacOS/Google Chrome Canary', 'com.google.Chrome.canary', 'KSVersion'])
const detectChrome = partial(findApp,
['Contents/MacOS/Google Chrome', 'com.google.Chrome', 'KSVersion'])
const detectChromium = partial(findApp,
['Contents/MacOS/Chromium', 'org.chromium.Chromium', 'CFBundleShortVersionString'])
const detectCanary = partial(findApp, [
'Contents/MacOS/Google Chrome Canary',
'com.google.Chrome.canary',
'KSVersion'
])
const detectChrome = partial(findApp, [
'Contents/MacOS/Google Chrome',
'com.google.Chrome',
'KSVersion'
])
const detectChromium = partial(findApp, [
'Contents/MacOS/Chromium',
'org.chromium.Chromium',
'CFBundleShortVersionString'
])
type Detectors = {
[index: string]: Function
@@ -21,7 +30,7 @@ const browsers: Detectors = {
chromium: detectChromium
}
export function detectBrowserDarwin (browser: Browser) {
export function detectBrowserDarwin(browser: Browser) {
let fn = browsers[browser.name]
if (!fn) {
@@ -30,11 +39,9 @@ export function detectBrowserDarwin (browser: Browser) {
return detectBrowserLinux(browser)
}
return fn()
.then(merge({name: browser.name}))
.catch(() => {
log('could not detect %s using traditional Mac methods', browser.name)
log('trying linux search')
return detectBrowserLinux(browser)
})
return fn().then(merge({ name: browser.name })).catch(() => {
log('could not detect %s using traditional Mac methods', browser.name)
log('trying linux search')
return detectBrowserLinux(browser)
})
}

View File

@@ -1,14 +1,13 @@
import {log} from '../log'
import {NotInstalledError} from '../types'
import {prop, tap} from 'ramda'
import execa = require('execa')
import fs = require('fs-extra')
import path = require('path')
import plist = require('plist')
import { log } from '../log'
import { NotInstalledError } from '../types'
import { prop, tap } from 'ramda'
import * as execa from 'execa'
import * as fs from 'fs-extra'
import * as path from 'path'
import * as plist from 'plist'
/** parses Info.plist file from given application and returns a property */
export function parse (p: string, property: string): Promise<string> {
export function parse(p: string, property: string): Promise<string> {
const pl = path.join(p, 'Contents', 'Info.plist')
log('reading property file "%s"', pl)
@@ -21,14 +20,15 @@ export function parse (p: string, property: string): Promise<string> {
throw err
}
return fs.readFile(pl, 'utf8')
return fs
.readFile(pl, 'utf8')
.then(plist.parse)
.then(prop(property))
.catch(failed)
}
/** uses mdfind to find app using Ma app id like 'com.google.Chrome.canary' */
export function mdfind (id: string): Promise<string> {
export function mdfind(id: string): Promise<string> {
const cmd = `mdfind 'kMDItemCFBundleIdentifier=="${id}"' | head -1`
log('looking for bundle id %s using command: %s', id, cmd)
@@ -44,18 +44,19 @@ export function mdfind (id: string): Promise<string> {
throw err
}
return execa.shell(cmd)
return execa
.shell(cmd)
.then(prop('stdout'))
.then(tap(logFound))
.catch(failedToFind)
}
export type AppInfo = {
path: string,
path: string
version: string
}
function formApplicationPath (executable: string) {
function formApplicationPath(executable: string) {
const parts = executable.split('/')
const name = parts[parts.length - 1]
const appName = `${name}.app`
@@ -63,21 +64,23 @@ function formApplicationPath (executable: string) {
}
/** finds an application and its version */
export function findApp (executable: string, appId: string, versionProperty: string): Promise<AppInfo> {
export function findApp(
executable: string,
appId: string,
versionProperty: string
): Promise<AppInfo> {
log('looking for app %s id %s', executable, appId)
const findVersion = (foundPath: string) =>
parse(foundPath, versionProperty)
.then((version) => {
return {
path: path.join(foundPath, executable),
version
}
})
parse(foundPath, versionProperty).then(version => {
return {
path: path.join(foundPath, executable),
version
}
})
const tryMdFind = () => {
return mdfind(appId)
.then(findVersion)
return mdfind(appId).then(findVersion)
}
const tryFullApplicationFind = () => {
@@ -86,6 +89,5 @@ export function findApp (executable: string, appId: string, versionProperty: str
return findVersion(applicationPath)
}
return tryMdFind()
.catch(tryFullApplicationFind)
return tryMdFind().catch(tryFullApplicationFind)
}

View File

@@ -1,19 +1,22 @@
import {detectBrowserLinux} from './linux'
import {detectBrowserDarwin} from './darwin'
import {log} from './log'
import {Browser, NotInstalledError} from './types'
import {browsers} from './browsers'
import { detectBrowserLinux } from './linux'
import { detectBrowserDarwin } from './darwin'
import { log } from './log'
import { Browser, NotInstalledError } from './types'
import { browsers } from './browsers'
import * as Bluebird from 'bluebird'
import {merge, pick, tap, uniqBy, prop} from 'ramda'
import _ = require('lodash')
import os = require('os')
import { merge, pick, tap, uniqBy, prop } from 'ramda'
import * as _ from 'lodash'
import * as os from 'os'
const setMajorVersion = (obj: Browser) => {
if (obj.version) {
obj.majorVersion = obj.version.split('.')[0]
log('browser %s version %s major version %s',
obj.name, obj.version, obj.majorVersion)
log(
'browser %s version %s major version %s',
obj.name,
obj.version,
obj.majorVersion
)
}
return obj
}
@@ -27,7 +30,7 @@ const detectors: Detectors = {
linux: detectBrowserLinux
}
function lookup (platform: NodeJS.Platform, obj: Browser): Promise<Object> {
function lookup(platform: NodeJS.Platform, obj: Browser): Promise<Object> {
log('looking up %s on %s platform', obj.name, platform)
const detector = detectors[platform]
if (!detector) {
@@ -36,9 +39,15 @@ function lookup (platform: NodeJS.Platform, obj: Browser): Promise<Object> {
return detector(obj)
}
function checkOneBrowser (browser: Browser) {
function checkOneBrowser(browser: Browser) {
const platform = os.platform()
const pickBrowserProps = pick(['name', 'displayName', 'type', 'version', 'path'])
const pickBrowserProps = pick([
'name',
'displayName',
'type',
'version',
'path'
])
const logBrowser = (props: any) => {
log('setting major version for %j', props)
@@ -61,7 +70,7 @@ function checkOneBrowser (browser: Browser) {
}
/** returns list of detected browsers */
function detectBrowsers (): Bluebird<Browser[]> {
function detectBrowsers(): Bluebird<Browser[]> {
// we can detect same browser under different aliases
// tell them apart by the full version property
const removeDuplicates = uniqBy(prop('version'))

View File

@@ -1,7 +1,7 @@
import {writeJson} from 'fs-extra'
import {launch} from './browsers'
import { writeJson } from 'fs-extra'
import { launch } from './browsers'
import detect from './detect'
import {Browser, LauncherApi} from './types'
import { Browser, LauncherApi } from './types'
const Promise = require('bluebird')
@@ -9,14 +9,13 @@ const missingConfig = () =>
Promise.reject(new Error('You must provide a path to a config file.'))
const wrap = (all: Browser[]) => ({
launch: (name: string, url: string, args = []) =>
launch(all, name, url, args)
launch: (name: string, url: string, args = []) => launch(all, name, url, args)
})
const init = (browsers: Browser[]) =>
browsers ? wrap(browsers) : detect().then(wrap)
const api: LauncherApi = init as any as LauncherApi
const api: LauncherApi = (init as any) as LauncherApi
const update = (pathToConfig?: string) => {
if (!pathToConfig) {
@@ -25,10 +24,9 @@ const update = (pathToConfig?: string) => {
// detect the browsers and set the config
const saveBrowsers = (browers: Browser[]) =>
writeJson(pathToConfig, browers, {spaces: 2})
writeJson(pathToConfig, browers, { spaces: 2 })
return detect()
.then(saveBrowsers)
return detect().then(saveBrowsers)
}
// extend "api" with a few utility methods for convenience

View File

@@ -1,22 +1,31 @@
import {log} from '../log'
import {prop, trim, tap} from 'ramda'
import {FoundBrowser, Browser, NotInstalledError} from '../types'
import execa = require('execa')
import { log } from '../log'
import { prop, trim, tap } from 'ramda'
import { FoundBrowser, Browser, NotInstalledError } from '../types'
import * as execa from 'execa'
const notInstalledErr = (name: string) => {
const err: NotInstalledError =
new Error(`Browser not installed: ${name}`) as NotInstalledError
const err: NotInstalledError = new Error(
`Browser not installed: ${name}`
) as NotInstalledError
err.notInstalled = true
throw err
}
function getLinuxBrowser (name: string, binary: string, versionRegex: RegExp): Promise<FoundBrowser> {
function getLinuxBrowser(
name: string,
binary: string,
versionRegex: RegExp
): Promise<FoundBrowser> {
const getVersion = (stdout: string) => {
const m = versionRegex.exec(stdout)
if (m) {
return m[1]
}
log('Could not extract version from %s using regex %s', stdout, versionRegex)
log(
'Could not extract version from %s using regex %s',
stdout,
versionRegex
)
return notInstalledErr(binary)
}
@@ -27,12 +36,13 @@ function getLinuxBrowser (name: string, binary: string, versionRegex: RegExp): P
const cmd = `${binary} --version`
log('looking using command "%s"', cmd)
return execa.shell(cmd)
return execa
.shell(cmd)
.then(prop('stdout'))
.then(trim)
.then(tap(log))
.then(getVersion)
.then((version) => {
.then(version => {
return {
name,
version,
@@ -42,6 +52,6 @@ function getLinuxBrowser (name: string, binary: string, versionRegex: RegExp): P
.catch(returnError)
}
export function detectBrowserLinux (browser: Browser) {
export function detectBrowserLinux(browser: Browser) {
return getLinuxBrowser(browser.name, browser.binary, browser.versionRegex)
}

View File

@@ -5,25 +5,25 @@ export type PlatformName = 'darwin' | 'linux'
export type Browser = {
/** short browser name */
name: MacBrowserName,
name: MacBrowserName
/** Optional display name */
displayName?: string,
displayName?: string
/** RegExp to use to extract version from something like "Google Chrome 58.0.3029.110" */
versionRegex: RegExp,
profile: boolean,
binary: string,
version?: string,
majorVersion?: string,
versionRegex: RegExp
profile: boolean
binary: string
version?: string
majorVersion?: string
page?: string
}
export type FoundBrowser = {
name: string,
name: string
path?: string
}
interface ExtraLauncherMethods {
update: Function,
update: Function
detect: Function
}
@@ -33,6 +33,6 @@ export type LauncherApi = LauncherLaunch & ExtraLauncherMethods
// all common type definition for this module
export type NotInstalledError = Error & {notInstalled: boolean}
export type NotInstalledError = Error & { notInstalled: boolean }
export type BrowserNotFoundError = Error & {specificBrowserNotFound: boolean}
export type BrowserNotFoundError = Error & { specificBrowserNotFound: boolean }

View File

@@ -9,9 +9,10 @@
"test": "mocha",
"clean-deps": "rm -rf node_modules",
"clean": "rm lib/*.js lib/**/*.js || true",
"lint": "npm run lint-ts && npm run lint-coffee",
"lint": "npm run format-ts && npm run lint-ts && npm run lint-coffee",
"lint-ts": "tslint --type-check --project . --fix --format stylish lib/*.ts lib/**/*.ts",
"lint-coffee": "../coffee/node_modules/.bin/coffeelint test/*.coffee test/**/*.coffee"
"lint-coffee": "../coffee/node_modules/.bin/coffeelint test/*.coffee test/**/*.coffee",
"format-ts": "prettier --no-semi --single-quote --write lib/*.ts lib/**/*.ts"
},
"repository": {
"type": "git",
@@ -34,9 +35,10 @@
"@types/node": "^7.0.18",
"chai": "^3.5.0",
"mocha": "^2.4.5",
"prettier": "^1.4.2",
"sinon": "^1.17.3",
"sinon-chai": "^2.8.0",
"tslint": "5.3.2",
"tslint": "5.4.3",
"tslint-config-standard": "5.0.2",
"typescript": "2.3.2"
},
@@ -47,7 +49,7 @@
"execa": "^0.6.3",
"fs-extra": "^3.0.0",
"lodash": "^4.11.1",
"plist": "^1.2.0",
"plist": "^2.1.0",
"ramda": "^0.23.0"
}
}

View File

@@ -14,7 +14,7 @@ describe('linux browser detection', () => {
execa.shell.restore()
})
it('is detects browser by running --version', () => {
it('detects browser by running --version', () => {
const goal = {
name: 'test-browser-name',
versionRegex: /v(\S+)$/,

View File

@@ -1,3 +1,6 @@
{
"extends": "tslint-config-standard"
"extends": "tslint-config-standard",
"rules": {
"space-before-function-paren": false
}
}