rewrite in C with libgit2, first version
This commit is contained in:
parent
bda4633633
commit
415e3fdd55
2 changed files with 222 additions and 135 deletions
135
urmoms
135
urmoms
|
@ -1,135 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
# DEBUG
|
||||
#set -e -x
|
||||
|
||||
usage() {
|
||||
printf '%s <repodir> <htmldir>\n' "$0"
|
||||
exit 1
|
||||
}
|
||||
|
||||
header() {
|
||||
cat <<!__EOF__
|
||||
<!DOCTYPE HTML>
|
||||
<html dir="ltr" lang="en">
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<meta http-equiv="Content-Language" content="en" />
|
||||
<title>${name} - ${description}</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css" />
|
||||
</head>
|
||||
<body>
|
||||
<center>
|
||||
<h1><img src="${relpath}logo.png" alt="" /> ${name}</h1>
|
||||
<span class="desc">${description}</span><br/>
|
||||
<a href="${relpath}log.html">Log</a> |
|
||||
<a href="${relpath}files.html">Files</a> |
|
||||
<a href="${relpath}stats.html">Stats</a> |
|
||||
<a href="${relpath}readme.html">README</a> |
|
||||
<a href="${relpath}license.html">LICENSE</a>
|
||||
</center>
|
||||
<hr/>
|
||||
<pre>
|
||||
!__EOF__
|
||||
}
|
||||
|
||||
footer() {
|
||||
cat <<!__EOF__
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
!__EOF__
|
||||
}
|
||||
|
||||
# usage: repodir and htmldir must be set.
|
||||
if test x"$1" = x"" || test x"$2" = x""; then
|
||||
usage
|
||||
fi
|
||||
|
||||
# make absolute path to htmldir.
|
||||
htmldir="$(readlink -f $2)"
|
||||
mkdir -p "${htmldir}"
|
||||
|
||||
# repodir must be a directory to go to.
|
||||
cd "$1" || usage
|
||||
|
||||
# default index page (symlink).
|
||||
indexpage="log.html"
|
||||
|
||||
# project name, if bare repo remove .git suffix.
|
||||
name=$(basename "$(pwd)" ".git")
|
||||
|
||||
# read .git/description.
|
||||
description=""
|
||||
test -f ".git/description" && description="$(cat '.git/description')"
|
||||
|
||||
# make diff for each commit (all files).
|
||||
relpath="../"
|
||||
mkdir -p "${htmldir}/commit"
|
||||
git log --pretty='%H' | while read -r commit; do
|
||||
test -e "${htmldir}/commit/${commit}.html" && continue
|
||||
|
||||
header > "${htmldir}/commit/${commit}.html"
|
||||
git show --pretty=full "${commit}" | \
|
||||
sed -E 's@^commit (.*)$@commit <a href="'${relpath}'commit/\1.html">\1</a>@g' >> "${htmldir}/commit/${commit}.html"
|
||||
footer >> "${htmldir}/commit/${commit}.html"
|
||||
done
|
||||
|
||||
# make log with all commits.
|
||||
relpath=""
|
||||
header > "${htmldir}/log.html"
|
||||
printf '<table border="0">' >> "${htmldir}/log.html"
|
||||
git log --pretty='<tr><td align="right">%cr</td><td><a href="'${relpath}'commit/%H.html">%H</a></td><td>%an</td><td>%s</td></tr>' >> "${htmldir}/log.html"
|
||||
printf '</table>' >> "${htmldir}/log.html"
|
||||
footer >> "${htmldir}/log.html"
|
||||
|
||||
# make index with file links.
|
||||
relpath=""
|
||||
header >> "${htmldir}/files.html"
|
||||
printf '<table><tr><td><b>Mode</b></td><td><b>Name</b></td><td><b>Size</b></td><td></td></tr>' >> "${htmldir}/files.html"
|
||||
git ls-tree -r -l master | while read -r mode type object size file; do
|
||||
git log -1 --pretty='<tr><td>'${mode}'</td><td><a href="'${relpath}'commit/%H.html#file-'${file}'">'${file}'</a></td><td>'${size}'</td><td><a href="file/'${file}'">[plain]</a></td></tr>' "${file}"
|
||||
done >> "${htmldir}/files.html"
|
||||
printf '</table>' >> "${htmldir}/files.html"
|
||||
footer >> "${htmldir}/files.html"
|
||||
|
||||
# readme page
|
||||
# find README file.
|
||||
relpath=""
|
||||
readme=""
|
||||
for f in README README.md readme.md; do
|
||||
test -e "${f}" && readme="${f}"
|
||||
done
|
||||
# make page.
|
||||
header > "${htmldir}/readme.html"
|
||||
if test x"${readme}" != x""; then
|
||||
cat "${readme}" >> "${htmldir}/readme.html"
|
||||
else
|
||||
echo "no README file found" >> "${htmldir}/readme.html"
|
||||
fi
|
||||
footer >> "${htmldir}/readme.html"
|
||||
|
||||
# license page
|
||||
# find LICENSE file.
|
||||
relpath=""
|
||||
license=""
|
||||
for f in LICENSE LICENSE.md; do
|
||||
test -e "${f}" && license="${f}"
|
||||
done
|
||||
# make page.
|
||||
header > "${htmldir}/license.html"
|
||||
if test x"${readme}" != x""; then
|
||||
cat "${license}" >> "${htmldir}/license.html"
|
||||
else
|
||||
echo "unknown license" >> "${htmldir}/license.html"
|
||||
fi
|
||||
footer >> "${htmldir}/license.html"
|
||||
|
||||
# stats (authors).
|
||||
relpath=""
|
||||
header > "${htmldir}/stats.html"
|
||||
git shortlog -n -s >> "${htmldir}/stats.html"
|
||||
footer >> "${htmldir}/stats.html"
|
||||
|
||||
# symlink to index page.
|
||||
ln -sf "$indexpage" "${htmldir}/index.html"
|
222
urmoms.c
Normal file
222
urmoms.c
Normal file
|
@ -0,0 +1,222 @@
|
|||
#include <err.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "git2.h"
|
||||
|
||||
static const char *relpath = "";
|
||||
static const char *name = "";
|
||||
static const char *description = "";
|
||||
|
||||
static const char *repodir = ".";
|
||||
|
||||
static git_repository *repo;
|
||||
|
||||
FILE *
|
||||
efopen(const char *name, const char *flags)
|
||||
{
|
||||
FILE *fp;
|
||||
|
||||
fp = fopen(name, flags);
|
||||
if (!fp)
|
||||
err(1, "fopen");
|
||||
|
||||
return fp;
|
||||
}
|
||||
|
||||
static void
|
||||
printtime(FILE *fp, const git_time * intime, const char *prefix)
|
||||
{
|
||||
struct tm *intm;
|
||||
time_t t;
|
||||
int offset, hours, minutes;
|
||||
char sign, out[32];
|
||||
|
||||
offset = intime->offset;
|
||||
if (offset < 0) {
|
||||
sign = '-';
|
||||
offset = -offset;
|
||||
} else {
|
||||
sign = '+';
|
||||
}
|
||||
|
||||
hours = offset / 60;
|
||||
minutes = offset % 60;
|
||||
|
||||
t = (time_t) intime->time + (intime->offset * 60);
|
||||
|
||||
intm = gmtime(&t);
|
||||
strftime(out, sizeof(out), "%a %b %e %T %Y", intm);
|
||||
|
||||
fprintf(fp, "%s%s %c%02d%02d\n", prefix, out, sign, hours, minutes);
|
||||
}
|
||||
|
||||
static void
|
||||
printcommit(FILE *fp, git_commit * commit)
|
||||
{
|
||||
const git_signature *sig;
|
||||
char buf[GIT_OID_HEXSZ + 1];
|
||||
int i, count;
|
||||
const char *scan, *eol;
|
||||
|
||||
git_oid_tostr(buf, sizeof(buf), git_commit_id(commit));
|
||||
fprintf(fp, "commit <a href=\"commit/%s.html\">%s</a>\n", buf, buf);
|
||||
|
||||
if ((count = (int)git_commit_parentcount(commit)) > 1) {
|
||||
fprintf(fp, "Merge:");
|
||||
for (i = 0; i < count; ++i) {
|
||||
git_oid_tostr(buf, 8, git_commit_parent_id(commit, i));
|
||||
fprintf(fp, " %s", buf);
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
if ((sig = git_commit_author(commit)) != NULL) {
|
||||
fprintf(fp, "Author: <a href=\"author/%s.html\">%s</a> <%s>\n",
|
||||
sig->name, sig->name, sig->email);
|
||||
printtime(fp, &sig->when, "Date: ");
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
|
||||
for (scan = git_commit_message(commit); scan && *scan;) {
|
||||
for (eol = scan; *eol && *eol != '\n'; ++eol) /* find eol */
|
||||
;
|
||||
|
||||
fprintf(fp, " %.*s\n", (int) (eol - scan), scan);
|
||||
scan = *eol ? eol + 1 : NULL;
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
|
||||
int
|
||||
writeheader(FILE *fp)
|
||||
{
|
||||
fprintf(fp, "<!DOCTYPE HTML>"
|
||||
"<html dir=\"ltr\" lang=\"en\"><head>"
|
||||
"<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />"
|
||||
"<meta http-equiv=\"Content-Language\" content=\"en\" />");
|
||||
fprintf(fp, "<title>%s - %s</title>", name, description);
|
||||
fprintf(fp, "<link rel=\"stylesheet\" type=\"text/css\" href=\"style.css\" />"
|
||||
"</head><body><center>");
|
||||
fprintf(fp, "<h1><img src=\"%slogo.png\" alt=\"\" /> %s</h1>", relpath, name);
|
||||
fprintf(fp, "<span class=\"desc\">%s</span><br/>", description);
|
||||
fprintf(fp, "<a href=\"%slog.html\">Log</a> |", relpath);
|
||||
fprintf(fp, "<a href=\"%sfiles.html\">Files</a>| ", relpath);
|
||||
fprintf(fp, "<a href=\"%sstats.html\">Stats</a> | ", relpath);
|
||||
fprintf(fp, "<a href=\"%sreadme.html\">README</a> | ", relpath);
|
||||
fprintf(fp, "<a href=\"%slicense.html\">LICENSE</a>", relpath);
|
||||
fprintf(fp, "</center><hr/><pre>");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
writefooter(FILE *fp)
|
||||
{
|
||||
fprintf(fp, "</pre></body></html>");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
writelog(FILE *fp)
|
||||
{
|
||||
git_revwalk *w = NULL;
|
||||
git_oid id;
|
||||
git_commit *c = NULL;
|
||||
|
||||
git_revwalk_new(&w, repo);
|
||||
git_revwalk_push_head(w);
|
||||
|
||||
while (!git_revwalk_next(&id, w)) {
|
||||
if (git_commit_lookup(&c, repo, &id))
|
||||
return 1;
|
||||
printcommit(fp, c);
|
||||
git_commit_free(c);
|
||||
}
|
||||
git_revwalk_free(w);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
writefiles(FILE *fp)
|
||||
{
|
||||
git_index *index;
|
||||
const git_index_entry *entry;
|
||||
size_t count, i;
|
||||
|
||||
git_repository_index(&index, repo);
|
||||
|
||||
count = git_index_entrycount(index);
|
||||
for (i = 0; i < count; i++) {
|
||||
entry = git_index_get_byindex(index, i);
|
||||
fprintf(fp, "name: %s, size: %lu, mode: %lu\n",
|
||||
entry->path, entry->file_size, entry->mode);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int
|
||||
writebranches(FILE *fp)
|
||||
{
|
||||
git_branch_iterator *branchit = NULL;
|
||||
git_branch_t branchtype;
|
||||
git_reference *branchref;
|
||||
char branchbuf[BUFSIZ] = "";
|
||||
int status;
|
||||
|
||||
git_branch_iterator_new(&branchit, repo, GIT_BRANCH_LOCAL);
|
||||
|
||||
while ((status = git_branch_next(&branchref, &branchtype, branchit)) == GIT_ITEROVER) {
|
||||
git_reference_normalize_name(branchbuf, sizeof(branchbuf), git_reference_name(branchref), GIT_REF_FORMAT_ALLOW_ONELEVEL | GIT_REF_FORMAT_REFSPEC_SHORTHAND);
|
||||
|
||||
/* fprintf(fp, "branch: |%s|\n", branchbuf); */
|
||||
}
|
||||
|
||||
git_branch_iterator_free(branchit);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int status;
|
||||
const git_error *e = NULL;
|
||||
FILE *fp;
|
||||
|
||||
if (argc != 2) {
|
||||
fprintf(stderr, "%s <repodir>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
repodir = argv[1];
|
||||
|
||||
git_libgit2_init();
|
||||
|
||||
if ((status = git_repository_open(&repo, repodir)) < 0) {
|
||||
e = giterr_last();
|
||||
fprintf(stderr, "error %d/%d: %s\n", status, e->klass, e->message);
|
||||
exit(status);
|
||||
}
|
||||
|
||||
fp = efopen("logs.html", "w+b");
|
||||
writeheader(fp);
|
||||
writelog(fp);
|
||||
writefooter(fp);
|
||||
fclose(fp);
|
||||
|
||||
fp = efopen("files.html", "w+b");
|
||||
writeheader(fp);
|
||||
writefiles(fp);
|
||||
writefooter(fp);
|
||||
fclose(fp);
|
||||
|
||||
/* cleanup */
|
||||
git_repository_free(repo);
|
||||
git_libgit2_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in a new issue