Skip to content

Commit

Permalink
add export gerbers command
Browse files Browse the repository at this point in the history
  • Loading branch information
seveibar committed Apr 10, 2024
1 parent 6e24098 commit 480067d
Show file tree
Hide file tree
Showing 7 changed files with 367 additions and 17 deletions.
Binary file modified bun.lockb
Binary file not shown.
60 changes: 60 additions & 0 deletions lib/cmd-fns/export-gerbers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { AppContext } from "../util/app-context"
import { z } from "zod"
import * as Path from "path"
import { unlink } from "node:fs/promises"
import { soupify } from "lib/soupify"
import * as fs from "fs"
import {
stringifyGerberCommandLayers,
convertSoupToGerberCommands,
} from "@tscircuit/builder"
import { zip } from "zip-a-folder"
import kleur from "kleur"
import archiver from "archiver"

export const exportGerbersCmd = async (ctx: AppContext, args: any) => {
const params = z
.object({
file: z.string(),
export: z.string().optional(),
outputfile: z.string().optional().default("gerbers.zip"),
})
.parse(args)

console.log(kleur.gray("[soupifying]..."))
const soup = await soupify(
{
filePath: params.file,
exportName: params.export,
},
ctx
)

console.log(kleur.gray("[soup to gerber json]..."))
const gerber_layer_cmds = convertSoupToGerberCommands(soup)

console.log(kleur.gray("[stringify gerber json]..."))
const gerber_file_contents = stringifyGerberCommandLayers(gerber_layer_cmds)

console.log(kleur.gray("[writing gerbers to tmp dir]..."))
const tempDir = Path.join(".tscircuit", "tmp-gerber-export")
await fs.mkdirSync(tempDir, { recursive: true })
for (const [fileName, fileContents] of Object.entries(gerber_file_contents)) {
const filePath = Path.join(tempDir, fileName)
await fs.writeFileSync(filePath, fileContents)
}

console.log(kleur.gray("[zipping tmp dir]..."))
const output = fs.createWriteStream(params.outputfile)
const archive = archiver("zip", {
zlib: { level: 9 },
})

archive.pipe(output)
archive.directory(tempDir, false)

await new Promise((resolve, reject) => {
output.on("close", resolve)
output.on("error", reject)
})
}
1 change: 1 addition & 0 deletions lib/cmd-fns/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,4 @@ export { devServerUpload } from "./dev-server-upload"
export { configClear } from "./config-clear"
export { openCmd as open } from "./open"
export { versionCmd as version } from "./version"
export { exportGerbersCmd as exportGerbers } from "./export-gerbers"
15 changes: 15 additions & 0 deletions lib/get-program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,21 @@ export const getProgram = (ctx: AppContext) => {
.description("Clear your local authentication")
.action((args) => CMDFN.authLogout(ctx, args))

const exportCmd = cmd
.command("export")
.description("Export Gerbers, Drill Files, Netlists and more")

exportCmd
.command("gerbers")
.description("Export Gerber files from an example file")
.requiredOption("--file <file>", "Input example files")
.option(
"--export <export_name>",
"Name of export to soupify, if not specified, soupify the default/only export"
)
.option("--outputfile <outputfile>", "Output file name", "gerbers.zip")
.action((args) => CMDFN.exportGerbers(ctx, args))

cmd
.command("soupify")
.description("Convert an example file to tscircuit soup")
Expand Down
22 changes: 22 additions & 0 deletions lib/soupify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import * as Path from "path"
import { unlink } from "node:fs/promises"
import kleur from "kleur"
import { writeFileSync } from "fs"
import { readFile } from "fs/promises"

export const soupify = async (
{
Expand All @@ -16,6 +17,27 @@ export const soupify = async (
},
ctx: { runtime: "node" | "bun" }
) => {
const targetFileContent = await readFile(filePath, "utf-8")

if (!exportName) {
if (targetFileContent.includes("export default")) {
exportName = "default"
} else {
// Look for "export const <name>" or "export function <name>"
const exportRegex = /export\s+(?:const|function)\s+(\w+)/g
const match = exportRegex.exec(targetFileContent)
if (match) {
exportName = match[1]
}
}
}

if (!exportName) {
throw new Error(
`Couldn't derive an export name and didn't find default export in "${filePath}"`
)
}

const tmpFilePath = Path.join(
Path.dirname(filePath),
Path.basename(filePath).replace(/\.[^\.]+$/, "") + ".__tmp_entrypoint.tsx"
Expand Down
Loading

0 comments on commit 480067d

Please sign in to comment.