diff --git a/cli/README.md b/cli/README.md index a59482844f06..1a08a54db198 100644 --- a/cli/README.md +++ b/cli/README.md @@ -24,3 +24,12 @@ npm i ~/git/cypress/cli/build/cypress-3.1.5.tgz --ignore-scripts ``` Which installs the `tgz` file we have just built from folder `~/git/cypress/cli/build`. + +## Local development + +See [index.js](index.js) for local commands. For example to install local zip file and print debug logs, you could do + +```shell +DEBUG=cypress:cli CYPRESS_INSTALL_BINARY=/tmp/tt/cyp.zip \ + node ./index.js --exec install --force +``` diff --git a/cli/lib/tasks/install.js b/cli/lib/tasks/install.js index 4f7b74922ada..33b777845d85 100644 --- a/cli/lib/tasks/install.js +++ b/cli/lib/tasks/install.js @@ -18,9 +18,9 @@ const { throwFormErrorText, errors } = require('../errors') const alreadyInstalledMsg = () => { if (!util.isPostInstall()) { - logger.log(stripIndent` + logger.log(stripIndent` Skipping installation: - + Pass the ${chalk.yellow('--force')} option if you'd like to reinstall anyway. `) } @@ -258,18 +258,25 @@ const start = (options = {}) => { } // see if version supplied is a path to a binary + debug('checking if file exists "%s" cwd "%s"', needVersion, process.cwd()) + return fs.pathExistsAsync(needVersion) .then((exists) => { if (exists) { + debug('checking extension of %s - it is "%s"', + needVersion, path.extname(needVersion)) + return path.extname(needVersion) === '.zip' ? needVersion : false } const possibleFile = util.formAbsolutePath(needVersion) - debug('checking local file', possibleFile, 'cwd', process.cwd()) + debug('from "%s" formed possible local file "%s" cwd "%s"', + needVersion, possibleFile, process.cwd()) return fs.pathExistsAsync(possibleFile) .then((exists) => { + debug('local file "%s" exists?', possibleFile, exists) // if this exists return the path to it // else false if (exists && path.extname(possibleFile) === '.zip') { @@ -281,9 +288,11 @@ const start = (options = {}) => { }) .then((pathToLocalFile) => { if (pathToLocalFile) { - const absolutePath = path.resolve(needVersion) + debug('forming absolute zip file path from cwd %s and version %s', + process.cwd(), needVersion) + const absolutePath = util.formAbsolutePath(needVersion) - debug('found local file at', absolutePath) + debug('using local zip file at "%s"', absolutePath) debug('skipping download') const rendererOptions = getRendererOptions() diff --git a/cli/lib/util.js b/cli/lib/util.js index 369f29c03175..982181cfda91 100644 --- a/cli/lib/util.js +++ b/cli/lib/util.js @@ -243,10 +243,16 @@ const util = { }) }, - // attention: - // when passing relative path to NPM post install hook, the current working - // directory is set to the `node_modules/cypress` folder - // the user is probably passing relative path with respect to root package folder + /** + * Returns absolute path to a given file IF the filename is specified + * while doing "npm install ..." + * + * **attention:** + * when passing relative path to NPM post install hook, the current working + * directory is set to the `node_modules/cypress` folder. + * the user is probably passing relative path with respect to root package folder, + * that's why we join it with 2 parent folders + */ formAbsolutePath (filename) { if (path.isAbsolute(filename)) { return filename diff --git a/cli/test/lib/tasks/install_spec.js b/cli/test/lib/tasks/install_spec.js index 1a8574f9ba23..b1d999274ab4 100644 --- a/cli/test/lib/tasks/install_spec.js +++ b/cli/test/lib/tasks/install_spec.js @@ -4,6 +4,7 @@ const path = require('path') const chalk = require('chalk') const Promise = require('bluebird') const mockfs = require('mock-fs') +const debug = require('debug')('test') const snapshot = require('../../support/snapshot') const stdout = require('../../support/stdout') @@ -99,7 +100,7 @@ describe('/lib/tasks/install', function () { }) }) - it('can install local binary zip file without download', function () { + it('can install local binary zip file without download (absolute path)', function () { const version = '/tmp/local/file.zip' process.env.CYPRESS_INSTALL_BINARY = version @@ -119,6 +120,15 @@ describe('/lib/tasks/install', function () { it('can install local binary zip file from relative path', function () { const version = './cypress-resources/file.zip' + debug('process.cwd %s', process.cwd()) + + // command "npm install cypress" + // sets the CWD to "node_modules/cypress" during post-install hook + sinon.stub(process, 'cwd').returns('/my/project/path/node_modules/cypress') + // in this case, the expected absolute zip file path will be from the + // project's root, not from the "node_modules/cypress" folder + const zipFilePath = '/my/project/path/cypress-resources/file.zip' + mockfs({ [version]: 'asdf', }) @@ -129,8 +139,9 @@ describe('/lib/tasks/install', function () { return install.start() .then(() => { expect(download.start).not.to.be.called + // expect(unzip.start).to.be.calledWithMatch({ - zipFilePath: path.resolve(version), + zipFilePath, installDir, }) }) diff --git a/scripts/win-appveyor-build.js b/scripts/win-appveyor-build.js index a37b56694368..c837d03aff3e 100755 --- a/scripts/win-appveyor-build.js +++ b/scripts/win-appveyor-build.js @@ -10,7 +10,8 @@ const shell = require('shelljs') const os = require('os') const la = require('lazy-ass') const is = require('check-more-types') -// const assert = require('assert') +const path = require('path') +const terminalBanner = require('terminal-banner').terminalBanner shell.set('-v') // verbose shell.set('-e') // any error is fatal @@ -42,15 +43,23 @@ if (!shouldBuildBinary()) { console.log('building Windows binary') +// package archive filename, something like "cypress-3.3.1.tgz" const filename = `cypress-${process.env.NEXT_DEV_VERSION}.tgz` const version = process.env.NEXT_DEV_VERSION la(is.unemptyString(version), 'missing NEXT_DEV_VERSION') -console.log('building version', version) +terminalBanner(`building version ${version}`) shell.exec(`node scripts/binary.js upload-npm-package --file cli/build/${filename} --version ${version}`) +console.log('CLI build folder') +shell.ls('-l', 'C:\\projects\\cypress\\cli\\build') + +const packageFilename = path.join(process.cwd(), 'cli', 'build', filename) + +console.log('full package filename:', packageFilename) + const arch = os.arch() shell.echo(`Building for win32 [${arch}]...`) @@ -73,22 +82,6 @@ if (result.stdout.includes('nodemon')) { process.exit(1) } -// const pathToExe = 'C:/projects/cypress/build/win32/Cypress/Cypress.exe' - -// // verify that Cypress.exe is either 32bit or 64bit based on node's arch -// const dumpbin = shell.exec(`dumpbin /headers ${pathToExe}`) - -// // eslint-disable-next-line default-case -// switch (arch) { -// case 'ia32': -// assert.ok(dumpbin.stdout.includes('machine (x86)')) -// break - -// case 'x64': -// assert.ok(dumpbin.stdout.includes('machine (x64)')) -// break -// } - /** * Returns true if we are building a pull request */ @@ -103,6 +96,35 @@ if (isPullRequest()) { shell.exec('npm run binary-zip') shell.ls('-l', '*.zip') + + terminalBanner('installing cypress.zip locally') + const zipFile = path.resolve('cypress.zip') + + // hmm, was the cypress-.tgz renamed to just "cypress.tgz" + console.log('CLI build folder') + console.log(shell.ls('-l', 'C:\\projects\\cypress\\cli\\build')) + const renamedPackageFile = path.join(process.cwd(), 'cli', 'build', 'cypress.tgz') + + console.log('zip file', zipFile) + shell.mkdir('test-local-install') + shell.cd('test-local-install') + + // getting error on Windows "Failed to replace env in config: ${APPDATA}" + // so let's try merging the env ourselves + // NOTE: be careful about printing merged environment, because process.env + // includes sensitive variables + const testEnv = { + APPDATA: process.env.APPDATA, + DEBUG: 'cypress:cli', + CYPRESS_INSTALL_BINARY: zipFile, + } + + shell.exec(`npm install ${renamedPackageFile}`, { + env: testEnv, + }) + shell.cd('..') + + terminalBanner('upload zipped binary') shell.exec(`node scripts/binary.js upload-unique-binary --file cypress.zip --version ${version}`) shell.cat('binary-url.json') shell.exec('node scripts/test-other-projects.js --npm npm-package-url.json --binary binary-url.json --provider appVeyor')