kisch 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/kisch-cli.js CHANGED
@@ -1,33 +1,139 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  import {program} from "commander";
4
- import Schematic from "./Schematic.js";
4
+ import Schematic, {loadSchematic, createSchematic} from "./Schematic.js";
5
5
  import path from "node:path";
6
+ import pkg from "../package.json" with { type: "json" };
7
+ import {DeclaredError} from "./js-util.js";
8
+ import fs, {promises as fsp} from "fs";
9
+
10
+ /*todo...
11
+
12
+ defines
13
+ wires*/
14
+
15
+ let HELP_TEXT=`
16
+ Examples:
17
+
18
+ Transform existng schema by applying script:
19
+ $ kisch design.sch --script x.js
20
+
21
+ Generate script for later use:
22
+ $ kisch --input fresh.sch --emit x.js
23
+
24
+ Load from one file, apply script, and save in another file:
25
+ $ kisch --input template.sch --script x.js --output out.sch
26
+
27
+ Dry-run, just load schematic and apply script, but don't save:
28
+ $ kisch --input design.sch --script x.js
29
+ `;
6
30
 
7
31
  program
8
- .description("Create or update KiCad schematic based on programmatic description.")
9
- .option("--symbol-library-path <path>","Where to find KiCad symbols.")
10
- .requiredOption("--script <script>","JavaScript file to transform the schematic.")
11
- .argument("<schematic>","KiCad Schematic file.")
32
+ .name("kisch")
33
+ .description(
34
+ "Schematic transformation tool for KiCad.\n\n" +
35
+ "Reads a schematic, applies a JavaScript transformation script,\n" +
36
+ "and writes the resulting schematic."
37
+ )
38
+ .version(pkg.version, "--version", "Show version")
39
+ .argument("[inout.kicad_sch]", "Schematic to be used as input and output.")
40
+
41
+ // Core options
42
+ .option("-i, --input <input.kicad_sch>", "Input schematic.")
43
+ .option("-o, --output <output.kicad_sch>","Output schematic.")
44
+ .option("-L, --symbol-dir <path>","Where to find KiCad symbols.")
45
+ .option("-s, --script <script.js>", "Input script to apply to schematic.")
46
+ .option("-e, --emit <script.js>", "Emit script based on schematic.")
47
+ .option("-q, --quiet", "No output, except for errors.")
48
+ //.option("-v, --verbose", "Print detailed execution info")
49
+ .option(
50
+ "-D, --define <key=value>",
51
+ "Define variable for the script.",
52
+ (value, previous = []) => {
53
+ previous.push(value);
54
+ return previous;
55
+ }
56
+ )
57
+
58
+ // Custom help formatting
59
+ .addHelpText("after",HELP_TEXT);
12
60
 
13
61
  await program.parseAsync();
14
- let options={
15
- ...program.opts(),
16
- schematic: program.args[0],
17
- }
18
62
 
19
- //console.log(options);
63
+ try {
64
+ let options=program.opts();
65
+ if (program.args[0]) {
66
+ if (options.input || options.output)
67
+ throw new DeclaredError("Can't use both positional arg together with -i or -o.");
68
+
69
+ options.input=program.args[0];
70
+ options.output=program.args[0];
71
+ }
20
72
 
21
- let schematic=new Schematic(options.schematic,{
22
- symbolLibraryPath: options.symbolLibraryPath
23
- });
73
+ if (!options.input && !options.output)
74
+ program.help();
24
75
 
25
- await schematic.load();
76
+ if (!options.define)
77
+ options.define=[];
78
+
79
+ if (!options.symbolDir)
80
+ options.symbolDir=
81
+ process.env.KISCH_SYMBOL_DIR ||
82
+ process.env.KICAD9_SYMBOL_DIR ||
83
+ process.env.KICAD_SYMBOL_DIR;
84
+
85
+ let cons=global.console;
86
+ if (options.quiet)
87
+ cons={info: ()=>{}, log: ()=>{}};
88
+
89
+ if (!options.symbolDir)
90
+ throw new DeclaredError("Symbol path missing, pass -L, or set KISCH_SYMBOL_DIR, KICAD9_SYMBOL_DIR or KICAD_SYMBOL_DIR");
91
+
92
+ let schematic;
93
+ if (options.input) {
94
+ cons.info("Loading: "+options.input);
95
+ schematic=await loadSchematic(options.input,{
96
+ symbolLibraryPath: options.symbolDir
97
+ });
98
+ }
99
+
100
+ else {
101
+ cons.info("Starting with empty schematic");
102
+ schematic=await createSchematic({
103
+ symbolLibraryPath: options.symbolDir
104
+ });
105
+ }
106
+
107
+ if (options.script) {
108
+ cons.info("Applying script: "+options.script);
109
+ global.schematic=schematic;
110
+ let defines=Object.fromEntries(options.define.map(e=>
111
+ ([e.slice(0,e.indexOf("=")),e.slice(e.indexOf("=")+1)])
112
+ ));
113
+
114
+ let mod=await import(path.resolve(options.script));
115
+ if (typeof mod.default=="function")
116
+ await mod.default(schematic,defines);
117
+
118
+ schematic.removeUndeclared();
119
+ }
120
+
121
+ if (options.emit) {
122
+ cons.info("Emitting script: "+options.emit);
123
+ await fsp.writeFile(options.emit,schematic.getSource());
124
+ }
125
+
126
+ if (options.output) {
127
+ cons.info("Saving: "+options.output);
128
+ await schematic.save(options.output);
129
+ }
130
+ }
26
131
 
