Skip to content

Commit

Permalink
feat: run yalc from anywhere
Browse files Browse the repository at this point in the history
Yalc now looks for the nearest ancestor that contains a package.json file.

I also did some tidying up!

Fixes wclr#47
  • Loading branch information
aleclarson committed Jan 11, 2019
1 parent ef1a0d3 commit bd9671c
Show file tree
Hide file tree
Showing 9 changed files with 129 additions and 117 deletions.
31 changes: 16 additions & 15 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 @@ -215,7 +216,7 @@ export const addPackages = async (
.map(_ => _!)

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

addPackageToLockfile(
Expand Down
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
}
40 changes: 27 additions & 13 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import * as fs from 'fs-extra'
import { join } from 'path'
import { homedir } from 'os'
import * as path from 'path'
import { PackageName } from './installations'

const userHome = require('user-home')
const { join } = path

export const values = {
myNameIs: 'yalc',
Expand Down Expand Up @@ -46,7 +47,7 @@ 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 {
Expand Down Expand Up @@ -102,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 @@ -169,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)
}
}
27 changes: 17 additions & 10 deletions src/publish.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ import {
execLoudOptions,
getPackageManager,
updatePackages,
readPackageManifest,
readPackage,
getStorePackagesDir,
PackageScripts
PackageScripts,
findPackage
} from '.'

export interface PublishPackageOptions {
Expand Down Expand Up @@ -57,20 +58,22 @@ const workaroundYarnCacheBug = async (pkg: PackageManifest) => {
}

export const publishPackage = async (options: PublishPackageOptions) => {
const workingDir = options.workingDir
const pkg = readPackageManifest(workingDir)
if (!pkg) {
return
}
const workingDir = findPackage(options.workingDir)
if (!workingDir) return

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

if (pkg.private && !options.private) {
console.log(
'Will not publish package with `private: true`' +
' use --private flag to force publishing.'
)
return
}

const scripts = pkg.scripts || ({} as PackageScripts)
const changeDirCmd = 'cd ' + options.workingDir + ' && '
const changeDirCmd = 'cd ' + workingDir + ' && '
const scriptRunCmd =
!options.force && pkg.scripts
? changeDirCmd + getPackageManager(workingDir) + ' run '
Expand All @@ -90,11 +93,13 @@ export const publishPackage = async (options: PublishPackageOptions) => {
execSync(scriptRunCmd + scriptName, execLoudOptions)
}
}

const copyRes = await copyPackageToStore(pkg, options)
if (options.changed && !copyRes) {
console.log('Package content has not changed, skipping publishing.')
return
}

if (scriptRunCmd) {
const scriptNames: (keyof PackageScripts)[] = ['postyalc', 'postpublish']
const scriptName = scriptNames.filter(name => !!scripts[name])[0]
Expand All @@ -116,13 +121,15 @@ export const publishPackage = async (options: PublishPackageOptions) => {
noInstallationsRemove: true,
yarn: options.yarn
})
installationsToRemove.concat(installationsToRemoveForPkg)
if (installationsToRemoveForPkg) {
installationsToRemove.push(...installationsToRemoveForPkg)
}
}
await removeInstallations(installationsToRemove)
}
//await workaroundYarnCacheBug(pkg)
const publishedPackageDir = join(getStorePackagesDir(), pkg.name, pkg.version)
const publishedPkg = readPackageManifest(publishedPackageDir)!
const publishedPkg = readPackage(publishedPackageDir)!
console.log(
`${publishedPkg.name}@${publishedPkg.version} published in store.`
)
Expand Down
Loading

0 comments on commit bd9671c

Please sign in to comment.