Created
January 6, 2020 18:24
-
-
Save Yona-Appletree/596899339c2522d38f0e2016f78d1862 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env node | |
const fs = require("fs"); | |
const child_process = require("child_process"); | |
const project = detectProject(process.argv[2] || "."); | |
if (! project) { | |
process.exit(1); | |
} | |
console.info(`Building project${project.name} in ${project.inputDir} to ${project.outputDir}`); | |
fs.mkdirSync(project.outputDir, { recursive: true }); | |
console.info("\tProcessing Files..."); | |
const pathsForZip = []; | |
// Process all files in directory | |
fs.readdirSync(project.inputDir) | |
.forEach(fileName => { | |
if (fileName.match(/pos|bom|\.csv/gi) && !fileName.match(/jlc/gi)) { | |
const contents = fs.readFileSync(project.inputDir + "/" + fileName).toString(); | |
const outputName = fileName.replace(/(\.\w+)$/, ".jlc$1") | |
if (contents.match(/^"Id"/)) { | |
// BOM file | |
console.info(`\t\tConverting BOM File: ${fileName}`); | |
fs.writeFileSync( | |
project.outputDir + "/" + outputName, | |
convertBom(contents) | |
); | |
} | |
else if (contents.match(/^Ref/)) { | |
// POS file | |
console.info(`\t\tConverting POS File: ${fileName}`); | |
fs.writeFileSync( | |
project.outputDir + "/" + outputName, | |
convertPos(contents) | |
); | |
} | |
} | |
else if (fileName.match(/\.(gbr|drl)$/)) { | |
pathsForZip.push(project.inputDir + "/" + fileName); | |
} | |
}); | |
console.info("\tZiping Files..."); | |
pathsForZip.forEach(name => console.info("\t\t" + name)); | |
if (pathsForZip.length < 10) { | |
console.error("ERROR: Fewer than 10 files were found for zipping. Please check that all files are present."); | |
process.exit(1); | |
} | |
child_process.exec(`zip ${project.outputDir}/${project.name}-${project.dateName}.zip ` + pathsForZip.map(name => `"${name}"`).join(" ")); | |
console.info("Done. Opening build directory in Finder."); | |
child_process.exec(`open ${project.outputDir}`); | |
function detectProject(inputDirPath) { | |
// Attempt to detect project name | |
const npthFilename = fs.readdirSync(inputDirPath) | |
.find(it => it.match(/-NPTH.drl$/)) | |
if (! npthFilename) { | |
console.error("Could not find a NPTH.drl file to base project name from."); | |
return null; | |
} | |
const projectName = npthFilename.match(/^(.*)-[\w_]+.drl$/)[1]; | |
const projectDateName = dateString(fs.statSync(inputDirPath + "/" + npthFilename).mtime); | |
const outputDir = inputDirPath + "/build-" + projectDateName; | |
return { | |
name: projectName, | |
dateName: projectDateName, | |
outputDir, | |
inputDir: inputDirPath | |
}; | |
} | |
function convertBom(contents) { | |
return writeMappedSheet( | |
parseSheet(contents, ";"), | |
[ | |
// Output: Input | |
[ "Comment", "Designation" ], | |
[ "Designator", "Designator" ], | |
[ "Footprint", "Package" ], | |
[ "LCSC Part Number", "Supplier and ref" ], | |
] | |
); | |
} | |
function convertPos(contents) { | |
return writeMappedSheet( | |
parseSheet(contents, ","), | |
[ | |
// Output: Input | |
["Designator", "Ref"], | |
["Val", "Val"], | |
["Package", "Package"], | |
["Mid X", "PosX"], | |
["Mid Y", "PosY"], | |
["Rotation", "Rot"], | |
["Layer", "Side"], | |
] | |
); | |
} | |
function writeMappedSheet( | |
rows, | |
colMapping | |
) { | |
let output = colMapping.map(([outputName, inputName]) => '"' + outputName + '"').join(", ") + "\n"; | |
output += rows.map( | |
row => colMapping.map(([outputName, inputName]) => row[inputName]).join(", ") | |
).join("\n"); | |
return output; | |
} | |
function parseSheet( | |
inputFileString, | |
separator | |
) { | |
const rawRos = inputFileString | |
.split("\n") | |
.map(row => row.trim()) | |
.filter(row => row.length > 0) | |
.map(row => row.split(separator)); | |
const headerNames = rawRos[0].map(name => name.replace(/^"*|"*$/g, "")); | |
const rows = rawRos.slice(1).map(rawRow => { | |
const outRow = {}; | |
headerNames.forEach((colName, index) => outRow[colName] = rawRow[index]); | |
return outRow; | |
}); | |
return rows; | |
} | |
function dateString(date) { | |
// Derived from https://stackoverflow.com/questions/17415579/how-to-iso-8601-format-a-date-with-timezone-offset-in-javascript | |
var tzo = -date.getTimezoneOffset(), | |
dif = tzo >= 0 ? '+' : '-', | |
pad = function(num) { | |
var norm = Math.floor(Math.abs(num)); | |
return (norm < 10 ? '0' : '') + norm; | |
}; | |
return date.getFullYear() + | |
'-' + pad(date.getMonth() + 1) + | |
'-' + pad(date.getDate()) + | |
'T' + pad(date.getHours()) + | |
'' + pad(date.getMinutes()) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment