Skip to content

Commit

Permalink
introduce CLI, fix slot issues from experiments w/ jlcpcb
Browse files Browse the repository at this point in the history
  • Loading branch information
seveibar committed Oct 25, 2024
1 parent 4a06ea9 commit 634c016
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 2 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -184,3 +184,5 @@ gerber-output
gerber-output.zip
.aider*
*.diff.png

tmp*
Binary file modified bun.lockb
Binary file not shown.
8 changes: 7 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,26 @@
"main": "dist/index.js",
"type": "module",
"scripts": {
"build": "tsup-node src/index.ts --format esm --dts --sourcemap",
"build": "tsup-node src/index.ts src/cli.ts --format esm --dts --sourcemap",
"format": "biome format --write .",
"format:check": "biome format ."
},
"files": [
"dist"
],
"bin": {
"circuit-to-gerber": "./dist/cli.js"
},
"devDependencies": {
"@biomejs/biome": "^1.8.3",
"@tscircuit/core": "^0.0.131",
"@types/archiver": "^6.0.3",
"@types/bun": "^1.1.8",
"@types/node": "^22.5.2",
"@types/react": "^18.3.12",
"archiver": "^7.0.1",
"bun-match-svg": "^0.0.3",
"commander": "^12.1.0",
"gerber-to-svg": "^4.2.8",
"pcb-stackup": "^4.2.8",
"react": "^18.3.1",
Expand Down
71 changes: 71 additions & 0 deletions src/cli.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#!/usr/bin/env node

import { program } from "commander"
import { readFile, writeFile } from "node:fs/promises"
import { createWriteStream } from "node:fs"
import { resolve, dirname, basename } from "node:path"
import { fileURLToPath } from "node:url"
import archiver from "archiver"
import { convertSoupToGerberCommands, stringifyGerberCommandLayers } from "./"
import { convertSoupToExcellonDrillCommands, stringifyExcellonDrill } from "./"

const __dirname = dirname(fileURLToPath(import.meta.url))

program
.name("circuit-to-gerber")
.description("Convert circuit JSON files to Gerber/Excellon files")
.argument("<input>", "Input circuit JSON file (*.circuit.json)")
.option(
"-o, --output <file>",
"Output ZIP file (defaults to input.gerbers.zip)",
)
.action(async (input, options) => {
try {
// Read and parse input JSON
const circuitJson = JSON.parse(await readFile(input, "utf8"))

// Convert to gerber commands
const gerberCmds = convertSoupToGerberCommands(circuitJson)
const excellonDrillCmds = convertSoupToExcellonDrillCommands({
circuitJson,
is_plated: true,
})
const excellonDrillUnplatedCmds = convertSoupToExcellonDrillCommands({
circuitJson,
is_plated: false,
})

// Stringify all outputs
const gerberOutput = stringifyGerberCommandLayers(gerberCmds)
const excellonDrillOutput = stringifyExcellonDrill(excellonDrillCmds)
const excellonDrillUnplatedOutput = stringifyExcellonDrill(
excellonDrillUnplatedCmds,
)

// Create output ZIP file
const outputPath =
options.output || input.replace(".circuit.json", ".gerbers.zip")
const output = createWriteStream(outputPath)
const archive = archiver("zip", { zlib: { level: 9 } })

archive.pipe(output)

// Add all gerber files to ZIP
for (const [filename, content] of Object.entries(gerberOutput)) {
archive.append(content, { name: `${filename}.gbr` })
}

// Add drill files
archive.append(excellonDrillOutput, { name: "plated.drl" })
archive.append(excellonDrillUnplatedOutput, { name: "unplated.drl" })

await archive.finalize()

console.log(`Created ${outputPath}`)
} catch (err) {
console.error("Error:", (err as Error).message)
process.exit(1)
}
})

program.parse()
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { AnyGerberCommand } from "src/gerber/any_gerber_command"
import { gerberBuilder } from "../gerber-builder"
import packageJson from "package.json"
import packageJson from "../../../package.json"

const layerAndTypeToFileFunction = {
"top-copper": "Copper,L1,Top",
Expand Down

0 comments on commit 634c016

Please sign in to comment.