Skip to content

Commit

Permalink
feat: find pkg manager installation, index refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
leoortizz committed Feb 21, 2022
1 parent a12375a commit c8ba014
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 79 deletions.
159 changes: 80 additions & 79 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,65 +1,60 @@
#!/usr/bin/env node

import { promisify } from 'util'
import { exec as realExec } from 'child_process'
import { writeFileSync, stat } from 'fs'
import { getReadlineInterface } from './utils'
import { writeFileSync } from 'fs'
import { question, fileExists, exec, ESLINT_FILENAME, PROJECT_DIR } from './utils'
import { configs, availableConfigs, type AvailableConfig } from './configs'
import { packageManagers, type PackageManager, installPrefixes } from './package-managers'
import {
packageManagers,
type PackageManager,
installPrefixes,
findPackageManager
} from './package-managers'

// check if ESLint file already exists to prevent unwanted overwrites
if (fileExists(`${PROJECT_DIR}/${ESLINT_FILENAME}`)) {
question(`\nDo you want to replace the current ${ESLINT_FILENAME} file? \n[y,n] `).then(
(answer) => {
const shouldReplaceCurrentConfig = answer?.toLowerCase() === 'y'

if (shouldReplaceCurrentConfig) {
handleCreate()
}
}
)
}

async function handleCreate() {
const config = await chooseConfig()

const exec = promisify(realExec)
if (config) {
const packageManager = await choosePackageManager()

const esLintFilename = '.eslintrc'
const projectDir = process.cwd()
if (packageManager) {
createESLintConfig(config)
await installDependencies(config, packageManager)
} else {
console.log(`❌ Package manager not available`)
}
} else {
console.log(`❌ Configuration not available`)
}
}

handleCreate()
async function chooseConfig(): Promise<AvailableConfig | null> {
let config: AvailableConfig | null = null

function handleCreate() {
const rl = getReadlineInterface()
const configOptions = availableConfigs.join(', ')

rl.question(`Which ESLint configuration do you want? [${configOptions}] `, (answer) => {
rl.close()
chooseConfig(answer.toLowerCase())
})
}
const chosenConfig = await question(
`\nWhich ESLint configuration do you want to install? \n[${configOptions}] `
)

function chooseConfig(whichConfig: string) {
if (availableConfigs.includes(whichConfig as AvailableConfig)) {
stat(`${projectDir}/${esLintFilename}`, (error, stats) => {
if (stats) {
const rl = getReadlineInterface()

rl.question(
`Do you want to replace the current ${esLintFilename} file? [y,n] `,
(answer) => {
rl.close()

const lowerCaseAnswer = answer.toLowerCase()

if (lowerCaseAnswer === 'y') {
configESLint(whichConfig as AvailableConfig)
} else if (lowerCaseAnswer === 'n') {
process.exit(0)
} else {
console.error('❌ Please insert y or n')
process.exit(0)
}
}
)
} else {
configESLint(whichConfig as AvailableConfig)
}
})
if (availableConfigs.includes(chosenConfig as AvailableConfig)) {
config = chosenConfig as AvailableConfig
} else {
console.log(`❌ ${whichConfig} is not available`)
config = chosenConfig as AvailableConfig
}
}

async function configESLint(whichConfig: AvailableConfig) {
createESLintConfig(whichConfig)

await installDependencies(whichConfig)
return config
}

function createESLintConfig(whichConfig: AvailableConfig) {
Expand All @@ -71,47 +66,53 @@ function createESLintConfig(whichConfig: AvailableConfig) {
2 // TODO : get config from prettier
)

writeFileSync(`${projectDir}/.eslintrc`, dataAsString)
writeFileSync(`${PROJECT_DIR}/.eslintrc`, dataAsString)

console.log(`\n✅ ESLint configuration file created at ${projectDir}/${esLintFilename}\n`)
console.log(`\n✅ ESLint configuration file created at ${PROJECT_DIR}/${ESLINT_FILENAME}`)
}

async function installDependencies(whichConfig: AvailableConfig) {
const rl = getReadlineInterface()
const packageManagersOptions = packageManagers.join(', ')
async function choosePackageManager() {
let packageManager = findPackageManager()

rl.question(
`Which package manager should be used? [${packageManagersOptions}] `,
(whichManager): void => {
if (packageManagersOptions.includes(whichManager as PackageManager)) {
rl.close()
if (packageManager) {
console.log(`📦 An existing ${packageManager} installation was found`)
} else {
const packageManagersOptions = packageManagers.join(', ')

const installPrefix = installPrefixes[whichManager]
const chosenManager = await question(
`Which package manager should be used? \n[${packageManagersOptions}] `
)

const { dependencies } = configs[whichConfig]
const dependenciesAsString = dependencies.join(' ')
if (packageManagersOptions.includes(chosenManager as PackageManager)) {
packageManager = chosenManager as PackageManager
}
}

return packageManager
}

const installCommand = `${installPrefix} ${dependenciesAsString}`
async function installDependencies(config: AvailableConfig, packageManager: PackageManager) {
const installPrefix = installPrefixes[packageManager]

console.log(`\nInstalling dependencies...`)
console.log(`${installCommand}\n`)
const { dependencies } = configs[config]
const dependenciesAsString = dependencies.join(' ')

exec(
installCommand,
// @ts-ignore
(stdout: string, stderr: string) => {
if (stderr) {
console.error(stderr)
} else {
console.log(stdout)
}
const installCommand = `${installPrefix} ${dependenciesAsString}`

Promise.resolve({ stdout, stderr })
}
)
console.log(`📦 Installing dependencies...`)
console.log(`${installCommand}\n`)

await exec(
installCommand,
// @ts-ignore
(stdout: string, stderr: string) => {
if (stderr) {
console.error(stderr)
} else {
console.log(` ${whichConfig} is not available`)
console.log(stdout)
}

Promise.resolve({ stdout, stderr })
}
)
}
18 changes: 18 additions & 0 deletions src/package-managers.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { fileExists, PROJECT_DIR } from './utils'

export const packageManagers = ['yarn', 'pnpm', 'npm'] as const

export type PackageManagers = typeof packageManagers
Expand All @@ -8,3 +10,19 @@ export const installPrefixes = {
pnpm: 'pnpm i -D',
npm: 'npm i -D'
} as const

export const lockFiles = {
yarn: `${PROJECT_DIR}/yarn.lock`,
pnpm: `${PROJECT_DIR}/pnpm-lock.yaml`,
npm: `${PROJECT_DIR}/package-lock.json`
}

export function findPackageManager(): PackageManager | null {
const found = packageManagers.find((pkg: PackageManager) => {
if (fileExists(lockFiles[pkg as PackageManager])) return pkg

return null
})

return found as PackageManager | null
}

0 comments on commit c8ba014

Please sign in to comment.