diff --git a/src/cli.js b/src/cli.js index 397a5e5..bdaeac0 100755 --- a/src/cli.js +++ b/src/cli.js @@ -98,20 +98,25 @@ let injections = [] try { if (config_file.endsWith('.zip') || config_file.endsWith('.ekb')) { + console.log('Analyzing bundle...'); [config_text, injections] = await io.unpack( - (new jszip()).loadAsync(fs.readFileSync(config_file)) + await (new jszip()).loadAsync(fs.readFileSync(config_file)) ) } else if (fs.statSync(config_file).isDirectory()) { - [config_text, injections] = await io.unpack(zip_from_dir(config_file)) + console.log('Analyzing folder...'); + [config_text, injections] = await io.unpack( + await zip_from_dir(config_file) + ) } else { config_text = fs.readFileSync(config_file).toString() // no injections... } - for (const [type, value] of injections) { - ergogen.inject(type, value) + for (const [type, name, value] of injections) { + ergogen.inject(type, name, value) } } catch (err) { - console.error(`Could not read config file "${config_file}": ${err}`) + console.error(`Could not read config file "${config_file}"!`) + console.error(err) process.exit(2) } diff --git a/src/io.js b/src/io.js index ce42cc4..4b28c1a 100644 --- a/src/io.js +++ b/src/io.js @@ -9,17 +9,22 @@ const kle = require('./kle') exports.unpack = async (zip) => { // main config text (has to be called "config.ext" where ext is one of yaml/json/js) - const config_text = await zip.file(/^config\.(yaml|json|js)$/).async('string') + const candidates = zip.file(/^config\.(yaml|json|js)$/) + if (candidates.length != 1) { + throw new Error('Ambiguous config in bundle!') + } + const config_text = await candidates[0].async('string') const injections = [] // bundled footprints const fps = zip.folder('footprints') const module_prefix = 'const module = {};\n\n' const module_suffix = '\n\nreturn module.exports;' - for (const fp in fps.file(/.*\.js$/)) { - const name = fp.name.split('.')[0] + for (const fp of fps.file(/.*\.js$/)) { + const name = fp.name.slice('footprints/'.length).split('.')[0] const text = await fp.async('string') const parsed = new Function(module_prefix + text + module_suffix)() + // TODO: some sort of footprint validation? injections.push(['footprint', name, parsed]) } diff --git a/test/cli/bad_bundle/command b/test/cli/bad_bundle/command new file mode 100644 index 0000000..28a5b7a --- /dev/null +++ b/test/cli/bad_bundle/command @@ -0,0 +1 @@ +node src/cli.js test/ diff --git a/test/cli/bad_bundle/error b/test/cli/bad_bundle/error new file mode 100644 index 0000000..0b991c8 --- /dev/null +++ b/test/cli/bad_bundle/error @@ -0,0 +1 @@ +Could not read config file "test/"! \ No newline at end of file diff --git a/test/cli/bundle/command b/test/cli/bundle/command new file mode 100644 index 0000000..ac2196e --- /dev/null +++ b/test/cli/bundle/command @@ -0,0 +1 @@ +node src/cli.js test/fixtures/bundle --clean diff --git a/test/cli/bundle/log b/test/cli/bundle/log new file mode 100644 index 0000000..40aaf03 --- /dev/null +++ b/test/cli/bundle/log @@ -0,0 +1,14 @@ +Ergogen CLI + +Analyzing folder... +Interpreting format: YAML +Preprocessing input... +Calculating variables... +Parsing points... +Generating outlines... +Modeling cases... +Scaffolding PCBs... +Cleaning output folder... +Writing output to disk... +Done. + diff --git a/test/cli/bundle/reference/outlines/box.dxf b/test/cli/bundle/reference/outlines/box.dxf new file mode 100644 index 0000000..0d161b6 --- /dev/null +++ b/test/cli/bundle/reference/outlines/box.dxf @@ -0,0 +1,98 @@ +0 +SECTION +2 +HEADER +9 +$INSUNITS +70 +4 +0 +ENDSEC +0 +SECTION +2 +TABLES +0 +TABLE +2 +LTYPE +0 +LTYPE +72 +65 +70 +64 +2 +CONTINUOUS +3 +______ +73 +0 +40 +0 +0 +ENDTAB +0 +TABLE +2 +LAYER +0 +ENDTAB +0 +ENDSEC +0 +SECTION +2 +ENTITIES +0 +LINE +8 +0 +10 +-9 +20 +-9 +11 +9 +21 +-9 +0 +LINE +8 +0 +10 +9 +20 +-9 +11 +9 +21 +9 +0 +LINE +8 +0 +10 +9 +20 +9 +11 +-9 +21 +9 +0 +LINE +8 +0 +10 +-9 +20 +9 +11 +-9 +21 +-9 +0 +ENDSEC +0 +EOF \ No newline at end of file diff --git a/test/cli/bundle/reference/pcbs/pcb.kicad_pcb b/test/cli/bundle/reference/pcbs/pcb.kicad_pcb new file mode 100644 index 0000000..c2ab692 --- /dev/null +++ b/test/cli/bundle/reference/pcbs/pcb.kicad_pcb @@ -0,0 +1,122 @@ + + +(kicad_pcb (version 20171130) (host pcbnew 5.1.6) + + (page A3) + (title_block + (title pcb) + (rev v1.0.0) + (company Unknown) + ) + + (general + (thickness 1.6) + ) + + (layers + (0 F.Cu signal) + (31 B.Cu signal) + (32 B.Adhes user) + (33 F.Adhes user) + (34 B.Paste user) + (35 F.Paste user) + (36 B.SilkS user) + (37 F.SilkS user) + (38 B.Mask user) + (39 F.Mask user) + (40 Dwgs.User user) + (41 Cmts.User user) + (42 Eco1.User user) + (43 Eco2.User user) + (44 Edge.Cuts user) + (45 Margin user) + (46 B.CrtYd user) + (47 F.CrtYd user) + (48 B.Fab user) + (49 F.Fab user) + ) + + (setup + (last_trace_width 0.25) + (trace_clearance 0.2) + (zone_clearance 0.508) + (zone_45_only no) + (trace_min 0.2) + (via_size 0.8) + (via_drill 0.4) + (via_min_size 0.4) + (via_min_drill 0.3) + (uvia_size 0.3) + (uvia_drill 0.1) + (uvias_allowed no) + (uvia_min_size 0.2) + (uvia_min_drill 0.1) + (edge_width 0.05) + (segment_width 0.2) + (pcb_text_width 0.3) + (pcb_text_size 1.5 1.5) + (mod_edge_width 0.12) + (mod_text_size 1 1) + (mod_text_width 0.15) + (pad_size 1.524 1.524) + (pad_drill 0.762) + (pad_to_mask_clearance 0.05) + (aux_axis_origin 0 0) + (visible_elements FFFFFF7F) + (pcbplotparams + (layerselection 0x010fc_ffffffff) + (usegerberextensions false) + (usegerberattributes true) + (usegerberadvancedattributes true) + (creategerberjobfile true) + (excludeedgelayer true) + (linewidth 0.100000) + (plotframeref false) + (viasonmask false) + (mode 1) + (useauxorigin false) + (hpglpennumber 1) + (hpglpenspeed 20) + (hpglpendiameter 15.000000) + (psnegative false) + (psa4output false) + (plotreference true) + (plotvalue true) + (plotinvisibletext false) + (padsonsilk false) + (subtractmaskfromsilk false) + (outputformat 1) + (mirror false) + (drillshape 1) + (scaleselection 1) + (outputdirectory "")) + ) + + (net 0 "") + + (net_class Default "This is the default net class." + (clearance 0.2) + (trace_width 0.25) + (via_dia 0.8) + (via_drill 0.4) + (uvia_dia 0.3) + (uvia_drill 0.1) + (add_net "") + ) + + + (module injected_test_footprint (layer F.Cu) (tedit 5E1ADAC2) + (at 0 0 0) + + + (fp_text reference "I1" (at 0 0) (layer F.SilkS) hide (effects (font (size 1.27 1.27) (thickness 0.15)))) + ) + + (gr_line (start -9 9) (end 9 9) (angle 90) (layer Edge.Cuts) (width 0.15)) +(gr_line (start 9 9) (end 9 -9) (angle 90) (layer Edge.Cuts) (width 0.15)) +(gr_line (start 9 -9) (end -9 -9) (angle 90) (layer Edge.Cuts) (width 0.15)) +(gr_line (start -9 -9) (end -9 9) (angle 90) (layer Edge.Cuts) (width 0.15)) + +) + + \ No newline at end of file diff --git a/test/cli/zip/command b/test/cli/zip/command new file mode 100644 index 0000000..0a7fcd7 --- /dev/null +++ b/test/cli/zip/command @@ -0,0 +1 @@ +node src/cli.js test/fixtures/bundle.zip --clean diff --git a/test/cli/zip/log b/test/cli/zip/log new file mode 100644 index 0000000..17f636b --- /dev/null +++ b/test/cli/zip/log @@ -0,0 +1,14 @@ +Ergogen CLI + +Analyzing bundle... +Interpreting format: YAML +Preprocessing input... +Calculating variables... +Parsing points... +Generating outlines... +Modeling cases... +Scaffolding PCBs... +Cleaning output folder... +Writing output to disk... +Done. + diff --git a/test/cli/zip/reference b/test/cli/zip/reference new file mode 100644 index 0000000..50be577 --- /dev/null +++ b/test/cli/zip/reference @@ -0,0 +1 @@ +../bundle/reference diff --git a/test/fixtures/bundle.zip b/test/fixtures/bundle.zip new file mode 100644 index 0000000..50aeede Binary files /dev/null and b/test/fixtures/bundle.zip differ diff --git a/test/fixtures/bundle/config.yaml b/test/fixtures/bundle/config.yaml new file mode 100644 index 0000000..e264ba3 --- /dev/null +++ b/test/fixtures/bundle/config.yaml @@ -0,0 +1,13 @@ +points.zones.matrix: +outlines: + box: + - what: rectangle + where: true + size: 18 +pcbs: + pcb: + outlines.edge.outline: box + footprints: + injected: + type: injected + anchor: matrix diff --git a/test/fixtures/bundle/footprints/injected.js b/test/fixtures/bundle/footprints/injected.js new file mode 100644 index 0000000..9ef0ad5 --- /dev/null +++ b/test/fixtures/bundle/footprints/injected.js @@ -0,0 +1,13 @@ +module.exports = { + params: { + class: 'I' + }, + body: p => ` + (module injected_test_footprint (layer F.Cu) (tedit 5E1ADAC2) + ${p.at /* parametric position */} + + ${'' /* footprint reference */} + (fp_text reference "${p.ref}" (at 0 0) (layer F.SilkS) ${p.ref_hide} (effects (font (size 1.27 1.27) (thickness 0.15)))) + ) + ` +} \ No newline at end of file diff --git a/test/index.js b/test/index.js index d81f740..9fbf57f 100644 --- a/test/index.js +++ b/test/index.js @@ -94,8 +94,9 @@ if (what) { // --what is the same as above ('cli', or 'cli/prefix') // --dump automatically overrides the old reference -const read = (d, p) => fs.readFileSync(path.join(d, p)).toString() -const exists = (d, p) => fs.existsSync(path.join(d, p)) +const joiner = (a, b) => path.join(a, b) +const read = (...args) => fs.readFileSync(args.reduce(joiner, '')).toString() +const exists = (...args) => fs.existsSync(args.reduce(joiner, '')) const { execSync } = require('child_process') const dircompare = require('dir-compare') @@ -114,22 +115,33 @@ for (let w of cli_what) { fs.removeSync(output_path) const version_regex = /\bv\d+\.\d+\.\d+(\-develop)?\b/ // correct execution - if (exists(t, 'log')) { - const ref_log = read(t, 'log').replace(version_regex, '') + if (!exists(t, 'error')) { + let ref_log = '' + if (exists(t, 'log')) { + ref_log = read(t, 'log').replace(version_regex, '') + } const actual_log = execSync(command).toString().replace(version_regex, '') if (dump) { fs.writeFileSync(path.join(t, 'log'), actual_log) } - const comp_res = dircompare.compareSync(output_path, path.join(t, 'reference'), { + let ref_path = path.join(t, 'reference') + if (!exists(ref_path)) { + fs.mkdirpSync(ref_path) + } + if (fs.statSync(ref_path).isFile()) { + ref_path = path.resolve(path.join(t, read(ref_path).trim())) + } + const comp_res = dircompare.compareSync(output_path, ref_path, { compareContent: true }) if (dump) { - fs.moveSync(output_path, path.join(t, 'reference'), {overwrite: true}) + fs.moveSync(output_path, ref_path, {overwrite: true}) } else { fs.removeSync(output_path) } actual_log.should.equal(ref_log) comp_res.same.should.be.true + // deliberately incorrect execution } else { const ref_error = read(t, 'error') try {