Skip to content

Commit

Permalink
fix: missing core yarn files (#1229) (#1230)
Browse files Browse the repository at this point in the history
* fix: missing core yarn files (#1229)

* fix: missing core yarn files

Newer versions of yarn depend on more files than "yarn.lock". As a result, the tarballs need to include these core files to ensure that any future commands against the tarball contents utilize the right version of `yarn`. Example: configuring yarn v4 with a "pinned version" requires the ".yarnrc.yml" file along with the `yarnPath` configuration value. If configured to use a specific version of yarn, Yarn will download required files into a "./.yarn/releases/" directory. In the future, any execution of `yarn` will pick up the `yarnPath` configuration and use the "./.yarn/releases/" directory contents to download and use the specific version of yarn.

* fix: yarn root path

* chore: satisfy linter

---------

Co-authored-by: Eric Swanson <ericis@users.noreply.github.com>
  • Loading branch information
mdonnalley and ericis committed Jan 2, 2024
1 parent 81222ca commit 9efd810
Showing 1 changed file with 45 additions and 2 deletions.
47 changes: 45 additions & 2 deletions src/tarballs/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,48 @@ const pack = async (from: string, to: string) => {
: await exec(`tar cfJ ${to} ${path.basename(from)}`, {cwd})
}

const isYarnProject = (yarnRootPath: string) => {
const yarnLockFileName = 'yarn.lock'
const rootYarnLockFilePath = path.join(yarnRootPath, yarnLockFileName)

return existsSync(rootYarnLockFilePath)
}

const copyCoreYarnFiles = async (yarnRootPath: string, workspacePath: string) => {
// copy yarn dependencies lock file
const yarnLockFileName = 'yarn.lock'
const rootYarnLockFilePath = path.join(yarnRootPath, yarnLockFileName)
const workspaceYarnLockFilePath = path.join(workspacePath, yarnLockFileName)

if (existsSync(rootYarnLockFilePath)) {
await copy(rootYarnLockFilePath, workspaceYarnLockFilePath)
}

// copy yarn configuration file
const yarnConfigFileName = '.yarnrc.yml'
const rootYarnConfigFilePath = path.join(yarnRootPath, yarnConfigFileName)
const workspaceYarnConfigFilePath = path.join(workspacePath, yarnConfigFileName)

if (existsSync(rootYarnConfigFilePath)) {
await copy(rootYarnConfigFilePath, workspaceYarnConfigFilePath)
}

// copy yarn releases e.g. yarn may be installed via a local config path like "yarnPath"
const yarnReleasesDirectoryRelativePath = './.yarn/releases/'
const rootYarnReleasesDirectoryPath = path.join(yarnRootPath, yarnReleasesDirectoryRelativePath)
const workspaceYarnReleasesDirectoryPath = path.join(workspacePath, yarnReleasesDirectoryRelativePath)

if (existsSync(rootYarnReleasesDirectoryPath)) {
// create the directory if it does not exist
if (!existsSync(workspaceYarnReleasesDirectoryPath)) {
await mkdir(workspaceYarnReleasesDirectoryPath, {recursive: true})
}

// recursively copy all files in the directory
await copy(rootYarnReleasesDirectoryPath, workspaceYarnReleasesDirectoryPath)
}
}

export async function build(
c: BuildConfig,
options: {
Expand Down Expand Up @@ -69,8 +111,9 @@ export async function build(

const addDependencies = async () => {
const yarnRoot = findYarnWorkspaceRoot(c.root) || c.root
if (existsSync(path.join(yarnRoot, 'yarn.lock'))) {
await copy(path.join(yarnRoot, 'yarn.lock'), path.join(c.workspace(), 'yarn.lock'))

if (isYarnProject(yarnRoot)) {
await copyCoreYarnFiles(yarnRoot, c.workspace())

const {stdout} = await exec('yarn -v')
const yarnVersion = stdout.charAt(0)
Expand Down

0 comments on commit 9efd810

Please sign in to comment.