Skip to content

Instantly share code, notes, and snippets.

@kwo
Last active June 13, 2024 12:47
Show Gist options
  • Save kwo/bbd251ab1d3392ad95dc889948177a78 to your computer and use it in GitHub Desktop.
Save kwo/bbd251ab1d3392ad95dc889948177a78 to your computer and use it in GitHub Desktop.
#! /usr/bin/env node
const { exec } = require('child_process');
const fs = require('fs');
const doOutput = (z) => {
console.log(z.gitdir, z.status);
};
const doGitPull = (next) => (z) => {
exec('git pull', { cwd: z.gitdir }, (err, stdout, stderr) => {
if (err) {
z.pulled = false;
z.status += ` pull error: ${err}`;
doOutput(z);
return;
}
z.pulled = true;
z.status += ` pulled ${stdout.trim()}`;
next(z);
});
};
const doGitFetch = (next) => (z) => {
exec('git fetch --all --tags --prune --prune-tags --quiet', { cwd: z.gitdir }, (err, stdout, stderr) => {
if (err) {
z.fetched = false;
z.status += ` fetch error: ${err}`;
doOutput(z);
return;
}
z.fetched = true;
z.status += ' fetched';
next(z);
});
};
const doGitBranch = (next) => (z) => {
exec('git branch --show-current', { cwd: z.gitdir }, (err, stdout, stderr) => {
if (err) {
z.status += ` branch error: ${err}`;
doOutput(z);
return;
}
z.branch = stdout.trim();
z.status += ` ${z.branch}`;
next(z);
});
};
const isGitClean = (next) => (z) => {
exec('git status --porcelain', { cwd: z.gitdir }, (err, stdout, stderr) => {
if (err) {
z.status += ` status error: ${err}`;
doOutput(z);
return;
}
if (stdout.trim().length === 0) {
z.clean = true;
z.status += ' clean';
next(z);
} else {
z.clean = false;
z.status += ' dirty';
doOutput(z);
}
});
};
const isGitDir = (next) => (z) => {
const { dirent } = z;
if (dirent.isDirectory()) {
fs.readdir(dirent.name, (err, subdirfiles) => {
if (err) {
z.status += ` subdir error: ${err}`;
doOutput(z);
return;
}
if (subdirfiles.includes('.git')) {
next({gitdir: dirent.name, ...z});
} else {
z.status += ' no .git';
doOutput(z);
}
});
}
};
const readFiles = (next) => (err, files) => {
if (err) {
console.error(`fs.readdir error: ${err}`);
return;
}
files.forEach(f => next({dirent: f, status: ''}));
};
fs.readdir('.', {withFileTypes: true}, readFiles(isGitDir(doGitBranch(doGitFetch(isGitClean(doGitPull(doOutput)))))));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment