|
| 1 | +/** |
| 2 | + * |
| 3 | + * all intrapackage deps modified to be gitpkg deps -> git branch name |
| 4 | + * get rid of volta entries in package.json files |
| 5 | + * create gitpkg url for @sentry/nextjs to use in test app -> git branch name |
| 6 | + * cobble together complete tsconfigs - no more "extends" (use `tsc --showConfig`, but beware relative paths) |
| 7 | + * |
| 8 | + * |
| 9 | + * |
| 10 | + * require package.json and tsconfig.x.json, modify the values, write to disk w JSON.stringify(), the use prettier to clean them up |
| 11 | + * |
| 12 | + */ |
| 13 | + |
| 14 | +import { exec } from 'child_process'; |
| 15 | +import * as eslint from 'eslint'; |
| 16 | +import * as fs from 'fs'; |
| 17 | +import * as path from 'path'; |
| 18 | +import * as prettier from 'prettier'; |
| 19 | +// import * as ts from 'typescript'; |
| 20 | +import { promisify } from 'util'; |
| 21 | + |
| 22 | +// eslint-disable-next-line @typescript-eslint/no-explicit-any |
| 23 | +type PlainObject<T = any> = { [key: string]: T }; |
| 24 | +type StringObject = PlainObject<string>; |
| 25 | + |
| 26 | +type PackageJSON = { name: string; dependencies: StringObject; devDependencies: StringObject; volta?: StringObject }; |
| 27 | + |
| 28 | +async function asyncForEach<T>(arr: T[], callback: (element: T, index: number, arr: T[]) => unknown): Promise<void> { |
| 29 | + for (let i = 0; i < arr.length; i++) { |
| 30 | + await callback(arr[i], i, arr); |
| 31 | + } |
| 32 | +} |
| 33 | + |
| 34 | +async function doPatching(): Promise<void> { |
| 35 | + // const packageNames = fs.readdirSync('../../packages').filter(name => { |
| 36 | + // const packagePath = path.resolve('../../packages', name); |
| 37 | + // return fs.statSync(packagePath).isDirectory(); |
| 38 | + // }); |
| 39 | + |
| 40 | + const packagesDir = path.resolve('../../packages'); |
| 41 | + |
| 42 | + // get the names of all the packages |
| 43 | + const packageDirNames: string[] = fs |
| 44 | + .readdirSync(packagesDir) |
| 45 | + .map(fileOrDir => path.resolve(packagesDir, fileOrDir)) |
| 46 | + .filter(fileOrDirPath => fs.statSync(fileOrDirPath).isDirectory()) |
| 47 | + .map(dirAbsPath => path.basename(dirAbsPath)); |
| 48 | + |
| 49 | + // compute a gitPkg URL for each, and cache it (this is in a separate loop because we'll need these from the first |
| 50 | + // iteration of the next loop) |
| 51 | + const gitBranch = await getGitBranch(); |
| 52 | + const gitPkgURLs: StringObject = {}; |
| 53 | + packageDirNames.forEach(dirName => { |
| 54 | + const npmName = ['eslint-config-sdk', 'eslint-plugin-sdk', 'typescript'].includes(dirName) |
| 55 | + ? `@sentry-internal/${dirName}` |
| 56 | + : `@sentry/${dirName}`; |
| 57 | + gitPkgURLs[npmName] = `https://gitpkg.now.sh/getsentry/sentry-javascript/packages/${dirName}?${gitBranch}`; |
| 58 | + }); |
| 59 | + |
| 60 | + // make the necessary changes in each package |
| 61 | + await asyncForEach(packageDirNames, async dirName => { |
| 62 | + const packageJSONPath = path.resolve(packagesDir, dirName, 'package.json'); |
| 63 | + |
| 64 | + // eslint-disable-next-line @typescript-eslint/no-var-requires |
| 65 | + const packageJSON = require(packageJSONPath) as PackageJSON; |
| 66 | + |
| 67 | + // we don't care about it and it's got a relative path that might not play well on vercel |
| 68 | + delete packageJSON.volta; |
| 69 | + |
| 70 | + // replace the versions of all `@sentry/x` packages (the ones from this repo, at least) with the appropriate URL, in |
| 71 | + // both regular and dev dependencies |
| 72 | + for (const depName in packageJSON.dependencies) { |
| 73 | + if (depName in gitPkgURLs) { |
| 74 | + packageJSON.dependencies[depName] = gitPkgURLs[depName]; |
| 75 | + } |
| 76 | + } |
| 77 | + for (const depName in packageJSON.devDependencies) { |
| 78 | + if (depName in gitPkgURLs) { |
| 79 | + packageJSON.devDependencies[depName] = gitPkgURLs[depName]; |
| 80 | + } |
| 81 | + } |
| 82 | + |
| 83 | + const eslintConfig: PlainObject = { |
| 84 | + fix: true, |
| 85 | + overrideConfig: { |
| 86 | + plugins: ['jsonc'], |
| 87 | + extends: ['plugin:jsonc/base'], |
| 88 | + overrides: [ |
| 89 | + { |
| 90 | + files: ['*.json'], |
| 91 | + rules: { |
| 92 | + 'jsonc/array-bracket-newline': [ |
| 93 | + 'error', |
| 94 | + { |
| 95 | + multiline: true, |
| 96 | + minItems: 1, |
| 97 | + }, |
| 98 | + ], |
| 99 | + 'jsonc/object-curly-newline': [ |
| 100 | + 'error', |
| 101 | + { |
| 102 | + ObjectExpression: { multiline: true, minProperties: 1 }, |
| 103 | + }, |
| 104 | + ], |
| 105 | + 'jsonc/array-element-newline': [ |
| 106 | + 'error', |
| 107 | + { |
| 108 | + multiline: true, |
| 109 | + minItems: 1, |
| 110 | + }, |
| 111 | + ], |
| 112 | + 'jsonc/object-property-newline': ['error'], |
| 113 | + 'jsonc/indent': ['error', 2], |
| 114 | + 'no-trailing-spaces': 'error', |
| 115 | + }, |
| 116 | + }, |
| 117 | + ], |
| 118 | + }, |
| 119 | + }; |
| 120 | + |
| 121 | + await prettier |
| 122 | + .resolveConfigFile() |
| 123 | + .then(configFilepath => prettier.resolveConfig(configFilepath as string)) |
| 124 | + .then(options => prettier.format(JSON.stringify(packageJSON), { ...options, parser: 'json' } as prettier.Options)) |
| 125 | + .then(finalOutput => |
| 126 | + fs.writeFile(packageJSONPath, finalOutput, () => { |
| 127 | + void new eslint.ESLint(eslintConfig) |
| 128 | + .lintFiles([packageJSONPath]) |
| 129 | + .then(lintResults => eslint.ESLint.outputFixes(lintResults)) |
| 130 | + .then(() => |
| 131 | + // eslint-disable-next-line no-console |
| 132 | + console.log(`Done rewriting \`package.json\` for @sentry/${dirName}.`), |
| 133 | + ) |
| 134 | + .catch(err => { |
| 135 | + // eslint-disable-next-line no-console |
| 136 | + console.log(`Error using eslint to format ${packageJSONPath}: ${err}`); |
| 137 | + }); |
| 138 | + }), |
| 139 | + ) |
| 140 | + .catch(err => { |
| 141 | + // eslint-disable-next-line no-console |
| 142 | + console.log(`Error using prettier to format ${packageJSONPath}: ${err}`); |
| 143 | + }); |
| 144 | + }); |
| 145 | +} |
| 146 | + |
| 147 | +async function getGitBranch(): Promise<string> { |
| 148 | + const asyncExec = promisify(exec); |
| 149 | + const { stdout } = await asyncExec('git rev-parse --abbrev-ref HEAD'); |
| 150 | + return stdout.trim(); |
| 151 | +} |
| 152 | + |
| 153 | +void doPatching(); |
0 commit comments