Skip to content

Instantly share code, notes, and snippets.

@semeleven
Last active March 6, 2024 19:20
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save semeleven/1593142fa9db41e2bcc939fd0c77209b to your computer and use it in GitHub Desktop.
Save semeleven/1593142fa9db41e2bcc939fd0c77209b to your computer and use it in GitHub Desktop.
Хелперы для плохометров
const fs = require("fs");
const path = require("path");
const util = require("util");
const { exec } = require("child_process");
const yargs = require("yargs/yargs");
const { hideBin } = require("yargs/helpers");
const execAsync = util.promisify(exec);
function commonYargs() {
const argv = yargs(hideBin(process.argv))
.check((argv) => {
const filePaths = argv._;
if (filePaths.length !== 2) {
throw new Error("Needs two path - to repo and file for save");
} else {
return true;
}
})
.help().argv;
return {
folder: path.resolve(argv._[0]),
filePath: path.resolve(argv._[1]),
};
}
const oneDay = 1000 * 60 * 60 * 24;
async function analysis({
startFrom = "2021-05-01T00:00:00Z",
filePath,
cb,
folder,
}) {
console.log(`Start ${filePath}`);
if (!fs.existsSync(filePath)) {
console.log(`No history available. Seeding the history now`);
await seedHistory(startFrom);
}
console.log("Getting last result");
addLine(await historicEntry());
async function seedHistory(start) {
let day = +new Date(start);
const end = Date.now() - oneDay;
while (day < end) {
addLine(await historicEntry(day));
day = day + oneDay;
}
}
function addLine(line) {
fs.appendFileSync(filePath, line + "\n", "utf-8");
}
async function historicEntry(timestamp) {
const time = timestamp || Date.now();
let checkoutTo = "master";
let commit = "";
if (timestamp) {
const until = new Date(timestamp).toISOString().split("T")[0];
const commitRaw = await execAsync(
`git rev-list --max-count=1 --first-parent --until="${until}" origin/master`,
{ cwd: folder }
);
checkoutTo = getFromStdout(commitRaw);
commit = checkoutTo;
} else {
const commitRaw = await execAsync(`git log --pretty="%H" -1`, {
cwd: folder,
});
commit = getFromStdout(commitRaw);
}
const result = await cb({
checkoutTo,
commit,
time,
folder,
});
return [time, commit, ...result].join('|');
}
}
function getFromStdout(str) {
return str.stdout.split("\n")[0];
}
module.exports = {
commonYargs,
analysis,
getFromStdout,
};
import {rgPath} from '@vscode/ripgrep';
import {spawn} from 'child_process';
export function ripGrep(cwd, optionsOrSearchTerm) {
const options = optionsOrSearchTerm;
if (!cwd) {
return Promise.reject(new Error('No `cwd` provided'));
}
if (arguments.length === 1) {
return Promise.reject(new Error('No search term provided'));
}
const args = options.args || ['--json'];
if ('regex' in options) {
args.push(`-e ${options.regex}`);
} else if ('string' in options) {
args.push(`-F ${options.string}`);
}
if (options.globs) {
for (const glob of options.globs) {
args.push(`-g '${glob}'`);
}
}
args.push('./');
return new Promise((resolve, reject) => {
const ls = spawn(rgPath, args, {shell: true, cwd});
let raw = '';
ls.stdout.on('data', (data) => {
raw += data;
});
ls.stderr.on('data', (data) => {
console.error(`stderr: ${data}`);
});
ls.on('close', (code) => {
if (code !== 0) {
try {
if (JSON.parse(raw).data.stats.bytes_printed === 0) {
resolve([]);
return;
}
} catch (e) {
reject(e);
}
reject(`code error: ${code}`);
return;
}
try {
if (args.includes('--json')) {
resolve(formatResults(raw));
} else {
resolve(raw);
}
} catch (e) {
reject(e);
}
});
});
}
function formatResults(stdout) {
stdout = stdout.trim();
if (!stdout) {
return [];
}
return stdout
.split('\n')
.map((line) => JSON.parse(line))
.filter((jsonLine) => jsonLine.type === 'match')
.map((jsonLine) => jsonLine.data);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment