Files
cypress/scripts/binary/util/packages.coffee
Ben Kucera 7857dac907 [internal] use webpack for builds (#4103)
* add webpack

* fix build proccess

* fix reporter build and test

* fix reporter test .css

* use apply(window, ...) since strict mode in webpack

* temp 05/13/19 [skip ci] resolver

* temp 05/14/19 [skip ci] webpack w/ root level symlinks

* run ci

* minor fixes

* fix link-packages script

* hopefully fix mac build

* re-add build-prod script in reporter

* fix typo in link-packages script

* fix lint errors

* fix node-version

* namespace files in webpack

* bust circle ci cache

* bust circle ci cache 2

* remove deps

* bust circle ci cache 3

* bust circle ci cache (launcher)

* ok circleci, you win. I will change all the cache keys

* update snapshot: not sure why added stack lines

* add mocha to reporter devDeps

* separate build file for reporter

* remove unneeded code

* node-sass-globbing use relative imports for appveyor

* add debugging for appveyor failure

* node-sass-globbing force unix paths for windows

* node-sass-globbing force unix paths for windows 2

* node-sass-globbing force unix paths for windows in runner

* run ci

* add checksum to packages caches

* bust circle ci cache (sub packages)

* testing code for appveyor env vars

* fix appveyor env vars for branchname
06-00000026

* fix binary build script, smoke test catch errors, include pkg mains
03-0000000a

* build binary in appveyor for this branch
07-00000047

* fix binary unit test, revert mocha upgrade in root, fix e2e specs
02-00000004

* statically replace symlinks at build time, add test, remove proxy packages code
03-00000002

* oops, update snapshot
04-00000049

* bump circle packages cache
02-00000005

* fix path.win32 on windows, add test for it
00-00000058

* for some reason packages ci cache is not including `rebuild-node-sass` in node_modules/.bin, and npm does not recreate .bin links if a node_modules folder already exists. so Im bumping all the npm caches, again
00-00000003

* emit during webpack-dev-server watch mode
02-00000020

* try revert circle.yml
02-0000002f

* try revert everything
03-0000003b

* Revert "try revert everything"

This reverts commit be125b88ff.

* no circle cache now
02-00000013

* remove logging in reporter build
06-00002a41

* Merge branch develop of github.com:cypress-io/cypress into webpack-runner
02-0000089b

* make build scripts DRY
04-00000a7f

* fix missing fonts, better watch mode
06-00003053

* use webpack --progress in watch mode
00-00000582

* move webpack config files into dedicated package
05-000023bf

* build desktop-gui with webpack, use relative scss url()s
03-00001801

* add timings info, fix configs
07-00005582

* enable sourcemaps "eval", fix desktopgui test
04-00005a08

* try 2: fix desktopgui test
01-0000058e

* fix lint
03-00000b10

* fix snapshot (very minor do not worry)
04-000014a4

* code cleanup
00-00007a4f

* try disable devtool
07-0000a97a

* remove cypress:// devtool sourceURL mapping to prevent cross-domain on electron
00-000056e4

* re-enable eval sourcemap in dev and prod
06-000051e6

* code cleanup
02-000056ae

* refactor node-jsdom setup for tests
00-000041a2

* re-enable sourceURL protocol, enable crossorigin script on runner to appease electron

* smoke tests for static assets in binary build script, disable sourceURL protocol mapping, more consistent dev/prod webpack builds

* use cross-env for desktop-gui

* desktop-dui: expect development NODE_ENV during build script (as has been in past)

* fix build script unit test

* fix build script unit test for real

* fix sourcemaps for dev/prod, add comments, add build static asset tests

* add cross-env to runner devDeps

* fix unit tests for build binary script

* fix whitespace

* add postcss autoprefixer + staticAsset tets

* add eslintrc to scripts/unit

* tabs -> spaces

* tabs -> spaces

* fix binary/util scripts

* fix testStaticAssets in build script

* fix extension requiring node socket

* fix unit-test for binary build script

* fix unit test for runner/reporter

* disable sourcemaps/eval in production

* fix disable sourcemaps in prod code

* resort jsons w/ new lint

* linting fixes

* runner/package.json add back rebuild-node-sass

* no circle cache again

* fix circle.yml

* try appveyor again

* fix binary build: remove "timers" from server/package.json.files

* fix testStaticAssets false-positive sourcemap detection (due to diff package)

* fix 2 failing e2e tests (run in chrome for now)
use build-prod scripts in binary-build script
add build-prod scripts to all packages

* a string is no regex

* correct merge: global_mode_spec

* fix all snapshot screenshot dimensions

* fix all snapshot screenshot dimensions (again)

* fix testStaticAssets development -> production

* Revert "fix all snapshot screenshot dimensions (again)"

This reverts commit d9022ef950.

* Revert "fix all snapshot screenshot dimensions"

This reverts commit 4f7628a051.

* helpers/e2e: only normalize screenshot dimensions NOT on electron

* post-task: windows build don't build on this branch

* post-task: un-bump circleci cache

* post-task: bump circleci cache packages/node_modules to v9

* cleanup: fix eol-newline, remove unneeded eslintrc

* bump circleci cache

* run rebuild-node-sass inside webpack build config

* bump circleci cache

* use cache version from env variable on circle

* use custom command to save cache for most packages

* add custom restore cache command

* restore 2 packages separately

* allow passing package path to restore

* pass explicit path to package to restore

* add restore-caches and save-caches

* print name for restoring cache commands

* print name when storing cache

* print .bin when saving cache

* fix path to .bin

* print launcher .bin

* show .bin for desktop-gui

* print bins

* update npm version

* update npm version - try 2

* update npm version - try 3

* remove circleci debugging print commands

* Revert "remove circleci debugging print commands"

This reverts commit 248966efcd.

* add TERM=xterm to Circle

* Revert "Revert "remove circleci debugging print commands""

This reverts commit cf77273b10.

* Revert "add TERM=xterm to Circle"

This reverts commit dc77c94c57.

* remove --serial arg from run all scripts

* add web-config package to cache

* simplify circleci build job

* circleci: try rmrf node_modules/@packages before install

* appveyor: try removing --serial from install script

* Revert "appveyor: try removing --serial from install script"

This reverts commit 7ef619ff30.

* use appveyor from develop

* use preinstall removing subpackage symlinks
fix webpack config typescript errors
fix path to rebuild-node-sass in packages/web-config
assert replace minimum number of symlink requires

* test binary build [build binary]

* fix transformRequires code [build binary]
2019-07-18 12:11:27 -04:00

240 lines
6.5 KiB
CoffeeScript

_ = require("lodash")
fs = require("fs-extra")
cp = require("child_process")
path = require("path")
glob = require("glob")
Promise = require("bluebird")
retry = require("bluebird-retry")
la = require("lazy-ass")
check = require("check-more-types")
execa = require("execa")
R = require("ramda")
os = require("os")
prettyMs = require("pretty-ms")
pluralize = require('pluralize')
fs = Promise.promisifyAll(fs)
glob = Promise.promisify(glob)
DEFAULT_PATHS = "package.json".split(" ")
pathToPackageJson = (packageFolder) ->
la(check.unemptyString(packageFolder), "expected package path", packageFolder)
path.join(packageFolder, "package.json")
npmRun = (args, cwd, env = {}) ->
command = "npm " + args.join(" ")
console.log(command)
if cwd
console.log("in folder:", cwd)
la(check.maybe.string(cwd), "invalid CWD string", cwd)
execa("npm", args, { stdio: "inherit", cwd, env })
# if everything is ok, resolve with nothing
.then R.always(undefined)
.catch (result) ->
msg = "#{command} failed with exit code: #{result.code}"
throw new Error(msg)
runAllBuildJs = _.partial(npmRun, ["run", "all", "build-js", "--skip-packages", "cli"])
# removes transpiled JS files in the original package folders
runAllCleanJs = _.partial(npmRun, ["run", "all", "clean-js", "--skip-packages", "cli"])
# builds all the packages except for cli
runAllBuild = (args...) ->
getPackagesWithScript('build')
.then (pkgNameArr) ->
pkgs = pkgNameArr.join(' ')
npmRun(
["run", "all", "build-prod", "--", "--serial", "--packages", pkgs, "--skip-packages", "cli"]
args...
)
## @returns string[] with names of packages, e.g. ['runner', 'driver', 'server']
getPackagesWithScript = (scriptName) ->
Promise.resolve(glob('./packages/*/package.json'))
.map (pkgPath) ->
fs.readJsonAsync(pkgPath)
.then (json) ->
if json.scripts?.build
return path.basename(path.dirname(pkgPath))
.filter(Boolean)
copyAllToDist = (distDir) ->
copyRelativePathToDist = (relative) ->
dest = path.join(distDir, relative)
retry ->
console.log(relative, "->", dest)
fs.copyAsync(relative, dest)
copyPackage = (pkg) ->
## copies the package to dist
## including the default paths
## and any specified in package.json files
Promise.resolve(fs.readJsonAsync(pathToPackageJson(pkg)))
.then (json) ->
## grab all the files
## and default included paths
## and convert to relative paths
Promise.resolve(
DEFAULT_PATHS
.concat(json.files or [])
.concat(json.main or [])
.map (file) ->
path.join(pkg, file)
)
.map(copyRelativePathToDist, {concurrency: 1})
## fs-extra concurrency tests (copyPackage / copyRelativePathToDist)
## 1/1 41688
## 1/5 42218
## 1/10 42566
## 2/1 45041
## 2/2 43589
## 3/3 51399
## cp -R concurrency tests
## 1/1 65811
started = new Date()
fs.ensureDirAsync(distDir)
.then ->
glob("./packages/*")
.map(copyPackage, {concurrency: 1})
.then ->
console.log("Finished Copying", new Date() - started)
forceNpmInstall = (packagePath, packageToInstall) ->
console.log("Force installing %s", packageToInstall)
console.log("in %s", packagePath)
la(check.unemptyString(packageToInstall), "missing package to install")
npmRun(["install", "--force", packageToInstall], packagePath)
removeDevDependencies = (packageFolder) ->
packagePath = pathToPackageJson(packageFolder)
console.log("removing devDependencies from %s", packagePath)
fs.readJsonAsync(packagePath)
.then (json) ->
delete json.devDependencies
fs.writeJsonAsync(packagePath, json, {spaces: 2})
retryGlobbing = (pathToPackages, delay = 1000) ->
retryGlob = ->
glob(pathToPackages)
.catch {code: "EMFILE"}, ->
## wait, then retry
Promise
.delay(delay)
.then(retryGlob)
retryGlob()
# installs all packages given a wildcard
# pathToPackages would be something like "C:\projects\cypress\dist\win32\packages\*"
npmInstallAll = (pathToPackages) ->
console.log("npmInstallAll packages in #{pathToPackages}")
started = new Date()
retryNpmInstall = (pkg) ->
console.log("installing %s", pkg)
console.log("NODE_ENV is %s", process.env.NODE_ENV)
# force installing only PRODUCTION dependencies
# https://docs.npmjs.com/cli/install
npmInstall = _.partial(npmRun, ["install", "--only=production", "--quiet"])
npmInstall(pkg, {NODE_ENV: "production"})
.catch {code: "EMFILE"}, ->
Promise
.delay(1000)
.then ->
retryNpmInstall(pkg)
.catch (err) ->
console.log(err, err.code)
throw err
printFolders = (folders) ->
console.log("found %s", pluralize("folder", folders.length, true))
## only installs production dependencies
retryGlobbing(pathToPackages)
.tap(printFolders)
.mapSeries (packageFolder) ->
removeDevDependencies(packageFolder)
.then ->
retryNpmInstall(packageFolder)
.then ->
end = new Date()
console.log("Finished NPM Installing", prettyMs(end - started))
removePackageJson = (filename) ->
if filename.endsWith("/package.json") then path.dirname(filename) else filename
ensureFoundSomething = (files) ->
if files.length == 0
throw new Error("Could not find any files")
files
symlinkType = () ->
if os.platform() == "win32"
"junction"
else
"dir"
symlinkAll = (pathToDistPackages, pathTo) ->
console.log("symlink these packages", pathToDistPackages)
la(check.unemptyString(pathToDistPackages),
"missing paths to dist packages", pathToDistPackages)
baseDir = path.dirname(pathTo())
toBase = path.relative.bind(null, baseDir)
symlink = (pkg) ->
# console.log(pkg, dist)
## strip off the initial './'
## ./packages/foo -> node_modules/@packages/foo
pkg = removePackageJson(pkg)
dest = pathTo("node_modules", "@packages", path.basename(pkg))
relativeDest = path.relative(dest + '/..', pkg)
type = symlinkType()
console.log(relativeDest, "link ->", dest, "type", type)
fs.ensureSymlinkAsync(relativeDest, dest, symlinkType)
.catch((err) ->
if not err.message.includes "EEXIST"
throw err
)
glob(pathToDistPackages)
.then(ensureFoundSomething)
.map(symlink)
module.exports = {
runAllBuild
runAllBuildJs
copyAllToDist
npmInstallAll
symlinkAll
runAllCleanJs
forceNpmInstall
getPackagesWithScript
}
if not module.parent
console.log("demo force install")
forceNpmInstall("packages/server", "@ffmpeg-installer/win32-x64")