Skip to content

Instantly share code, notes, and snippets.

@Yona-Appletree
Created January 6, 2020 18:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Yona-Appletree/596899339c2522d38f0e2016f78d1862 to your computer and use it in GitHub Desktop.
Save Yona-Appletree/596899339c2522d38f0e2016f78d1862 to your computer and use it in GitHub Desktop.
#!/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