chore(): start moving some packages to the core directory (#7215)

This commit is contained in:
Adrien de Peretti
2024-05-03 13:37:41 +02:00
committed by GitHub
parent fdee748eed
commit bbccd6481d
1436 changed files with 275 additions and 756 deletions
@@ -0,0 +1,19 @@
const signalExit = require(`signal-exit`);
const cleanupTasks = new Set();
exports.registerCleanupTask = (taskFn) => {
cleanupTasks.add(taskFn);
return () => {
const result = taskFn();
cleanupTasks.delete(taskFn);
return result;
};
};
signalExit(() => {
if (cleanupTasks.size) {
console.log(`Process exitted in middle of publishing - cleaning up`);
cleanupTasks.forEach((taskFn) => taskFn());
}
});
@@ -0,0 +1,79 @@
const startVerdaccio = require(`verdaccio`).default
const fs = require(`fs-extra`)
const _ = require(`lodash`)
let VerdaccioInitPromise = null
const { verdaccioConfig } = require(`./verdaccio-config`)
const { publishPackage } = require(`./publish-package`)
const { installPackages } = require(`./install-packages`)
const startServer = () => {
if (VerdaccioInitPromise) {
return VerdaccioInitPromise
}
console.log(`Starting local verdaccio server`)
// clear storage
fs.removeSync(verdaccioConfig.storage)
VerdaccioInitPromise = new Promise((resolve) => {
startVerdaccio(
verdaccioConfig,
verdaccioConfig.port,
verdaccioConfig.storage,
`1.0.0`,
`medusa-dev`,
(webServer, addr, pkgName, pkgVersion) => {
// console.log(webServer)
webServer.listen(addr.port || addr.path, addr.host, () => {
console.log(`Started local verdaccio server`)
resolve()
})
}
)
})
return VerdaccioInitPromise
}
exports.startVerdaccio = startServer
exports.publishPackagesLocallyAndInstall = async ({
packagesToPublish,
localPackages,
packageNameToPath,
ignorePackageJSONChanges,
yarnWorkspaceRoot,
externalRegistry,
root,
}) => {
await startServer()
const versionPostFix = Date.now()
const newlyPublishedPackageVersions = {}
for (const packageName of packagesToPublish) {
newlyPublishedPackageVersions[packageName] = await publishPackage({
packageName,
packagesToPublish,
packageNameToPath,
versionPostFix,
ignorePackageJSONChanges,
root,
})
}
const packagesToInstall = _.intersection(packagesToPublish, localPackages)
await installPackages({
packagesToInstall,
yarnWorkspaceRoot,
newlyPublishedPackageVersions,
externalRegistry,
})
}
@@ -0,0 +1,163 @@
const path = require(`path`)
const fs = require(`fs-extra`)
const { promisifiedSpawn } = require(`../utils/promisified-spawn`)
const { registryUrl } = require(`./verdaccio-config`)
const installPackages = async ({
packagesToInstall,
yarnWorkspaceRoot,
newlyPublishedPackageVersions,
externalRegistry,
}) => {
console.log(
`Installing packages from local registry:\n${packagesToInstall
.map((packageAndVersion) => ` - ${packageAndVersion}`)
.join(`\n`)}`
)
let installCmd
if (yarnWorkspaceRoot) {
// this is very hacky - given root, we run `yarn workspaces info`
// to get list of all workspaces and their locations, and manually
// edit package.json file for packages we want to install
// to make sure there are no mismatched versions of same package
// in workspaces which should preserve node_modules structure
// (packages being mostly hoisted to top-level node_modules)
const { stdout: yarnVersion } = await promisifiedSpawn([
`yarn`,
[`--version`],
{ stdio: `pipe` },
])
const workspaceCommand = !yarnVersion.startsWith("1") ? "list" : "info"
const { stdout } = await promisifiedSpawn([
`yarn`,
[`workspaces`, workspaceCommand, `--json`],
{ stdio: `pipe` },
])
let workspacesLayout
try {
workspacesLayout = JSON.parse(JSON.parse(stdout).data)
} catch (e) {
/*
Yarn 1.22 doesn't output pure json - it has leading and trailing text:
```
$ yarn workspaces info --json
yarn workspaces v1.22.0
{
"z": {
"location": "z",
"workspaceDependencies": [],
"mismatchedWorkspaceDependencies": []
},
"y": {
"location": "y",
"workspaceDependencies": [],
"mismatchedWorkspaceDependencies": []
}
}
Done in 0.48s.
```
So we need to do some sanitization. We find JSON by matching substring
that starts with `{` and ends with `}`
*/
const regex = /^[^{]*({.*})[^}]*$/gs
const sanitizedStdOut = regex.exec(stdout)
if (sanitizedStdOut?.length >= 2) {
// pick content of first (and only) capturing group
const jsonString = sanitizedStdOut[1]
try {
workspacesLayout = JSON.parse(jsonString)
} catch (e) {
console.error(
`Failed to parse "sanitized" output of "yarn workspaces info" command.\n\nSanitized string: "${jsonString}`
)
// not exitting here, because we have general check for `workspacesLayout` being set below
}
}
}
if (!workspacesLayout) {
console.error(
`Couldn't parse output of "yarn workspaces info" command`,
stdout
)
process.exit(1)
}
const handleDeps = (deps) => {
if (!deps) {
return false
}
let changed = false
Object.keys(deps).forEach((depName) => {
if (packagesToInstall.includes(depName)) {
deps[depName] = `medusa-dev`
changed = true
}
})
return changed
}
Object.keys(workspacesLayout).forEach((workspaceName) => {
const { location } = workspacesLayout[workspaceName]
const pkgJsonPath = path.join(yarnWorkspaceRoot, location, `package.json`)
if (!fs.existsSync(pkgJsonPath)) {
return
}
const pkg = JSON.parse(fs.readFileSync(pkgJsonPath, `utf8`))
let changed = false
changed |= handleDeps(pkg.dependencies)
changed |= handleDeps(pkg.devDependencies)
changed |= handleDeps(pkg.peerDependencies)
if (changed) {
console.log(`Changing deps in ${pkgJsonPath} to use @medusa-dev`)
fs.outputJSONSync(pkgJsonPath, pkg, {
spaces: 2,
})
}
})
// package.json files are changed - so we just want to install
// using verdaccio registry
const yarnCommands = [`install`]
if (!externalRegistry) {
yarnCommands.push(`--registry=${registryUrl}`)
}
installCmd = [`yarn`, yarnCommands]
} else {
const yarnCommands = [
`add`,
...packagesToInstall.map((packageName) => {
const packageVersion = newlyPublishedPackageVersions[packageName]
return `${packageName}@${packageVersion}`
}),
`--exact`,
]
if (!externalRegistry) {
yarnCommands.push(`--registry=${registryUrl}`)
}
installCmd = [`yarn`, yarnCommands]
}
try {
await promisifiedSpawn(installCmd)
console.log(`Installation complete`)
} catch (error) {
console.error(`Installation failed`, error)
process.exit(1)
}
}
exports.installPackages = installPackages
@@ -0,0 +1,158 @@
const fs = require(`fs-extra`)
const path = require(`path`)
const { promisifiedSpawn } = require(`../utils/promisified-spawn`)
const { registryUrl } = require(`./verdaccio-config`)
const NPMRCContent = `${registryUrl.replace(
/https?:/g,
``
)}/:_authToken="medusa-dev"`
const {
getMonorepoPackageJsonPath,
} = require(`../utils/get-monorepo-package-json-path`)
const { registerCleanupTask } = require(`./cleanup-tasks`)
/**
* Edit package.json to:
* - adjust version to temporary one
* - change version selectors for dependencies that
* will be published, to make sure that yarn
* install them in local site
*/
const adjustPackageJson = ({
monoRepoPackageJsonPath,
packageName,
versionPostFix,
packagesToPublish,
ignorePackageJSONChanges,
packageNameToPath,
}) => {
// we need to check if package depend on any other package to will be published and
// adjust version selector to point to dev version of package so local registry is used
// for dependencies.
const monorepoPKGjsonString = fs.readFileSync(
monoRepoPackageJsonPath,
`utf-8`
)
const monorepoPKGjson = JSON.parse(monorepoPKGjsonString)
monorepoPKGjson.version = `${monorepoPKGjson.version}-dev-${versionPostFix}`
packagesToPublish.forEach((packageThatWillBePublished) => {
if (
monorepoPKGjson.dependencies &&
monorepoPKGjson.dependencies[packageThatWillBePublished]
) {
const currentVersion = JSON.parse(
fs.readFileSync(
getMonorepoPackageJsonPath({
packageName: packageThatWillBePublished,
packageNameToPath,
}),
`utf-8`
)
).version
monorepoPKGjson.dependencies[
packageThatWillBePublished
] = `${currentVersion}-dev-${versionPostFix}`
}
})
const temporaryMonorepoPKGjsonString = JSON.stringify(monorepoPKGjson)
const unignorePackageJSONChanges = ignorePackageJSONChanges(packageName, [
monorepoPKGjsonString,
temporaryMonorepoPKGjsonString,
])
// change version and dependency versions
fs.outputFileSync(monoRepoPackageJsonPath, temporaryMonorepoPKGjsonString)
return {
newPackageVersion: monorepoPKGjson.version,
unadjustPackageJson: registerCleanupTask(() => {
// restore original package.json
fs.outputFileSync(monoRepoPackageJsonPath, monorepoPKGjsonString)
unignorePackageJSONChanges()
}),
}
}
/**
* Anonymous publishing require dummy .npmrc
* See https://github.com/verdaccio/verdaccio/issues/212#issuecomment-308578500
* This is `npm publish` (as in linked comment) and `yarn publish` requirement.
* This is not verdaccio restriction.
*/
const createTemporaryNPMRC = ({ pathToPackage, root }) => {
const NPMRCPathInPackage = path.join(pathToPackage, `.npmrc`)
fs.outputFileSync(NPMRCPathInPackage, NPMRCContent)
const NPMRCPathInRoot = path.join(root, `.npmrc`)
fs.outputFileSync(NPMRCPathInRoot, NPMRCContent)
return registerCleanupTask(() => {
fs.removeSync(NPMRCPathInPackage)
fs.removeSync(NPMRCPathInRoot)
})
}
const publishPackage = async ({
packageName,
packagesToPublish,
versionPostFix,
ignorePackageJSONChanges,
packageNameToPath,
root,
}) => {
const monoRepoPackageJsonPath = getMonorepoPackageJsonPath({
packageName,
packageNameToPath,
})
const { unadjustPackageJson, newPackageVersion } = adjustPackageJson({
monoRepoPackageJsonPath,
packageName,
packageNameToPath,
versionPostFix,
packagesToPublish,
ignorePackageJSONChanges,
})
const pathToPackage = path.dirname(monoRepoPackageJsonPath)
const uncreateTemporaryNPMRC = createTemporaryNPMRC({ pathToPackage, root })
// npm publish
const publishCmd = [
`npm`,
[`publish`, `--tag`, `medusa-dev`, `--registry=${registryUrl}`],
{
cwd: pathToPackage,
},
]
console.log(
`Publishing ${packageName}@${newPackageVersion} to local registry`
)
try {
await promisifiedSpawn(publishCmd)
console.log(
`Published ${packageName}@${newPackageVersion} to local registry`
)
} catch (e) {
console.error(`Failed to publish ${packageName}@${newPackageVersion}`, e)
process.exit(1)
}
uncreateTemporaryNPMRC()
unadjustPackageJson()
return newPackageVersion
}
exports.publishPackage = publishPackage
@@ -0,0 +1,33 @@
const path = require(`path`)
const os = require(`os`)
const verdaccioConfig = {
storage: path.join(os.tmpdir(), `verdaccio`, `storage`),
port: 4873, // default
max_body_size: `1000mb`,
web: {
enable: true,
title: `gatsby-dev`,
},
logs: [{ type: `stdout`, format: `pretty-timestamped`, level: `warn` }],
packages: {
"**": {
access: `$all`,
publish: `$all`,
proxy: `npmjs`,
},
},
uplinks: {
npmjs: {
url: `https://registry.npmjs.org/`,
// default is 2 max_fails - on flaky networks that cause a lot of failed installations
max_fails: 10,
},
},
}
exports.verdaccioConfig = verdaccioConfig
const registryUrl = `http://localhost:${verdaccioConfig.port}`
exports.registryUrl = registryUrl