Skip to content

Instantly share code, notes, and snippets.

@cometkim
Created April 11, 2024 07:04
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 cometkim/9f42cb35fbfb07c64e120ac0933fddec to your computer and use it in GitHub Desktop.
Save cometkim/9f42cb35fbfb07c64e120ac0933fddec to your computer and use it in GitHub Desktop.
Analytics GitHub billing by SKU and repository name
#!/usr/bin/env node
import * as fs from 'node:fs';
import csvParser from 'csv-parser';
const [csvFile, sku] = process.argv.slice(2);
if (!fs.existsSync(csvFile) || !sku) {
console.error('Usage: ./report.mjs [CSV file] [SKU]');
process.exit(1);
}
/**
* @typedef {{ name: string, price: number }} ProjectStats
* @type {Record<ProjectStats['name'], ProjectStats>}
*/
const stats = {};
fs.createReadStream(csvFile)
.pipe(csvParser())
.on('data', row => {
if (row['SKU'] !== sku) {
return;
}
const name = row['Repository Slug'];
const quantity = parseFloat(row['Quantity']);
const unitPrice = parseFloat(row['Price Per Unit ($)']);
const multiplier = parseFloat(row['Multiplier']);
const price = quantity * unitPrice * multiplier;
if (stats[name]) {
stats[name].price += price;
} else {
stats[name] = { name, price };
}
})
.on('end', () => {
const entries = Object.entries(stats);
entries.sort(([a], [b]) => a.localeCompare(b))
console.table(Object.fromEntries(entries));
const totalPrice = entries.reduce((acc, x) => acc + x[1].price, 0);
console.log('Total Price (%s): $%d', sku, totalPrice.toFixed(2));
});
;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment