99 * repository rule while the file system remains read/write.
1010 */
1111
12- const { spawnSync, spawn } = require ( 'child_process' ) ;
13- const { readdirSync, statSync, writeFileSync, mkdirSync} = require ( 'fs' ) ;
12+ const { spawnSync} = require ( 'child_process' ) ;
13+ const { readdirSync, statSync, writeFileSync, mkdirSync, createWriteStream } = require ( 'fs' ) ;
1414const {
1515 join,
1616 basename,
1717 relative,
1818 dirname,
1919} = require ( 'path' ) ;
20+
2021const nodePath = process . argv [ 1 ] ;
2122const cwd = process . cwd ( ) ;
2223const cypressBin = process . argv [ 2 ] ;
2324
24- // Sandboxing doesn't work on windows, so we can just use the global cypress cache.
25- if ( process . platform === 'win32' ) {
26- installGlobalCypressCache ( ) ;
27- process . exit ( 0 ) ;
28- }
25+ const nodeModulesPath = join ( cypressBin . split ( 'node_modules' ) [ 0 ] , 'node_modules' ) ;
26+ const tar = require ( require . resolve ( 'tar' , {
27+ paths : [
28+ join ( nodeModulesPath , '@bazel' , 'cypress' , 'node_modules' ) ,
29+ nodeModulesPath ,
30+ ]
31+ } ) ) ;
32+
33+ async function main ( ) {
34+ // Sandboxing doesn't work on windows, so we can just use the global cypress cache.
35+ if ( process . platform === 'win32' ) {
36+ installGlobalCypressCache ( ) ;
37+ process . exit ( 0 ) ;
38+ }
2939
30- // Attempt to install the cypress cache within the bazel sandbox and fallback to a global cypress
31- // cache as a last resort.
32- try {
33- installSandboxedCypressCache ( )
34- } catch ( e ) {
35- console . error ( 'ERROR' , e ) ;
36- installGlobalCypressCache ( ) ;
40+ // Attempt to install the cypress cache within the bazel sandbox and fallback to a global cypress
41+ // cache as a last resort.
42+ try {
43+ await installSandboxedCypressCache ( )
44+ } catch ( e ) {
45+ console . error ( 'ERROR' , e ) ;
46+ installGlobalCypressCache ( ) ;
47+ }
3748}
3849
3950function installGlobalCypressCache ( ) {
@@ -70,11 +81,11 @@ cypress_web_test = _cypress_web_test`)
7081}
7182
7283
73- function installSandboxedCypressCache ( ) {
74- mkdirSync ( join ( cwd , 'cypress-cache ' ) )
84+ async function installSandboxedCypressCache ( ) {
85+ mkdirSync ( join ( cwd , 'cypress-install ' ) )
7586
7687 const env = {
77- CYPRESS_CACHE_FOLDER : join ( cwd , 'cypress-cache ' ) ,
88+ CYPRESS_CACHE_FOLDER : join ( cwd , 'cypress-install ' ) ,
7889 PATH : `${ dirname ( nodePath ) } :${ process . env . PATH } ` ,
7990 DEBUG : 'cypress:*'
8091 }
@@ -119,19 +130,24 @@ function installSandboxedCypressCache() {
119130 throw new Error ( `cypress verify failed` ) ;
120131 }
121132
133+ writeFileSync ( join ( env . CYPRESS_CACHE_FOLDER , 'bazel_cypress.json' ) , JSON . stringify ( {
134+ cypressExecutable : relative ( cwd , CYPRESS_RUN_BINARY ) ,
135+ } ) ) ;
136+
122137 const cacheFiles = [ ] ;
123138 walkDir ( env . CYPRESS_CACHE_FOLDER , ( filePath ) => {
124- cacheFiles . push ( filePath ) ;
139+ cacheFiles . push ( relative ( cwd , filePath ) ) ;
125140 } ) ;
126141
142+ const archiveName = 'cypress.archive' ;
143+ await createCypressArchive ( cacheFiles , join ( cwd , archiveName ) ) ;
144+
127145 writeFileSync ( 'index.bzl' , `load(
128146 "//:packages/cypress/internal/cypress_web_test.bzl",
129147 _cypress_web_test = "cypress_web_test",
130148)
131149cypress_web_test = _cypress_web_test` )
132- writeFileSync (
133- 'BUILD.bazel' ,
134- `
150+ writeFileSync ( 'BUILD.bazel' , `
135151package(default_visibility = ["//visibility:public"])
136152
137153exports_files([
@@ -140,62 +156,32 @@ exports_files([
140156])
141157
142158filegroup(
143- name = "cypress_cache",
144- srcs = ${
145- process . platform === 'darwin' ?
146- // On mac we are required to include cache files including spaces. These can only be
147- // included using a glob.
148- 'glob(["cypress-cache/**/*"]),' :
149- // On unix the only no files containing spaces are required to run cypress.
150- ` [
151- ${
152- cacheFiles . filter ( f => ! f . includes ( ' ' ) )
153- . map ( f => `"${ relative ( cwd , f ) } "` )
154- . join ( ',\n ' ) }
155- ]` }
156- )
157-
158- filegroup(
159- name = "cypress_executable",
160- srcs = ["${ relative ( cwd , CYPRESS_RUN_BINARY ) } "]
159+ name = "cypress_archive",
160+ srcs = ["${ relative ( cwd , archiveName ) } "],
161161)
162162` . trim ( ) )
163+ }
163164
165+ function createCypressArchive ( cypressFiles , archiveName ) {
166+ return new Promise ( ( resolve , reject ) => {
167+ const writeStream = createWriteStream ( archiveName ) ;
168+
169+ tar . create (
170+ {
171+ gzip : false ,
172+ portable : true ,
173+ noMtime : true ,
174+ } ,
175+ cypressFiles )
176+ . pipe ( writeStream )
177+ . on ( 'finish' , ( err ) => {
178+ if ( err ) {
179+ return reject ( err ) ;
180+ }
181+
182+ return resolve ( ) ;
183+ } )
184+ } ) ;
185+ }
164186
165- // On mac, the first run of cypress requires write access to the filesystem.
166- if ( process . platform === 'darwin' ) {
167- const http = require ( 'http' ) ;
168- const server = http . createServer ( ( _request , response ) => {
169- response . writeHead ( 200 , { 'Content-Type' : 'text/html' } ) ;
170- response . write ( '<html><body>hello-world</body></html>\n' ) ;
171- response . end ( ) ;
172- } )
173- . listen ( 0 , '127.0.0.1' ) ;
174- server . on ( 'listening' , ( ) => {
175- const baseUrl = `http://127.0.0.1:${ server . address ( ) . port } ` ;
176- writeFileSync (
177- 'cypress.json' , JSON . stringify ( { baseUrl, 'integrationFolder' : cwd , video : false } ) )
178- writeFileSync ( 'spec.js' , `
179- describe('hello', () => {
180- it('should find hello', () => {
181- cy.visit('${ baseUrl } ');
182-
183- cy.contains('hello');
184- });
185- });
186- ` )
187-
188-
189- spawn (
190- `${ cypressBin } ` , [ 'run' , '--config-file=cypress.json' , '--headless' , '--spec=spec.js' ] ,
191- spawnOptions )
192- . on ( 'exit' , ( code ) => {
193- server . close ( ) ;
194-
195- if ( code !== 0 ) {
196- throw new Error ( 'Failed to perform a dry-run of cypress' )
197- }
198- } )
199- } )
200- }
201- }
187+ main ( )
0 commit comments