2017-08-21 05:49:32 +00:00
"use strict" ;
2017-12-09 20:06:41 +00:00
const _ = require ( "lodash" ) ;
2018-06-15 20:31:06 +00:00
const log = require ( "../log" ) ;
2018-03-02 18:28:54 +00:00
const colors = require ( "chalk" ) ;
2017-08-21 06:03:40 +00:00
const fs = require ( "fs" ) ;
2017-12-08 04:00:27 +00:00
const Helper = require ( "../helper" ) ;
2017-08-21 06:03:40 +00:00
const path = require ( "path" ) ;
2017-11-19 18:21:37 +00:00
let home ;
2017-08-21 05:49:32 +00:00
class Utils {
static extraHelp ( ) {
[
"" ,
"" ,
" Environment variable:" ,
"" ,
2017-12-08 04:00:27 +00:00
` THELOUNGE_HOME Path for all configuration files and folders. Defaults to ${ colors . green ( Helper . expandHome ( Utils . defaultHome ( ) ) ) } . ` ,
2017-08-21 05:49:32 +00:00
"" ,
2017-12-09 07:11:05 +00:00
] . forEach ( ( e ) => log . raw ( e ) ) ;
2017-08-21 05:49:32 +00:00
}
2017-08-21 06:03:40 +00:00
2018-03-02 16:59:37 +00:00
// TODO: Remove in a couple of releases
static checkOldHome ( ) {
const currentHome = Helper . getHomePath ( ) ;
const oldHome = currentHome . replace ( /\.thelounge$/ , ".lounge" ) ;
if ( currentHome === oldHome || ! fs . existsSync ( oldHome ) ) {
return ;
}
console . log ( ) ; // eslint-disable-line no-console
log . warn ( ` Folder ${ colors . bold . red ( oldHome ) } still exists. ` ) ;
log . warn ( ` In v3, we renamed the default configuration folder to ${ colors . bold . green ( ".thelounge" ) } for consistency. ` ) ;
log . warn ( ` You might want to rename the folder from ${ colors . bold . red ( ".lounge" ) } to ${ colors . bold . green ( ".thelounge" ) } to keep existing configuration. ` ) ;
log . warn ( "Make sure to look at the release notes to see other breaking changes." ) ;
console . log ( ) ; // eslint-disable-line no-console
}
2017-11-19 18:21:37 +00:00
static defaultHome ( ) {
if ( home ) {
return home ;
2017-08-21 06:03:40 +00:00
}
2017-11-19 18:21:37 +00:00
2018-02-19 18:43:53 +00:00
const distConfig = path . resolve ( path . join (
2017-08-21 06:03:40 +00:00
_ _dirname ,
".." ,
".." ,
2018-02-19 18:43:53 +00:00
".thelounge_home"
2017-08-21 06:03:40 +00:00
) ) ;
2017-11-19 18:21:37 +00:00
home = fs . readFileSync ( distConfig , "utf-8" ) . trim ( ) ;
2017-08-21 06:03:40 +00:00
2017-11-19 18:21:37 +00:00
return home ;
2017-08-21 06:03:40 +00:00
}
2017-12-09 20:06:41 +00:00
// Parses CLI options such as `-c public=true`, `-c debug.raw=true`, etc.
static parseConfigOptions ( val , memo ) {
// Invalid option that is not of format `key=value`, do nothing
if ( ! val . includes ( "=" ) ) {
return memo ;
}
const parseValue = ( value ) => {
if ( value === "true" ) {
return true ;
} else if ( value === "false" ) {
return false ;
} else if ( value === "undefined" ) {
return undefined ;
} else if ( value === "null" ) {
return null ;
} else if ( /^\[.*\]$/ . test ( value ) ) { // Arrays
// Supporting arrays `[a,b]` and `[a, b]`
const array = value . slice ( 1 , - 1 ) . split ( /,\s*/ ) ;
2018-02-20 07:28:04 +00:00
2017-12-09 20:06:41 +00:00
// If [] is given, it will be parsed as `[ "" ]`, so treat this as empty
if ( array . length === 1 && array [ 0 ] === "" ) {
return [ ] ;
}
2018-02-20 07:28:04 +00:00
2017-12-09 20:06:41 +00:00
return array . map ( parseValue ) ; // Re-parses all values of the array
}
2018-02-20 07:28:04 +00:00
2017-12-09 20:06:41 +00:00
return value ;
} ;
// First time the option is parsed, memo is not set
if ( memo === undefined ) {
memo = { } ;
}
// Note: If passed `-c foo="bar=42"` (with single or double quotes), `val`
// will always be passed as `foo=bar=42`, never with quotes.
const position = val . indexOf ( "=" ) ; // Only split on the first = found
const key = val . slice ( 0 , position ) ;
const value = val . slice ( position + 1 ) ;
const parsedValue = parseValue ( value ) ;
if ( _ . has ( memo , key ) ) {
log . warn ( ` Configuration key ${ colors . bold ( key ) } was already specified, ignoring... ` ) ;
} else {
memo = _ . set ( memo , key , parsedValue ) ;
}
return memo ;
}
2018-04-24 18:38:54 +00:00
2019-01-16 10:51:52 +00:00
static executeYarnCommand ( command , ... parameters ) {
2018-04-24 18:38:54 +00:00
// First off, try to find yarn inside of The Lounge
let yarn = path . join (
_ _dirname , ".." , ".." , "node_modules" ,
"yarn" , "bin" , "yarn.js"
) ;
if ( ! fs . existsSync ( yarn ) ) {
// Now try to find yarn in the same parent folder as The Lounge (flat install)
yarn = path . join (
_ _dirname , ".." , ".." , ".." ,
"yarn" , "bin" , "yarn.js"
) ;
if ( ! fs . existsSync ( yarn ) ) {
// Fallback to global installation
yarn = "yarn" ;
}
}
2019-01-16 10:51:52 +00:00
const packagesPath = Helper . getPackagesPath ( ) ;
const cachePath = path . join ( packagesPath , "package_manager_cache" ) ;
const staticParameters = [
"--cache-folder" ,
cachePath ,
"--cwd" ,
packagesPath ,
"--json" ,
"--ignore-scripts" ,
"--non-interactive" ,
] ;
2018-04-24 18:38:54 +00:00
return new Promise ( ( resolve , reject ) => {
let success = false ;
2019-01-16 10:51:52 +00:00
const add = require ( "child_process" ) . spawn ( process . execPath , [
yarn ,
command ,
... staticParameters ,
... parameters ,
] ) ;
2018-04-24 18:38:54 +00:00
add . stdout . on ( "data" , ( data ) => {
data . toString ( ) . trim ( ) . split ( "\n" ) . forEach ( ( line ) => {
line = JSON . parse ( line ) ;
if ( line . type === "success" ) {
success = true ;
}
} ) ;
} ) ;
add . stderr . on ( "data" , ( data ) => {
data . toString ( ) . trim ( ) . split ( "\n" ) . forEach ( ( line ) => {
const json = JSON . parse ( line ) ;
if ( json . type === "error" ) {
log . error ( json . data ) ;
}
} ) ;
} ) ;
add . on ( "error" , ( e ) => {
log . error ( ` ${ e } ` ) ;
process . exit ( 1 ) ;
} ) ;
add . on ( "close" , ( code ) => {
if ( ! success || code !== 0 ) {
return reject ( code ) ;
}
resolve ( ) ;
} ) ;
} ) ;
}
2017-08-21 05:49:32 +00:00
}
module . exports = Utils ;