Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(remove): update node_modules/.bin #63

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
12 changes: 4 additions & 8 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,9 @@
{
"taskName": "tsc",
"command": "node",
"args": [
"./node_modules/typescript/lib/tsc.js",
"-w",
"-p",
"."
],
"args": ["./node_modules/typescript/lib/tsc.js", "-w", "-p", "."],
"isBackground": true,
"problemMatcher": "$tsc-watch"
}]
}
}
]
}
10 changes: 7 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,17 @@
"scripts": {
"build": "tsc",
"clean": "trash **/*.js **/*.js.map **/*.d.ts **/*.log !**/node_modules/**",
"precommit": "yalc check",
"prepublishOnly": "yarn clean && tsc && yarn test",
"test": "tsc && mocha test && yarn lint",
"watch": "mocha test --watch",
"ci": "tsc && yarn test",
"lint": "tslint -p ."
},
"husky": {
"hooks": {
"pre-commit": "yalc check && pretty-quick --staged"
}
},
"dependencies": {
"del": "^2.2.2",
"fs-extra": "^4.0.2",
Expand All @@ -44,11 +48,11 @@
"@types/npm-packlist": "^1.1.0",
"@types/yargs": "^6.6.0",
"clean-ts-built": "^1.0.0",
"husky": "^0.13.3",
"husky": "^1.3.1",
"mocha": "^5.2.0",
"prettier": "^1.14.2",
"pretty-quick": "^1.8.0",
"trash-cli": "^1.4.0",
"ts-clean-built": "^1.0.0",
"tslint": "^5.11.0",
"tslint-config-prettier": "^1.15.0",
"tslint-plugin-prettier": "^1.3.0",
Expand Down
57 changes: 40 additions & 17 deletions src/add.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ import {
getPackageStoreDir,
values,
parsePackageName,
readPackageManifest,
writePackageManifest,
readSignatureFile
readPackage,
writePackage,
readSignatureFile,
findPackage
} from '.'

const ensureSymlinkSync = fs.ensureSymlinkSync as typeof fs.symlinkSync
Expand Down Expand Up @@ -64,14 +65,16 @@ export const addPackages = async (
packages: string[],
options: AddPackagesOptions
) => {
const workingDir = options.workingDir
const localPkg = readPackageManifest(workingDir)
const workingDir = findPackage(options.workingDir)
if (!workingDir) return

const localPkg = readPackage(workingDir)
if (!localPkg) return

let localPkgUpdated = false
if (!localPkg) {
return
}
const doPure =
options.pure === false ? false : options.pure || !!localPkg.workspaces

const addedInstalls = packages
.map(packageName => {
const { name, version = '' } = parsePackageName(packageName)
Expand All @@ -87,10 +90,9 @@ export const addPackages = async (
)
return null
}
const versionToInstall = version || getLatestPackageVersion(name)

const versionToInstall = version || getLatestPackageVersion(name)
const storedPackageDir = getPackageStoreDir(name, versionToInstall)

if (!fs.existsSync(storedPackageDir)) {
console.log(
`Could not find package \`${packageName}\` ` + storedPackageDir,
Expand All @@ -99,12 +101,12 @@ export const addPackages = async (
return null
}

const pkg = readPackageManifest(storedPackageDir)
const pkg = readPackage(storedPackageDir)
if (!pkg) {
return
}
const destYalcCopyDir = join(workingDir, values.yalcPackagesFolder, name)

const destYalcCopyDir = join(workingDir, values.yalcPackagesFolder, name)
emptyDirExcludeNodeModules(destYalcCopyDir)
fs.copySync(storedPackageDir, destYalcCopyDir)

Expand All @@ -124,8 +126,7 @@ export const addPackages = async (
name
)} purely`
)
}
if (!doPure) {
} else {
const destModulesDir = join(workingDir, 'node_modules', name)
if (options.link || options.linkDep || isSymlink(destModulesDir)) {
fs.removeSync(destModulesDir)
Expand Down Expand Up @@ -174,9 +175,31 @@ export const addPackages = async (
replacedVersion =
replacedVersion == localAddress ? '' : replacedVersion
}

if (pkg.bin) {
const binDir = join(workingDir, 'node_modules', '.bin')
const addBinScript = (src: string, dest: string) => {
const srcPath = join(destYalcCopyDir, src)
const destPath = join(binDir, dest)
ensureSymlinkSync(srcPath, destPath)
fs.chmodSync(destPath, 700)
}
if (typeof pkg.bin === 'string') {
fs.ensureDirSync(binDir)
addBinScript(pkg.bin, pkg.name)
} else if (typeof pkg.bin === 'object') {
fs.ensureDirSync(binDir)
for (const name in pkg.bin) {
addBinScript(pkg.bin[name], name)
}
}
}

const addedAction = options.link ? 'linked' : 'added'
console.log(
`Package ${pkg.name}@${pkg.version} ${addedAction} ==> ${destModulesDir}.`
`Package ${pkg.name}@${
pkg.version
} ${addedAction} ==> ${destModulesDir}.`
)
}

Expand All @@ -193,7 +216,7 @@ export const addPackages = async (
.map(_ => _!)

if (localPkgUpdated) {
writePackageManifest(workingDir, localPkg)
writePackage(workingDir, localPkg)
}

addPackageToLockfile(
Expand All @@ -213,6 +236,6 @@ export const addPackages = async (

if (options.yarn) {
console.log('Running yarn:')
execSync('yarn', {cwd: options.workingDir})
execSync('yarn', { cwd: options.workingDir })
}
}
32 changes: 8 additions & 24 deletions src/check.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,12 @@
import * as fs from 'fs-extra'
import { execSync } from 'child_process'
import * as path from 'path'
import { join } from 'path'
import { PackageManifest, values } from '.'
import { PackageManifest, values, findPackage } from '.'

export type CheckOptions = {
workingDir: string
all?: boolean
commit?: boolean
}

const stagedChangesCmd = 'git diff --cached --name-only'

const isPackageManifest = (fileName: string) =>
path.basename(fileName) === 'package.json'

export function checkManifest(options: CheckOptions) {
const findLocalDepsInManifest = (manifestPath: string) => {
const pkg = fs.readJSONSync(manifestPath) as PackageManifest
Expand All @@ -30,23 +22,15 @@ export function checkManifest(options: CheckOptions) {
return localDeps
}

if (options.commit) {
execSync(stagedChangesCmd, {
cwd: options.workingDir
})
.toString()
.trim()
execSync(stagedChangesCmd, {
cwd: options.workingDir
})
.toString()
.trim()
.split('\n')
.filter(isPackageManifest)
const workingDir = findPackage(options.workingDir)
if (!workingDir) {
console.log('Not inside a package')
return process.exit(1)
}

const manifestPath = join(options.workingDir, 'package.json')
const localDeps = findLocalDepsInManifest(manifestPath)
const localDeps = findLocalDepsInManifest(
path.join(workingDir, 'package.json')
)
if (localDeps.length) {
console.log('Yalc dependencies found:', localDeps)
process.exit(1)
Expand Down
5 changes: 2 additions & 3 deletions src/copy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ import { readIgnoreFile, readSignatureFile } from '.'
import {
PackageManifest,
getStorePackagesDir,
readPackageManifest,
writePackageManifest,
writePackage,
writeSignatureFile
} from '.'

Expand Down Expand Up @@ -137,6 +136,6 @@ export const copyPackageToStore = async (
version: pkg.version + versionPre,
devDependencies: undefined
}
writePackageManifest(storePackageStoreDir, pkgToWrite)
writePackage(storePackageStoreDir, pkgToWrite)
return signature
}
46 changes: 29 additions & 17 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import * as fs from 'fs-extra'
import { homedir } from 'os'
import * as path from 'path'
import { PackageName } from './installations'

const userHome = require('user-home')

const { join } = path

export const values = {
Expand Down Expand Up @@ -48,15 +47,15 @@ export function getStoreMainDir(): string {
if (process.platform === 'win32' && process.env.LOCALAPPDATA) {
return join(process.env.LOCALAPPDATA, values.myNameIsCapitalized)
}
return join(userHome, '.' + values.myNameIs)
return join(homedir(), '.' + values.myNameIs)
}

export function getStorePackagesDir(): string {
return join(getStoreMainDir(), 'packages')
}

export const getPackageStoreDir = (packageName: string, version = '') =>
path.join(getStorePackagesDir(), packageName, version)
join(getStorePackagesDir(), packageName, version)

export type PackageScripts = Partial<{
preinstall: string
Expand All @@ -75,16 +74,16 @@ export interface PackageManifest {
name: string
version: string
private?: boolean
files: string[]
bin?: string | { [name: string]: string }
dependencies?: { [name: string]: string }
devDependencies?: { [name: string]: string }
workspaces?: string[]
scripts?: PackageScripts
__JSONSpaces: number
}

export const getPackageManager = (workingDir: string) =>
fs.existsSync('yarn.lock') ? 'yarn' : 'npm'
export const getPackageManager = (cwd: string) =>
fs.existsSync(join(cwd, 'yarn.lock')) ? 'yarn' : 'npm'

export const execLoudOptions = { stdio: 'inherit' }

Expand All @@ -104,28 +103,38 @@ const getJSONSpaces = (jsonStr: string) => {
return match && match[1] ? match[1].length : null
}

export function readPackageManifest(workingDir: string) {
export function findPackage(workingDir: string) {
let dir = path.resolve(workingDir)
while (true) {
const pkg = join(dir, 'package.json')
if (fs.existsSync(pkg)) return dir
if (dir === '/') return null
dir = path.dirname(dir)
}
}

export function readPackage(packageDir: string) {
let pkg: PackageManifest
const packagePath = join(workingDir, 'package.json')
const manifestPath = join(packageDir, 'package.json')
try {
const fileData = fs.readFileSync(packagePath, 'utf-8')
const fileData = fs.readFileSync(manifestPath, 'utf-8')
pkg = JSON.parse(fileData) as PackageManifest
if (!pkg.name && pkg.version) {
console.log(
'Package manifest',
packagePath,
manifestPath,
'should contain name and version.'
)
return null
}
const formatSpaces = getJSONSpaces(fileData) || 2
if (!formatSpaces) {
console.log('Could not get JSON formatting for', packagePath, 'using 2')
console.log('Could not get JSON formatting for', manifestPath, 'using 2')
}
pkg.__JSONSpaces = formatSpaces
return pkg
} catch (e) {
console.error('Could not read', packagePath)
console.error('Could not read', manifestPath)
return null
}
}
Expand Down Expand Up @@ -171,23 +180,26 @@ const sortDependencies = (dependencies: { [name: string]: string }) => {
)
}

export function writePackageManifest(workingDir: string, pkg: PackageManifest) {
export function writePackage(packageDir: string, pkg: PackageManifest) {
pkg = Object.assign({}, pkg)

if (pkg.dependencies) {
pkg.dependencies = sortDependencies(pkg.dependencies)
}
if (pkg.devDependencies) {
pkg.devDependencies = sortDependencies(pkg.devDependencies)
}

const formatSpaces = pkg.__JSONSpaces
delete pkg.__JSONSpaces
const packagePath = join(workingDir, 'package.json')

const manifestPath = join(packageDir, 'package.json')
try {
fs.writeFileSync(
packagePath,
manifestPath,
JSON.stringify(pkg, null, formatSpaces) + '\n'
)
} catch (e) {
console.error('Could not write ', packagePath)
console.error('Could not write ', manifestPath)
}
}