11import path from "path" ;
22import fs from "fs/promises" ;
3- import { existsSync as exists } from "fs" ;
43import assert from "assert" ;
54import ora from "ora" ;
65import { mapper } from "@design-sdk/figma-remote" ;
@@ -20,51 +19,75 @@ import { RemoteImageRepositories } from "@design-sdk/figma-remote/asset-reposito
2019
2120setupCache ( axios ) ;
2221
23- const mkdir = ( path : string ) => ! exists ( path ) && fs . mkdir ( path ) ;
22+ const exists = async ( path : string ) => {
23+ try {
24+ await fs . access ( path ) ;
25+ return true ;
26+ } catch ( e ) {
27+ return false ;
28+ }
29+ } ;
30+
31+ const mkdir = async ( path : string ) =>
32+ ! ( await exists ( path ) ) && ( await fs . mkdir ( path ) ) ;
2433
2534interface ReportConfig {
2635 sample : string ;
2736 outDir ?: string ;
2837 localarchive ?: {
29- file : string ;
30- image : string ;
38+ files : string ;
39+ images : string ;
3140 } ;
3241 skipIfReportExists ?: boolean ;
3342}
3443
3544// disable logging
3645console . log = ( ) => { } ;
37- console . info = ( ) => { } ;
3846console . warn = ( ) => { } ;
3947console . error = ( ) => { } ;
4048
4149async function report ( ) {
50+ console . info ( "Starting report" ) ;
4251 const cwd = process . cwd ( ) ;
4352 // read the config
4453 const config : ReportConfig = require ( path . join ( cwd , "report.config.js" ) ) ;
4554
4655 // load the sample file
47- const samples_path = path . join ( cwd , config . sample ) ;
56+ const samples_path = ( await exists ( config . sample ) )
57+ ? config . sample
58+ : path . join ( cwd , config . sample ) ;
59+
60+ assert (
61+ await exists ( samples_path ) ,
62+ `sample file not found at ${ config . sample } nor ${ samples_path } `
63+ ) ;
64+
4865 const samples = JSON . parse ( await fs . readFile ( samples_path , "utf-8" ) ) ;
4966
5067 // create .coverage folder
5168 const coverage_path = config . outDir ?? path . join ( cwd , ".coverage" ) ;
52- mkdir ( coverage_path ) ;
69+
70+ console . info ( `Loaded ${ samples . length } samples` ) ;
71+ console . info ( `Configuration used - ${ JSON . stringify ( config , null , 2 ) } ` ) ;
72+
73+ await mkdir ( coverage_path ) ;
5374
5475 const client = Client ( {
5576 paths : {
56- file : config . localarchive . file ,
57- image : config . localarchive . image ,
77+ files : config . localarchive . files ,
78+ images : config . localarchive . images ,
5879 } ,
5980 } ) ;
6081
6182 const ssworker = new ScreenshotWorker ( { } ) ;
6283 await ssworker . launch ( ) ;
6384
85+ let i = 0 ;
6486 for ( const c of samples ) {
87+ i ++ ;
6588 // create .coverage/:id folder
6689 const coverage_set_path = path . join ( coverage_path , c . id ) ;
67- mkdir ( coverage_set_path ) ;
90+ await mkdir ( coverage_set_path ) ;
6891
6992 const { id : filekey } = c ;
7093 let file ;
@@ -93,21 +116,26 @@ async function report() {
93116 } )
94117 ) . data . images ;
95118 } catch ( e ) {
96- console . error ( "exports not ready for" , filekey ) ;
119+ console . error ( "exports not ready for" , filekey , e . message ) ;
97120 continue ;
98121 }
99122
123+ let ii = 0 ;
100124 for ( const frame of frames ) {
101- const spinner = ora ( `Running coverage for ${ c . id } /${ frame . id } ` ) . start ( ) ;
125+ ii ++ ;
126+
127+ const spinner = ora (
128+ `[${ i } /${ samples . length } ] Running coverage for ${ c . id } /${ frame . id } (${ ii } /${ frames . length } )`
129+ ) . start ( ) ;
102130
103131 // create .coverage/:id/:node folder
104132 const coverage_node_path = path . join ( coverage_set_path , frame . id ) ;
105- mkdir ( coverage_node_path ) ;
133+ await mkdir ( coverage_node_path ) ;
106134
107135 // report.json
108136 const report_file = path . join ( coverage_node_path , "report.json" ) ;
109137 if ( config . skipIfReportExists ) {
110- if ( exists ( report_file ) ) {
138+ if ( await exists ( report_file ) ) {
111139 spinner . succeed ( `Skipping - report for ${ frame . id } already exists` ) ;
112140 continue ;
113141 }
@@ -134,6 +162,37 @@ async function report() {
134162 ) ;
135163
136164 try {
165+ // image A (original)
166+ const exported = exports [ frame . id ] ;
167+ const image_a_rel = "./a.png" ;
168+ const image_a = path . join ( coverage_node_path , image_a_rel ) ;
169+ // download the exported image with url
170+ // if the exported is local fs path, then use copy instead
171+ if ( await exists ( exported ) ) {
172+ try {
173+ // copy file with symlink
174+ // rempve if already exists before linking new one
175+ if ( await exists ( image_a ) ) {
176+ await fs . unlink ( image_a ) ;
177+ }
178+ await fs . symlink ( exported , image_a ) ;
179+ } catch ( e ) {
180+ // TODO: symlink still fails with "EEXIST: file already exists, symlink"
181+ // we need to handle this.
182+ // reason? - unknown
183+ }
184+ } else if ( exported . startsWith ( "http" ) ) {
185+ const dl = await axios . get ( exported , { responseType : "arraybuffer" } ) ;
186+ await fs . writeFile ( image_a , dl . data ) ;
187+ } else {
188+ throw new Error ( `File not found - ${ exported } ` ) ;
189+ }
190+
191+ if ( ! ( await exists ( image_a ) ) ) {
192+ spinner . fail ( `Image A not found - ${ image_a } ` ) ;
193+ continue ;
194+ }
195+
137196 // codegen
138197 const code = await htmlcss (
139198 {
@@ -165,23 +224,6 @@ async function report() {
165224 const image_b = path . join ( coverage_node_path , image_b_rel ) ;
166225 await fs . writeFile ( image_b , screenshot_buffer ) ;
167226
168- const exported = exports [ frame . id ] ;
169- const image_a_rel = "./a.png" ;
170- const image_a = path . join ( coverage_node_path , image_a_rel ) ;
171- // download the exported image with url
172- // if the exported is local fs path, then use copy instead
173- if ( exists ( exported ) ) {
174- // copy file with symlink
175- // unlink if exists
176- if ( exists ( image_a ) ) {
177- await fs . unlink ( image_a ) ;
178- }
179- await fs . symlink ( exported , image_a ) ;
180- } else {
181- const dl = await axios . get ( exported , { responseType : "arraybuffer" } ) ;
182- await fs . writeFile ( image_a , dl . data ) ;
183- }
184-
185227 const diff = await resemble ( image_a , image_b ) ;
186228 const diff_file = path . join ( coverage_node_path , "diff.png" ) ;
187229 // write diff.png
@@ -224,6 +266,13 @@ async function report() {
224266 spinner . fail ( `error on ${ frame . id } : ${ e . message } ` ) ;
225267 }
226268 }
269+
270+ // cleaup
271+ // if the coverage is empty, remove the folder
272+ const files = await fs . readdir ( coverage_set_path ) ;
273+ if ( files . length === 0 ) {
274+ await fs . rmdir ( coverage_set_path ) ;
275+ }
227276 }
228277
229278 // cleaup
0 commit comments