From 415e3fdd55b2ecdf2f35680694362a4b35fd1a05 Mon Sep 17 00:00:00 2001 From: Hiltjo Posthuma Date: Sat, 5 Dec 2015 20:22:57 +0100 Subject: [PATCH] rewrite in C with libgit2, first version --- urmoms | 135 --------------------------------------------------------------------------------------------------------------------------------------- urmoms.c | 222 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 222 insertions(+), 135 deletions(-) delete mode 100755 urmoms create mode 100644 urmoms.c diff --git a/urmoms b/urmoms deleted file mode 100755 index 4243687..0000000 --- a/urmoms +++ /dev/null @@ -1,135 +0,0 @@ -#!/bin/sh - -# DEBUG -#set -e -x - -usage() { - printf '%s \n' "$0" - exit 1 -} - -header() { - cat < - - - - -${name} - ${description} - - - -
-

${name}

-${description}
-Log | -Files | -Stats | -README | -LICENSE -
-
-
-!__EOF__
-}
-
-footer() {
-	cat <
-
-
-!__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 \1@g' >> "${htmldir}/commit/${commit}.html"
-	footer >> "${htmldir}/commit/${commit}.html"
-done 
-
-# make log with all commits.
-relpath=""
-header > "${htmldir}/log.html"
-printf '' >> "${htmldir}/log.html"
-git log --pretty='' >> "${htmldir}/log.html"
-printf '
%cr%H%an%s
' >> "${htmldir}/log.html" -footer >> "${htmldir}/log.html" - -# make index with file links. -relpath="" -header >> "${htmldir}/files.html" -printf '' >> "${htmldir}/files.html" -git ls-tree -r -l master | while read -r mode type object size file; do - git log -1 --pretty='' "${file}" -done >> "${htmldir}/files.html" -printf '
ModeNameSize
'${mode}''${file}''${size}'[plain]
' >> "${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" diff --git a/urmoms.c b/urmoms.c new file mode 100644 index 0000000..c0d2ab3 --- /dev/null +++ b/urmoms.c @@ -0,0 +1,222 @@ +#include +#include +#include + +#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 %s\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: %s <%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, "" + "" + "" + ""); + fprintf(fp, "%s - %s", name, description); + fprintf(fp, "" + "
"); + fprintf(fp, "

\"\" %s

", relpath, name); + fprintf(fp, "%s
", description); + fprintf(fp, "Log |", relpath); + fprintf(fp, "Files| ", relpath); + fprintf(fp, "Stats | ", relpath); + fprintf(fp, "README | ", relpath); + fprintf(fp, "LICENSE", relpath); + fprintf(fp, "

");
+
+	return 0;
+}
+
+int
+writefooter(FILE *fp)
+{
+	fprintf(fp, "
"); + + 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 \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; +} -- libgit2 1.1.1