27
- global.schematic=schematic;
28
- let mod=await import(path.resolve(options.script));
29
- if (typeof mod.default=="function")
30
- await mod.default(schematic);
132
+ catch (e) {
133
+ if (e.declared) {
134
+ console.log("Error: "+e.message);
135
+ process.exit(1);
136
+ }
31
137
 
32
- schematic.removeUndeclared();
33
- await schematic.save();
138
+ throw e;
139
+ }
@@ -0,0 +1,17 @@
1
+ import {spawn} from 'node:child_process';
2
+
3
+ export function runCommand(cmd, args = []) {
4
+ return new Promise((resolve, reject) => {
5
+ const child=spawn(cmd,args,{stdio: 'inherit'});
6
+
7
+ child.on('close', (code)=>{
8
+ if (code===0) {
9
+ resolve();
10
+ } else {
11
+ reject(new Error(`Command exited with code ${code}`));
12
+ }
13
+ });
14
+
15
+ child.on('error', reject);
16
+ });
17
+ }
package/lab/kish-test.js DELETED
@@ -1,35 +0,0 @@
1
- import {openSchematic} from "../src/Schematic.js";
2
- import fs, {promises as fsp} from "fs";
3
-
4
- await fsp.rm("lab/kitest",{force: true, recursive: true});
5
- await fsp.cp("lab/kitest-org","lab/kitest",{recursive: true});
6
-
7
- let schematic=await openSchematic("lab/kitest/kitest.kicad_sch",{
8
- symbolLibraryPath: "/home/micke/Repo.ext/kicad-symbols"
9
- });
10
-
11
- await schematic.use(
12
- "Connector_Generic:Conn_01x08"
13
- );
14
-
15
- schematic.sym("J1").pin(1).connect(schematic.sym("J3").pin(2));
16
- schematic.sym("J3").pin(1).connect("GND");
17
- schematic.sym("J1").pin(1).connect(schematic.sym("J3").pin(1));
18
-
19
- let r=schematic.sym("J3").getBoundingRect();
20
-
21
- /*for (let i=4; i<20; i++) {
22
- schematic.declare("J"+i,{
23
- symbol: "Connector_Generic:Conn_01x08",
24
- });
25
- }*/
26
-
27
- schematic.declare("J4",{
28
- symbol: "Connector_Generic:Conn_01x04",
29
- });
30
-
31
- schematic.sym("J4").pin(1).connect("GND");
32
- schematic.sym("J4").pin(4).connect(schematic.sym("J3").pin(3));
33
- schematic.sym("J1").pin(1).connect(schematic.sym("J4").pin(1));
34
-
35
- await schematic.save();
@@ -1,2 +0,0 @@
1
- (kicad_pcb (version 20241229) (generator "pcbnew") (generator_version "9.0")
2
- )
@@ -1,98 +0,0 @@
1
- {
2
- "board": {
3
- "active_layer": 0,
4
- "active_layer_preset": "",
5
- "auto_track_width": true,
6
- "hidden_netclasses": [],
7
- "hidden_nets": [],
8
- "high_contrast_mode": 0,
9
- "net_color_mode": 1,
10
- "opacity": {
11
- "images": 0.6,
12
- "pads": 1.0,
13
- "shapes": 1.0,
14
- "tracks": 1.0,
15
- "vias": 1.0,
16
- "zones": 0.6
17
- },
18
- "selection_filter": {
19
- "dimensions": true,
20
- "footprints": true,
21
- "graphics": true,
22
- "keepouts": true,
23
- "lockedItems": false,
24
- "otherItems": true,
25
- "pads": true,
26
- "text": true,
27
- "tracks": true,
28
- "vias": true,
29
- "zones": true
30
- },
31
- "visible_items": [
32
- "vias",
33
- "footprint_text",
34
- "footprint_anchors",
35
- "ratsnest",
36
- "grid",
37
- "footprints_front",
38
- "footprints_back",
39
- "footprint_values",
40
- "footprint_references",
41
- "tracks",
42
- "drc_errors",
43
- "drawing_sheet",
44
- "bitmaps",
45
- "pads",
46
- "zones",
47
- "drc_warnings",
48
- "drc_exclusions",
49
- "locked_item_shadows",
50
- "conflict_shadows",
51
- "shapes"
52
- ],
53
- "visible_layers": "ffffffff_ffffffff_ffffffff_ffffffff",
54
- "zone_display_mode": 0
55
- },
56
- "git": {
57
- "repo_type": "",
58
- "repo_username": "",
59
- "ssh_key": ""
60
- },
61
- "meta": {
62
- "filename": "kitest.kicad_prl",
63
- "version": 5
64
- },
65
- "net_inspector_panel": {
66
- "col_hidden": [],
67
- "col_order": [],
68
- "col_widths": [],
69
- "custom_group_rules": [],
70
- "expanded_rows": [],
71
- "filter_by_net_name": true,
72
- "filter_by_netclass": true,
73
- "filter_text": "",
74
- "group_by_constraint": false,
75
- "group_by_netclass": false,
76
- "show_unconnected_nets": false,
77
- "show_zero_pad_nets": false,
78
- "sort_ascending": true,
79
- "sorting_column": -1
80
- },
81
- "open_jobsets": [],
82
- "project": {
83
- "files": []
84
- },
85
- "schematic": {
86
- "selection_filter": {
87
- "graphics": true,
88
- "images": true,
89
- "labels": true,
90
- "lockedItems": false,
91
- "otherItems": true,
92
- "pins": true,
93
- "symbols": true,
94
- "text": true,
95
- "wires": true
96
- }
97
- }
98
- }