2008-02-11 22:58:10 +01:00
|
|
|
;; Tekuti
|
2012-02-12 20:48:50 +01:00
|
|
|
;; Copyright (C) 2008, 2010, 2011, 2012 Andy Wingo <wingo at pobox dot com>
|
|
|
|
|
|
|
|
;; This program is free software; you can redistribute it and/or
|
|
|
|
;; modify it under the terms of the GNU General Public License as
|
|
|
|
;; published by the Free Software Foundation; either version 3 of
|
|
|
|
;; the License, or (at your option) any later version.
|
|
|
|
;;
|
|
|
|
;; This program is distributed in the hope that it will be useful,
|
|
|
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
;; GNU General Public License for more details.
|
|
|
|
;;
|
2008-02-11 22:58:10 +01:00
|
|
|
;; You should have received a copy of the GNU General Public License
|
|
|
|
;; along with this program; if not, contact:
|
|
|
|
;;
|
|
|
|
;; Free Software Foundation Voice: +1-617-542-5942
|
|
|
|
;; 59 Temple Place - Suite 330 Fax: +1-617-542-2652
|
|
|
|
;; Boston, MA 02111-1307, USA gnu@gnu.org
|
|
|
|
|
|
|
|
;;; Commentary:
|
|
|
|
;;
|
2008-02-29 00:32:49 +01:00
|
|
|
;; Using git's object database as a persistent store.
|
2008-02-11 22:58:10 +01:00
|
|
|
;;
|
|
|
|
;;; Code:
|
|
|
|
|
|
|
|
(define-module (tekuti git)
|
|
|
|
#:use-module (ice-9 rdelim)
|
|
|
|
#:use-module (ice-9 popen)
|
|
|
|
#:use-module (tekuti util)
|
|
|
|
#:use-module (tekuti config)
|
2010-10-14 12:54:56 +02:00
|
|
|
#:use-module (tekuti match-bind)
|
2010-12-03 19:59:15 +01:00
|
|
|
#:use-module (rnrs bytevectors)
|
2011-02-22 22:21:30 +01:00
|
|
|
#:use-module (ice-9 binary-ports)
|
2008-03-04 23:15:38 +01:00
|
|
|
#:use-module ((srfi srfi-1) #:select (filter-map partition
|
|
|
|
delete-duplicates))
|
2008-02-19 08:58:16 +01:00
|
|
|
#:use-module (srfi srfi-34)
|
|
|
|
#:use-module (srfi srfi-35)
|
|
|
|
#:export (&git-condition git-condition? git-condition-argv
|
|
|
|
git-condition-output git-condition-status false-if-git-error
|
|
|
|
|
|
|
|
git git* ensure-git-repo git-ls-tree git-ls-subdirs
|
2008-02-29 00:32:49 +01:00
|
|
|
git-mktree git-rev-parse git-hash-object git-update-ref
|
comment deletion, post editing.
* tekuti/comment.scm (make-new-comment): Refactor to decouple comment.scm
from post.scm.
* tekuti/git.scm (run): Generalize so it can run any executable.
(git-ls-tree, git-ls-subdirs): Check for a #f treeish, return directly
in that case, avoiding tracebacks in the forked kid.
(git-mktree): Return #f if the tree is empty.
(git-rev-list): New command, something like git log.
(patch-blob): New function; unused, though. Perhaps I should just
delete it.
(git-commit-reverse-operations): New function, constructs munge-tree
operations to revert a commit.
(git-revert): New operator, reverts a commit. Can't use git's revert
because it requires a working tree.
(munge-tree): Rewrite to unify the various commands, and process the
commands in order. Makes a bit more garbage, but is much more
understandable.
* tekuti/page-helpers.scm (post-editing-form): Add a preview.
(admin-post-url): New helper.
(redirect): New helper.
(admin-post-redirect): New helper.
* tekuti/page.scm (page-admin): Show recent changes in the sidebar.
(page-admin-new-post): Redirect to the new post.
(page-new-comment): Rework for make-new-comment changes, and redirect
to the post. Would be nice to redirect to the comment though.
(page-admin-changes): New page, lists recent changes.
(page-admin-change): New page, shows a change, allowing it to be
undone.
(page-admin-revert-change): New page, actually reverts a change. Thus
we have comment deletion.
* tekuti/post.scm (munge-post): New helper, factored out of
make-new-post.
(parse-post-data): Another new helper. Needs to do more validation,
though.
(modify-post): Post editing, yay!
* tekuti/request.scm (parse-www-form-urlencoded): Factored out of
request-form-data.
(*request-initializers*): Initialize 'query to have the parsed query
string data.
* tekuti/url.scm (url:path-part, url:query-part): New somewhat hacky
functions. url.scm needs some love.
(url:path-split): Split on only the "path part" of the URL.
* tekuti/util.scm (foldn): New export. Probably a bad idea.
(match-case): New macro, not used though.
(string-split/trimming): New util.
* tekuti/web.scm (choose-handler): Update the set of pages.
2008-03-07 13:09:47 +01:00
|
|
|
git-commit-tree git-rev-list git-revert
|
2008-02-22 12:57:18 +01:00
|
|
|
|
comment deletion, post editing.
* tekuti/comment.scm (make-new-comment): Refactor to decouple comment.scm
from post.scm.
* tekuti/git.scm (run): Generalize so it can run any executable.
(git-ls-tree, git-ls-subdirs): Check for a #f treeish, return directly
in that case, avoiding tracebacks in the forked kid.
(git-mktree): Return #f if the tree is empty.
(git-rev-list): New command, something like git log.
(patch-blob): New function; unused, though. Perhaps I should just
delete it.
(git-commit-reverse-operations): New function, constructs munge-tree
operations to revert a commit.
(git-revert): New operator, reverts a commit. Can't use git's revert
because it requires a working tree.
(munge-tree): Rewrite to unify the various commands, and process the
commands in order. Makes a bit more garbage, but is much more
understandable.
* tekuti/page-helpers.scm (post-editing-form): Add a preview.
(admin-post-url): New helper.
(redirect): New helper.
(admin-post-redirect): New helper.
* tekuti/page.scm (page-admin): Show recent changes in the sidebar.
(page-admin-new-post): Redirect to the new post.
(page-new-comment): Rework for make-new-comment changes, and redirect
to the post. Would be nice to redirect to the comment though.
(page-admin-changes): New page, lists recent changes.
(page-admin-change): New page, shows a change, allowing it to be
undone.
(page-admin-revert-change): New page, actually reverts a change. Thus
we have comment deletion.
* tekuti/post.scm (munge-post): New helper, factored out of
make-new-post.
(parse-post-data): Another new helper. Needs to do more validation,
though.
(modify-post): Post editing, yay!
* tekuti/request.scm (parse-www-form-urlencoded): Factored out of
request-form-data.
(*request-initializers*): Initialize 'query to have the parsed query
string data.
* tekuti/url.scm (url:path-part, url:query-part): New somewhat hacky
functions. url.scm needs some love.
(url:path-split): Split on only the "path part" of the URL.
* tekuti/util.scm (foldn): New export. Probably a bad idea.
(match-case): New macro, not used though.
(string-split/trimming): New util.
* tekuti/web.scm (choose-handler): Update the set of pages.
2008-03-07 13:09:47 +01:00
|
|
|
munge-tree munge-tree1 parse-commit commit-utc-timestamp
|
2012-02-12 20:48:50 +01:00
|
|
|
|
2008-02-29 00:32:49 +01:00
|
|
|
with-output-to-blob with-input-from-blob))
|
2008-02-28 22:14:42 +01:00
|
|
|
|
2008-02-29 00:32:49 +01:00
|
|
|
|
|
|
|
;;;
|
|
|
|
;;; git conditions
|
|
|
|
;;;
|
2008-02-11 22:58:10 +01:00
|
|
|
|
2008-02-19 08:58:16 +01:00
|
|
|
(define-condition-type &git-condition &condition git-condition?
|
|
|
|
(argv git-condition-argv)
|
|
|
|
(output git-condition-output)
|
|
|
|
(status git-condition-status))
|
|
|
|
|
2009-06-30 18:22:05 +02:00
|
|
|
(define-syntax false-if-git-error
|
|
|
|
(syntax-rules ()
|
|
|
|
((_ body0 body ...)
|
|
|
|
(guard (c ((git-condition? c) #f))
|
|
|
|
body0 body ...))))
|
2008-02-19 08:58:16 +01:00
|
|
|
|
2008-02-29 00:32:49 +01:00
|
|
|
;;;
|
|
|
|
;;; running git
|
2012-02-12 20:48:50 +01:00
|
|
|
;;;
|
2008-02-29 00:32:49 +01:00
|
|
|
|
2008-02-27 21:42:10 +01:00
|
|
|
(define *debug* #f)
|
2008-02-21 23:48:44 +01:00
|
|
|
(define (trc . args)
|
|
|
|
(if *debug*
|
|
|
|
(apply pk args)
|
|
|
|
(car (last-pair args))))
|
|
|
|
|
comment deletion, post editing.
* tekuti/comment.scm (make-new-comment): Refactor to decouple comment.scm
from post.scm.
* tekuti/git.scm (run): Generalize so it can run any executable.
(git-ls-tree, git-ls-subdirs): Check for a #f treeish, return directly
in that case, avoiding tracebacks in the forked kid.
(git-mktree): Return #f if the tree is empty.
(git-rev-list): New command, something like git log.
(patch-blob): New function; unused, though. Perhaps I should just
delete it.
(git-commit-reverse-operations): New function, constructs munge-tree
operations to revert a commit.
(git-revert): New operator, reverts a commit. Can't use git's revert
because it requires a working tree.
(munge-tree): Rewrite to unify the various commands, and process the
commands in order. Makes a bit more garbage, but is much more
understandable.
* tekuti/page-helpers.scm (post-editing-form): Add a preview.
(admin-post-url): New helper.
(redirect): New helper.
(admin-post-redirect): New helper.
* tekuti/page.scm (page-admin): Show recent changes in the sidebar.
(page-admin-new-post): Redirect to the new post.
(page-new-comment): Rework for make-new-comment changes, and redirect
to the post. Would be nice to redirect to the comment though.
(page-admin-changes): New page, lists recent changes.
(page-admin-change): New page, shows a change, allowing it to be
undone.
(page-admin-revert-change): New page, actually reverts a change. Thus
we have comment deletion.
* tekuti/post.scm (munge-post): New helper, factored out of
make-new-post.
(parse-post-data): Another new helper. Needs to do more validation,
though.
(modify-post): Post editing, yay!
* tekuti/request.scm (parse-www-form-urlencoded): Factored out of
request-form-data.
(*request-initializers*): Initialize 'query to have the parsed query
string data.
* tekuti/url.scm (url:path-part, url:query-part): New somewhat hacky
functions. url.scm needs some love.
(url:path-split): Split on only the "path part" of the URL.
* tekuti/util.scm (foldn): New export. Probably a bad idea.
(match-case): New macro, not used though.
(string-split/trimming): New util.
* tekuti/web.scm (choose-handler): Update the set of pages.
2008-03-07 13:09:47 +01:00
|
|
|
(define (run env input-file args)
|
2008-02-19 08:58:16 +01:00
|
|
|
(define (prepend-env args)
|
|
|
|
(if (null? env)
|
|
|
|
args
|
|
|
|
(cons "/usr/bin/env" (append env args))))
|
|
|
|
(define (redirect-input args)
|
|
|
|
(if input-file
|
2008-02-21 23:48:44 +01:00
|
|
|
(list "/bin/sh" "-c"
|
|
|
|
(string-append (string-join (map shell:quote args) " ")
|
|
|
|
"<" input-file))
|
2008-02-19 08:58:16 +01:00
|
|
|
args))
|
comment deletion, post editing.
* tekuti/comment.scm (make-new-comment): Refactor to decouple comment.scm
from post.scm.
* tekuti/git.scm (run): Generalize so it can run any executable.
(git-ls-tree, git-ls-subdirs): Check for a #f treeish, return directly
in that case, avoiding tracebacks in the forked kid.
(git-mktree): Return #f if the tree is empty.
(git-rev-list): New command, something like git log.
(patch-blob): New function; unused, though. Perhaps I should just
delete it.
(git-commit-reverse-operations): New function, constructs munge-tree
operations to revert a commit.
(git-revert): New operator, reverts a commit. Can't use git's revert
because it requires a working tree.
(munge-tree): Rewrite to unify the various commands, and process the
commands in order. Makes a bit more garbage, but is much more
understandable.
* tekuti/page-helpers.scm (post-editing-form): Add a preview.
(admin-post-url): New helper.
(redirect): New helper.
(admin-post-redirect): New helper.
* tekuti/page.scm (page-admin): Show recent changes in the sidebar.
(page-admin-new-post): Redirect to the new post.
(page-new-comment): Rework for make-new-comment changes, and redirect
to the post. Would be nice to redirect to the comment though.
(page-admin-changes): New page, lists recent changes.
(page-admin-change): New page, shows a change, allowing it to be
undone.
(page-admin-revert-change): New page, actually reverts a change. Thus
we have comment deletion.
* tekuti/post.scm (munge-post): New helper, factored out of
make-new-post.
(parse-post-data): Another new helper. Needs to do more validation,
though.
(modify-post): Post editing, yay!
* tekuti/request.scm (parse-www-form-urlencoded): Factored out of
request-form-data.
(*request-initializers*): Initialize 'query to have the parsed query
string data.
* tekuti/url.scm (url:path-part, url:query-part): New somewhat hacky
functions. url.scm needs some love.
(url:path-split): Split on only the "path part" of the URL.
* tekuti/util.scm (foldn): New export. Probably a bad idea.
(match-case): New macro, not used though.
(string-split/trimming): New util.
* tekuti/web.scm (choose-handler): Update the set of pages.
2008-03-07 13:09:47 +01:00
|
|
|
(let* ((real-args (trc (redirect-input (prepend-env args))))
|
2008-02-19 08:58:16 +01:00
|
|
|
(pipe (apply open-pipe* OPEN_READ real-args))
|
2010-12-03 19:59:15 +01:00
|
|
|
(output (begin
|
|
|
|
(let ((bv (get-bytevector-all pipe)))
|
|
|
|
(if (eof-object? bv)
|
|
|
|
""
|
|
|
|
(utf8->string bv)))))
|
2008-02-19 08:58:16 +01:00
|
|
|
(ret (close-pipe pipe)))
|
|
|
|
(case (status:exit-val ret)
|
2010-12-03 19:59:15 +01:00
|
|
|
((0) output)
|
2008-02-27 21:42:10 +01:00
|
|
|
(else (trc 'git-error output ret real-args)
|
|
|
|
(raise (condition (&git-condition
|
2008-02-19 08:58:16 +01:00
|
|
|
(argv real-args)
|
|
|
|
(output output)
|
|
|
|
(status ret))))))))
|
2008-02-11 22:58:10 +01:00
|
|
|
|
2010-10-14 13:04:05 +02:00
|
|
|
(define* (git* args #:key (input #f) (env '()))
|
2008-02-19 08:58:16 +01:00
|
|
|
(if input
|
|
|
|
(call-with-temp-file
|
|
|
|
input
|
|
|
|
(lambda (tempname)
|
2008-02-21 23:48:44 +01:00
|
|
|
(trc input)
|
comment deletion, post editing.
* tekuti/comment.scm (make-new-comment): Refactor to decouple comment.scm
from post.scm.
* tekuti/git.scm (run): Generalize so it can run any executable.
(git-ls-tree, git-ls-subdirs): Check for a #f treeish, return directly
in that case, avoiding tracebacks in the forked kid.
(git-mktree): Return #f if the tree is empty.
(git-rev-list): New command, something like git log.
(patch-blob): New function; unused, though. Perhaps I should just
delete it.
(git-commit-reverse-operations): New function, constructs munge-tree
operations to revert a commit.
(git-revert): New operator, reverts a commit. Can't use git's revert
because it requires a working tree.
(munge-tree): Rewrite to unify the various commands, and process the
commands in order. Makes a bit more garbage, but is much more
understandable.
* tekuti/page-helpers.scm (post-editing-form): Add a preview.
(admin-post-url): New helper.
(redirect): New helper.
(admin-post-redirect): New helper.
* tekuti/page.scm (page-admin): Show recent changes in the sidebar.
(page-admin-new-post): Redirect to the new post.
(page-new-comment): Rework for make-new-comment changes, and redirect
to the post. Would be nice to redirect to the comment though.
(page-admin-changes): New page, lists recent changes.
(page-admin-change): New page, shows a change, allowing it to be
undone.
(page-admin-revert-change): New page, actually reverts a change. Thus
we have comment deletion.
* tekuti/post.scm (munge-post): New helper, factored out of
make-new-post.
(parse-post-data): Another new helper. Needs to do more validation,
though.
(modify-post): Post editing, yay!
* tekuti/request.scm (parse-www-form-urlencoded): Factored out of
request-form-data.
(*request-initializers*): Initialize 'query to have the parsed query
string data.
* tekuti/url.scm (url:path-part, url:query-part): New somewhat hacky
functions. url.scm needs some love.
(url:path-split): Split on only the "path part" of the URL.
* tekuti/util.scm (foldn): New export. Probably a bad idea.
(match-case): New macro, not used though.
(string-split/trimming): New util.
* tekuti/web.scm (choose-handler): Update the set of pages.
2008-03-07 13:09:47 +01:00
|
|
|
(run env tempname (cons* *git* "--bare" args))))
|
|
|
|
(run env #f (cons* *git* "--bare" args))))
|
2008-02-11 22:58:10 +01:00
|
|
|
|
|
|
|
(define (git . args)
|
|
|
|
(git* args))
|
|
|
|
|
2008-02-29 00:32:49 +01:00
|
|
|
;;;
|
|
|
|
;;; git commands
|
2012-02-12 20:48:50 +01:00
|
|
|
;;;
|
2008-02-29 00:32:49 +01:00
|
|
|
|
2008-02-11 22:58:10 +01:00
|
|
|
(define (is-dir? path)
|
|
|
|
(catch 'system-error
|
|
|
|
(lambda () (eq? (stat:type (stat path)) 'directory))
|
|
|
|
(lambda args #f)))
|
|
|
|
|
|
|
|
(define (ensure-git-repo)
|
|
|
|
(let ((d (expanduser *git-dir*)))
|
|
|
|
(if (not (is-dir? d))
|
|
|
|
(begin
|
|
|
|
(mkdir d)
|
|
|
|
(chdir d)
|
2008-04-22 11:29:18 +02:00
|
|
|
(git "init")
|
|
|
|
(git "update-ref" "refs/heads/master"
|
|
|
|
(git-commit-tree (string-trim-both (git* '("mktree") #:input ""))
|
|
|
|
#f "initial commit" #f)))
|
2008-02-11 22:58:10 +01:00
|
|
|
(chdir d))))
|
|
|
|
|
|
|
|
(define (git-ls-tree treeish path)
|
comment deletion, post editing.
* tekuti/comment.scm (make-new-comment): Refactor to decouple comment.scm
from post.scm.
* tekuti/git.scm (run): Generalize so it can run any executable.
(git-ls-tree, git-ls-subdirs): Check for a #f treeish, return directly
in that case, avoiding tracebacks in the forked kid.
(git-mktree): Return #f if the tree is empty.
(git-rev-list): New command, something like git log.
(patch-blob): New function; unused, though. Perhaps I should just
delete it.
(git-commit-reverse-operations): New function, constructs munge-tree
operations to revert a commit.
(git-revert): New operator, reverts a commit. Can't use git's revert
because it requires a working tree.
(munge-tree): Rewrite to unify the various commands, and process the
commands in order. Makes a bit more garbage, but is much more
understandable.
* tekuti/page-helpers.scm (post-editing-form): Add a preview.
(admin-post-url): New helper.
(redirect): New helper.
(admin-post-redirect): New helper.
* tekuti/page.scm (page-admin): Show recent changes in the sidebar.
(page-admin-new-post): Redirect to the new post.
(page-new-comment): Rework for make-new-comment changes, and redirect
to the post. Would be nice to redirect to the comment though.
(page-admin-changes): New page, lists recent changes.
(page-admin-change): New page, shows a change, allowing it to be
undone.
(page-admin-revert-change): New page, actually reverts a change. Thus
we have comment deletion.
* tekuti/post.scm (munge-post): New helper, factored out of
make-new-post.
(parse-post-data): Another new helper. Needs to do more validation,
though.
(modify-post): Post editing, yay!
* tekuti/request.scm (parse-www-form-urlencoded): Factored out of
request-form-data.
(*request-initializers*): Initialize 'query to have the parsed query
string data.
* tekuti/url.scm (url:path-part, url:query-part): New somewhat hacky
functions. url.scm needs some love.
(url:path-split): Split on only the "path part" of the URL.
* tekuti/util.scm (foldn): New export. Probably a bad idea.
(match-case): New macro, not used though.
(string-split/trimming): New util.
* tekuti/web.scm (choose-handler): Update the set of pages.
2008-03-07 13:09:47 +01:00
|
|
|
(or (and treeish
|
|
|
|
(false-if-git-error
|
|
|
|
(match-lines (git "ls-tree" treeish (or path "."))
|
|
|
|
"^(.+) (.+) (.+)\t(.+)$" (_ mode type object name)
|
|
|
|
;; reversed for assoc
|
|
|
|
(list name object (string->symbol type)))))
|
2008-02-23 23:58:55 +01:00
|
|
|
'()))
|
2008-02-11 22:58:10 +01:00
|
|
|
|
|
|
|
(define (git-ls-subdirs treeish path)
|
comment deletion, post editing.
* tekuti/comment.scm (make-new-comment): Refactor to decouple comment.scm
from post.scm.
* tekuti/git.scm (run): Generalize so it can run any executable.
(git-ls-tree, git-ls-subdirs): Check for a #f treeish, return directly
in that case, avoiding tracebacks in the forked kid.
(git-mktree): Return #f if the tree is empty.
(git-rev-list): New command, something like git log.
(patch-blob): New function; unused, though. Perhaps I should just
delete it.
(git-commit-reverse-operations): New function, constructs munge-tree
operations to revert a commit.
(git-revert): New operator, reverts a commit. Can't use git's revert
because it requires a working tree.
(munge-tree): Rewrite to unify the various commands, and process the
commands in order. Makes a bit more garbage, but is much more
understandable.
* tekuti/page-helpers.scm (post-editing-form): Add a preview.
(admin-post-url): New helper.
(redirect): New helper.
(admin-post-redirect): New helper.
* tekuti/page.scm (page-admin): Show recent changes in the sidebar.
(page-admin-new-post): Redirect to the new post.
(page-new-comment): Rework for make-new-comment changes, and redirect
to the post. Would be nice to redirect to the comment though.
(page-admin-changes): New page, lists recent changes.
(page-admin-change): New page, shows a change, allowing it to be
undone.
(page-admin-revert-change): New page, actually reverts a change. Thus
we have comment deletion.
* tekuti/post.scm (munge-post): New helper, factored out of
make-new-post.
(parse-post-data): Another new helper. Needs to do more validation,
though.
(modify-post): Post editing, yay!
* tekuti/request.scm (parse-www-form-urlencoded): Factored out of
request-form-data.
(*request-initializers*): Initialize 'query to have the parsed query
string data.
* tekuti/url.scm (url:path-part, url:query-part): New somewhat hacky
functions. url.scm needs some love.
(url:path-split): Split on only the "path part" of the URL.
* tekuti/util.scm (foldn): New export. Probably a bad idea.
(match-case): New macro, not used though.
(string-split/trimming): New util.
* tekuti/web.scm (choose-handler): Update the set of pages.
2008-03-07 13:09:47 +01:00
|
|
|
(or (and treeish
|
|
|
|
(false-if-git-error
|
|
|
|
(match-lines (git "ls-tree" treeish (or path "."))
|
|
|
|
"^(.+) tree (.+)\t(.+)$" (_ mode object name)
|
|
|
|
(cons name object))))
|
2008-02-22 18:20:41 +01:00
|
|
|
'()))
|
2008-02-11 22:58:10 +01:00
|
|
|
|
2008-02-28 14:28:38 +01:00
|
|
|
(define (git-mktree alist)
|
comment deletion, post editing.
* tekuti/comment.scm (make-new-comment): Refactor to decouple comment.scm
from post.scm.
* tekuti/git.scm (run): Generalize so it can run any executable.
(git-ls-tree, git-ls-subdirs): Check for a #f treeish, return directly
in that case, avoiding tracebacks in the forked kid.
(git-mktree): Return #f if the tree is empty.
(git-rev-list): New command, something like git log.
(patch-blob): New function; unused, though. Perhaps I should just
delete it.
(git-commit-reverse-operations): New function, constructs munge-tree
operations to revert a commit.
(git-revert): New operator, reverts a commit. Can't use git's revert
because it requires a working tree.
(munge-tree): Rewrite to unify the various commands, and process the
commands in order. Makes a bit more garbage, but is much more
understandable.
* tekuti/page-helpers.scm (post-editing-form): Add a preview.
(admin-post-url): New helper.
(redirect): New helper.
(admin-post-redirect): New helper.
* tekuti/page.scm (page-admin): Show recent changes in the sidebar.
(page-admin-new-post): Redirect to the new post.
(page-new-comment): Rework for make-new-comment changes, and redirect
to the post. Would be nice to redirect to the comment though.
(page-admin-changes): New page, lists recent changes.
(page-admin-change): New page, shows a change, allowing it to be
undone.
(page-admin-revert-change): New page, actually reverts a change. Thus
we have comment deletion.
* tekuti/post.scm (munge-post): New helper, factored out of
make-new-post.
(parse-post-data): Another new helper. Needs to do more validation,
though.
(modify-post): Post editing, yay!
* tekuti/request.scm (parse-www-form-urlencoded): Factored out of
request-form-data.
(*request-initializers*): Initialize 'query to have the parsed query
string data.
* tekuti/url.scm (url:path-part, url:query-part): New somewhat hacky
functions. url.scm needs some love.
(url:path-split): Split on only the "path part" of the URL.
* tekuti/util.scm (foldn): New export. Probably a bad idea.
(match-case): New macro, not used though.
(string-split/trimming): New util.
* tekuti/web.scm (choose-handler): Update the set of pages.
2008-03-07 13:09:47 +01:00
|
|
|
(if (null? alist)
|
|
|
|
#f
|
|
|
|
(string-trim-both
|
|
|
|
(git* '("mktree")
|
|
|
|
#:input (string-join
|
|
|
|
(map (lambda (l)
|
|
|
|
(format #f
|
|
|
|
(if (or (null? (cddr l))
|
|
|
|
(equal? (caddr l) 'blob))
|
|
|
|
"100644 blob ~a\t~a"
|
|
|
|
"040000 tree ~a\t~a")
|
|
|
|
(cadr l) (car l)))
|
|
|
|
alist)
|
|
|
|
"\n" 'suffix)))))
|
2008-02-11 22:58:10 +01:00
|
|
|
|
|
|
|
(define (git-rev-parse rev)
|
2012-02-15 22:31:54 +01:00
|
|
|
(or (false-if-exception
|
|
|
|
(let ((s (string-trim-both (call-with-input-file rev read-line))))
|
|
|
|
(and (= (string-length s) 40)
|
|
|
|
s)))
|
2017-03-02 16:28:55 +01:00
|
|
|
(string-trim-both (git "rev-parse" rev))))
|
2008-02-22 12:57:18 +01:00
|
|
|
|
comment deletion, post editing.
* tekuti/comment.scm (make-new-comment): Refactor to decouple comment.scm
from post.scm.
* tekuti/git.scm (run): Generalize so it can run any executable.
(git-ls-tree, git-ls-subdirs): Check for a #f treeish, return directly
in that case, avoiding tracebacks in the forked kid.
(git-mktree): Return #f if the tree is empty.
(git-rev-list): New command, something like git log.
(patch-blob): New function; unused, though. Perhaps I should just
delete it.
(git-commit-reverse-operations): New function, constructs munge-tree
operations to revert a commit.
(git-revert): New operator, reverts a commit. Can't use git's revert
because it requires a working tree.
(munge-tree): Rewrite to unify the various commands, and process the
commands in order. Makes a bit more garbage, but is much more
understandable.
* tekuti/page-helpers.scm (post-editing-form): Add a preview.
(admin-post-url): New helper.
(redirect): New helper.
(admin-post-redirect): New helper.
* tekuti/page.scm (page-admin): Show recent changes in the sidebar.
(page-admin-new-post): Redirect to the new post.
(page-new-comment): Rework for make-new-comment changes, and redirect
to the post. Would be nice to redirect to the comment though.
(page-admin-changes): New page, lists recent changes.
(page-admin-change): New page, shows a change, allowing it to be
undone.
(page-admin-revert-change): New page, actually reverts a change. Thus
we have comment deletion.
* tekuti/post.scm (munge-post): New helper, factored out of
make-new-post.
(parse-post-data): Another new helper. Needs to do more validation,
though.
(modify-post): Post editing, yay!
* tekuti/request.scm (parse-www-form-urlencoded): Factored out of
request-form-data.
(*request-initializers*): Initialize 'query to have the parsed query
string data.
* tekuti/url.scm (url:path-part, url:query-part): New somewhat hacky
functions. url.scm needs some love.
(url:path-split): Split on only the "path part" of the URL.
* tekuti/util.scm (foldn): New export. Probably a bad idea.
(match-case): New macro, not used though.
(string-split/trimming): New util.
* tekuti/web.scm (choose-handler): Update the set of pages.
2008-03-07 13:09:47 +01:00
|
|
|
(define (git-rev-list rev n)
|
|
|
|
(let lp ((lines (string-split
|
|
|
|
(git "rev-list" "--pretty=format:%ct %s"
|
|
|
|
"-n" (number->string n) rev) #\newline))
|
|
|
|
(ret '()))
|
|
|
|
(if (or (null? lines)
|
|
|
|
(and (null? (cdr lines)) (string-null? (car lines))))
|
|
|
|
(reverse ret)
|
|
|
|
(lp (cddr lines)
|
|
|
|
(let ((line1 (car lines)) (line2 (cadr lines)))
|
|
|
|
(match-bind
|
|
|
|
"^commit (.*)$" line1 (_ sha1)
|
|
|
|
(match-bind
|
|
|
|
"^([0-9]+) (.*)$" line2 (_ ts subject)
|
|
|
|
(cons `(,sha1 ,(string->number ts) ,subject) ret)
|
|
|
|
(error "bad line2" line2))
|
|
|
|
(error "bad line1" line1)))))))
|
|
|
|
|
2008-02-28 22:14:42 +01:00
|
|
|
(define (git-hash-object contents)
|
2008-02-22 12:57:18 +01:00
|
|
|
(string-trim-both
|
|
|
|
(git* '("hash-object" "-w" "--stdin") #:input contents)))
|
|
|
|
|
2008-02-27 21:42:10 +01:00
|
|
|
(define (git-update-ref refname proc count)
|
|
|
|
(let* ((ref (git-rev-parse refname))
|
|
|
|
(commit (proc ref)))
|
|
|
|
(cond
|
|
|
|
((zero? count)
|
|
|
|
(error "my god, we looped 5 times" commit))
|
|
|
|
((false-if-git-error
|
|
|
|
(git "update-ref" refname commit ref))
|
|
|
|
commit)
|
|
|
|
(else
|
|
|
|
(pk "failed to update the ref, trying again..." refname)
|
2010-11-13 18:40:05 +01:00
|
|
|
(git-update-ref refname proc (1- count))))))
|
2008-02-27 21:42:10 +01:00
|
|
|
|
2008-02-28 14:28:38 +01:00
|
|
|
(define (git-commit-tree tree parent message timestamp)
|
|
|
|
(string-trim-both
|
|
|
|
(git* (cons* "commit-tree" tree
|
|
|
|
(if parent (list "-p" parent) '()))
|
|
|
|
#:input message
|
|
|
|
#:env (if timestamp
|
|
|
|
(list "GIT_COMMMITTER=tekuti"
|
|
|
|
(format #f "GIT_COMMITTER_DATE=~a +0100" timestamp)
|
2008-02-28 22:14:42 +01:00
|
|
|
(format #f "GIT_AUTHOR_DATE=~a +0100" timestamp))
|
|
|
|
(list "GIT_COMMMITTER=tekuti")))))
|
2008-02-22 12:57:18 +01:00
|
|
|
|
2012-02-12 20:48:50 +01:00
|
|
|
;;;
|
2008-02-29 00:32:49 +01:00
|
|
|
;;; utilities
|
2012-02-12 20:48:50 +01:00
|
|
|
;;;
|
2008-02-29 00:32:49 +01:00
|
|
|
|
comment deletion, post editing.
* tekuti/comment.scm (make-new-comment): Refactor to decouple comment.scm
from post.scm.
* tekuti/git.scm (run): Generalize so it can run any executable.
(git-ls-tree, git-ls-subdirs): Check for a #f treeish, return directly
in that case, avoiding tracebacks in the forked kid.
(git-mktree): Return #f if the tree is empty.
(git-rev-list): New command, something like git log.
(patch-blob): New function; unused, though. Perhaps I should just
delete it.
(git-commit-reverse-operations): New function, constructs munge-tree
operations to revert a commit.
(git-revert): New operator, reverts a commit. Can't use git's revert
because it requires a working tree.
(munge-tree): Rewrite to unify the various commands, and process the
commands in order. Makes a bit more garbage, but is much more
understandable.
* tekuti/page-helpers.scm (post-editing-form): Add a preview.
(admin-post-url): New helper.
(redirect): New helper.
(admin-post-redirect): New helper.
* tekuti/page.scm (page-admin): Show recent changes in the sidebar.
(page-admin-new-post): Redirect to the new post.
(page-new-comment): Rework for make-new-comment changes, and redirect
to the post. Would be nice to redirect to the comment though.
(page-admin-changes): New page, lists recent changes.
(page-admin-change): New page, shows a change, allowing it to be
undone.
(page-admin-revert-change): New page, actually reverts a change. Thus
we have comment deletion.
* tekuti/post.scm (munge-post): New helper, factored out of
make-new-post.
(parse-post-data): Another new helper. Needs to do more validation,
though.
(modify-post): Post editing, yay!
* tekuti/request.scm (parse-www-form-urlencoded): Factored out of
request-form-data.
(*request-initializers*): Initialize 'query to have the parsed query
string data.
* tekuti/url.scm (url:path-part, url:query-part): New somewhat hacky
functions. url.scm needs some love.
(url:path-split): Split on only the "path part" of the URL.
* tekuti/util.scm (foldn): New export. Probably a bad idea.
(match-case): New macro, not used though.
(string-split/trimming): New util.
* tekuti/web.scm (choose-handler): Update the set of pages.
2008-03-07 13:09:47 +01:00
|
|
|
;; unused.
|
|
|
|
(define (patch-blob sha1 patch)
|
|
|
|
(call-with-temp-file
|
|
|
|
(git "cat-file" "blob" sha1)
|
|
|
|
(lambda (orig)
|
|
|
|
(run '() patch (list "patch" "-N" "-s" "-u" "-r" "/dev/null" orig))
|
|
|
|
(with-output-to-blob
|
|
|
|
(display
|
2010-11-13 18:40:05 +01:00
|
|
|
(call-with-input-file orig
|
|
|
|
(lambda (port)
|
|
|
|
(read-delimited "" port))))))))
|
comment deletion, post editing.
* tekuti/comment.scm (make-new-comment): Refactor to decouple comment.scm
from post.scm.
* tekuti/git.scm (run): Generalize so it can run any executable.
(git-ls-tree, git-ls-subdirs): Check for a #f treeish, return directly
in that case, avoiding tracebacks in the forked kid.
(git-mktree): Return #f if the tree is empty.
(git-rev-list): New command, something like git log.
(patch-blob): New function; unused, though. Perhaps I should just
delete it.
(git-commit-reverse-operations): New function, constructs munge-tree
operations to revert a commit.
(git-revert): New operator, reverts a commit. Can't use git's revert
because it requires a working tree.
(munge-tree): Rewrite to unify the various commands, and process the
commands in order. Makes a bit more garbage, but is much more
understandable.
* tekuti/page-helpers.scm (post-editing-form): Add a preview.
(admin-post-url): New helper.
(redirect): New helper.
(admin-post-redirect): New helper.
* tekuti/page.scm (page-admin): Show recent changes in the sidebar.
(page-admin-new-post): Redirect to the new post.
(page-new-comment): Rework for make-new-comment changes, and redirect
to the post. Would be nice to redirect to the comment though.
(page-admin-changes): New page, lists recent changes.
(page-admin-change): New page, shows a change, allowing it to be
undone.
(page-admin-revert-change): New page, actually reverts a change. Thus
we have comment deletion.
* tekuti/post.scm (munge-post): New helper, factored out of
make-new-post.
(parse-post-data): Another new helper. Needs to do more validation,
though.
(modify-post): Post editing, yay!
* tekuti/request.scm (parse-www-form-urlencoded): Factored out of
request-form-data.
(*request-initializers*): Initialize 'query to have the parsed query
string data.
* tekuti/url.scm (url:path-part, url:query-part): New somewhat hacky
functions. url.scm needs some love.
(url:path-split): Split on only the "path part" of the URL.
* tekuti/util.scm (foldn): New export. Probably a bad idea.
(match-case): New macro, not used though.
(string-split/trimming): New util.
* tekuti/web.scm (choose-handler): Update the set of pages.
2008-03-07 13:09:47 +01:00
|
|
|
|
|
|
|
;; could leave stray comments if the post directory changes. but this is
|
|
|
|
;; probably the best that we can do, given that git does not track
|
|
|
|
;; directory renames.
|
|
|
|
(define (git-commit-reverse-operations sha1)
|
2011-04-25 19:10:07 +02:00
|
|
|
(with-input-from-string* (git "diff-tree" "-R" "-r" sha1)
|
comment deletion, post editing.
* tekuti/comment.scm (make-new-comment): Refactor to decouple comment.scm
from post.scm.
* tekuti/git.scm (run): Generalize so it can run any executable.
(git-ls-tree, git-ls-subdirs): Check for a #f treeish, return directly
in that case, avoiding tracebacks in the forked kid.
(git-mktree): Return #f if the tree is empty.
(git-rev-list): New command, something like git log.
(patch-blob): New function; unused, though. Perhaps I should just
delete it.
(git-commit-reverse-operations): New function, constructs munge-tree
operations to revert a commit.
(git-revert): New operator, reverts a commit. Can't use git's revert
because it requires a working tree.
(munge-tree): Rewrite to unify the various commands, and process the
commands in order. Makes a bit more garbage, but is much more
understandable.
* tekuti/page-helpers.scm (post-editing-form): Add a preview.
(admin-post-url): New helper.
(redirect): New helper.
(admin-post-redirect): New helper.
* tekuti/page.scm (page-admin): Show recent changes in the sidebar.
(page-admin-new-post): Redirect to the new post.
(page-new-comment): Rework for make-new-comment changes, and redirect
to the post. Would be nice to redirect to the comment though.
(page-admin-changes): New page, lists recent changes.
(page-admin-change): New page, shows a change, allowing it to be
undone.
(page-admin-revert-change): New page, actually reverts a change. Thus
we have comment deletion.
* tekuti/post.scm (munge-post): New helper, factored out of
make-new-post.
(parse-post-data): Another new helper. Needs to do more validation,
though.
(modify-post): Post editing, yay!
* tekuti/request.scm (parse-www-form-urlencoded): Factored out of
request-form-data.
(*request-initializers*): Initialize 'query to have the parsed query
string data.
* tekuti/url.scm (url:path-part, url:query-part): New somewhat hacky
functions. url.scm needs some love.
(url:path-split): Split on only the "path part" of the URL.
* tekuti/util.scm (foldn): New export. Probably a bad idea.
(match-case): New macro, not used though.
(string-split/trimming): New util.
* tekuti/web.scm (choose-handler): Update the set of pages.
2008-03-07 13:09:47 +01:00
|
|
|
(lambda ()
|
|
|
|
(read-line) ;; throw away the header
|
|
|
|
(let lp ((ops '()))
|
|
|
|
(let ((line (read-line)))
|
|
|
|
(if (eof-object? line)
|
|
|
|
ops
|
|
|
|
(match-bind
|
|
|
|
"^:([0-9]+) ([0-9]+) ([0-9a-f]+) ([0-9a-f]+) (.)\t(.*)$"
|
|
|
|
line (_ mode1 mode2 ob1 ob2 op path)
|
|
|
|
(let ((head (let ((d (dirname path)))
|
|
|
|
(if (string=? d ".") '()
|
|
|
|
(string-split d #\/))))
|
|
|
|
(tail (basename path)))
|
|
|
|
(lp
|
|
|
|
(case (string-ref op 0)
|
|
|
|
((#\D) (cons `(delete ,head (,tail))
|
|
|
|
ops))
|
|
|
|
((#\A) (cons `(create ,head (,tail ,ob2 blob))
|
|
|
|
ops))
|
|
|
|
((#\M) (cons* `(delete ,head (,tail))
|
|
|
|
`(create ,head (,tail ,ob2 blob))
|
|
|
|
ops)))))
|
|
|
|
(error "crack line" line))))))))
|
|
|
|
|
|
|
|
(define (git-revert ref sha1)
|
|
|
|
(let ((ops (git-commit-reverse-operations sha1)))
|
|
|
|
(git-update-ref ref
|
|
|
|
(lambda (master)
|
|
|
|
(git-commit-tree (munge-tree master ops)
|
|
|
|
master "revert change" #f))
|
|
|
|
5)))
|
|
|
|
|
|
|
|
(define (munge-tree1-local dents command arg)
|
|
|
|
(define (command-error why)
|
|
|
|
(error "munge-tree1-local error" why command arg))
|
|
|
|
(let ((dent (assoc (car arg) dents)))
|
2008-02-29 00:32:49 +01:00
|
|
|
(git-mktree
|
comment deletion, post editing.
* tekuti/comment.scm (make-new-comment): Refactor to decouple comment.scm
from post.scm.
* tekuti/git.scm (run): Generalize so it can run any executable.
(git-ls-tree, git-ls-subdirs): Check for a #f treeish, return directly
in that case, avoiding tracebacks in the forked kid.
(git-mktree): Return #f if the tree is empty.
(git-rev-list): New command, something like git log.
(patch-blob): New function; unused, though. Perhaps I should just
delete it.
(git-commit-reverse-operations): New function, constructs munge-tree
operations to revert a commit.
(git-revert): New operator, reverts a commit. Can't use git's revert
because it requires a working tree.
(munge-tree): Rewrite to unify the various commands, and process the
commands in order. Makes a bit more garbage, but is much more
understandable.
* tekuti/page-helpers.scm (post-editing-form): Add a preview.
(admin-post-url): New helper.
(redirect): New helper.
(admin-post-redirect): New helper.
* tekuti/page.scm (page-admin): Show recent changes in the sidebar.
(page-admin-new-post): Redirect to the new post.
(page-new-comment): Rework for make-new-comment changes, and redirect
to the post. Would be nice to redirect to the comment though.
(page-admin-changes): New page, lists recent changes.
(page-admin-change): New page, shows a change, allowing it to be
undone.
(page-admin-revert-change): New page, actually reverts a change. Thus
we have comment deletion.
* tekuti/post.scm (munge-post): New helper, factored out of
make-new-post.
(parse-post-data): Another new helper. Needs to do more validation,
though.
(modify-post): Post editing, yay!
* tekuti/request.scm (parse-www-form-urlencoded): Factored out of
request-form-data.
(*request-initializers*): Initialize 'query to have the parsed query
string data.
* tekuti/url.scm (url:path-part, url:query-part): New somewhat hacky
functions. url.scm needs some love.
(url:path-split): Split on only the "path part" of the URL.
* tekuti/util.scm (foldn): New export. Probably a bad idea.
(match-case): New macro, not used though.
(string-split/trimming): New util.
* tekuti/web.scm (choose-handler): Update the set of pages.
2008-03-07 13:09:47 +01:00
|
|
|
(case command
|
|
|
|
((create) (if dent
|
|
|
|
(command-error 'file-present)
|
|
|
|
(cons arg dents)))
|
|
|
|
((delete) (if dent
|
|
|
|
(delq dent dents)
|
|
|
|
(command-error 'file-not-present)))
|
|
|
|
((rename) (if dent
|
|
|
|
(acons (cadr arg) (cdr dent) (delq dent dents))
|
|
|
|
(command-error 'file-not-present)))
|
|
|
|
(else (command-error 'unrecognized))))))
|
|
|
|
|
|
|
|
(define (munge-tree1-recursive dents command ldir rdir arg)
|
|
|
|
(define (command-error why)
|
2010-11-13 18:40:05 +01:00
|
|
|
(error "munge-tree1-recursive error" why command ldir rdir arg))
|
comment deletion, post editing.
* tekuti/comment.scm (make-new-comment): Refactor to decouple comment.scm
from post.scm.
* tekuti/git.scm (run): Generalize so it can run any executable.
(git-ls-tree, git-ls-subdirs): Check for a #f treeish, return directly
in that case, avoiding tracebacks in the forked kid.
(git-mktree): Return #f if the tree is empty.
(git-rev-list): New command, something like git log.
(patch-blob): New function; unused, though. Perhaps I should just
delete it.
(git-commit-reverse-operations): New function, constructs munge-tree
operations to revert a commit.
(git-revert): New operator, reverts a commit. Can't use git's revert
because it requires a working tree.
(munge-tree): Rewrite to unify the various commands, and process the
commands in order. Makes a bit more garbage, but is much more
understandable.
* tekuti/page-helpers.scm (post-editing-form): Add a preview.
(admin-post-url): New helper.
(redirect): New helper.
(admin-post-redirect): New helper.
* tekuti/page.scm (page-admin): Show recent changes in the sidebar.
(page-admin-new-post): Redirect to the new post.
(page-new-comment): Rework for make-new-comment changes, and redirect
to the post. Would be nice to redirect to the comment though.
(page-admin-changes): New page, lists recent changes.
(page-admin-change): New page, shows a change, allowing it to be
undone.
(page-admin-revert-change): New page, actually reverts a change. Thus
we have comment deletion.
* tekuti/post.scm (munge-post): New helper, factored out of
make-new-post.
(parse-post-data): Another new helper. Needs to do more validation,
though.
(modify-post): Post editing, yay!
* tekuti/request.scm (parse-www-form-urlencoded): Factored out of
request-form-data.
(*request-initializers*): Initialize 'query to have the parsed query
string data.
* tekuti/url.scm (url:path-part, url:query-part): New somewhat hacky
functions. url.scm needs some love.
(url:path-split): Split on only the "path part" of the URL.
* tekuti/util.scm (foldn): New export. Probably a bad idea.
(match-case): New macro, not used though.
(string-split/trimming): New util.
* tekuti/web.scm (choose-handler): Update the set of pages.
2008-03-07 13:09:47 +01:00
|
|
|
(let ((dent (assoc ldir dents)))
|
|
|
|
(if (and dent (not (eq? (caddr dent) 'tree)))
|
|
|
|
(command-error 'not-a-tree))
|
|
|
|
(let ((subtree (and=> dent cadr))
|
|
|
|
(other-dents (if dent (delq dent dents) dents)))
|
|
|
|
(let ((new (case command
|
|
|
|
((create)
|
|
|
|
(munge-tree1 subtree command rdir arg))
|
|
|
|
((delete rename)
|
|
|
|
(if subtree
|
|
|
|
(munge-tree1 subtree command rdir arg)
|
|
|
|
(command-error 'file-not-present)))
|
|
|
|
(else (command-error 'unrecognized)))))
|
|
|
|
(git-mktree (if new
|
|
|
|
(cons (list ldir new 'tree) other-dents)
|
|
|
|
other-dents))))))
|
|
|
|
|
|
|
|
(define (munge-tree1 treeish command dir arg)
|
|
|
|
(let ((dents (git-ls-tree treeish #f)))
|
|
|
|
(if (null? dir)
|
|
|
|
(munge-tree1-local dents command arg)
|
|
|
|
(munge-tree1-recursive dents command (car dir) (cdr dir) arg))))
|
|
|
|
|
|
|
|
;; (munge-tree sha1 ((create (key comments) (name sha1 blob))
|
|
|
|
;; (delete (foo bar) (name))
|
|
|
|
;; (rename (baz borky) (from to))))
|
|
|
|
(define (munge-tree treeish operations)
|
|
|
|
(if (null? operations)
|
|
|
|
treeish
|
|
|
|
(let ((op (car operations)))
|
|
|
|
(munge-tree (munge-tree1 treeish (car op) (cadr op) (caddr op))
|
|
|
|
(cdr operations)))))
|
|
|
|
|
2008-02-29 00:32:49 +01:00
|
|
|
(define (parse-commit commit)
|
|
|
|
(let ((text (git "cat-file" "commit" commit)))
|
|
|
|
(match-bind
|
|
|
|
"\n\n(.*)$" text (_ message)
|
|
|
|
(acons
|
|
|
|
'message message
|
|
|
|
(match-lines (substring text 0 (- (string-length text) (string-length _)))
|
|
|
|
"^([^ ]+) (.*)$" (_ k v)
|
|
|
|
(cons (string->symbol k) v))))))
|
2008-02-22 12:57:18 +01:00
|
|
|
|
2008-02-29 00:32:49 +01:00
|
|
|
(define (commit-utc-timestamp commit)
|
|
|
|
(match-bind
|
|
|
|
"^(.*) ([0-9]+) ([+-][0-9]+)" (assq-ref (parse-commit commit) 'committer)
|
|
|
|
(_ who ts tz)
|
|
|
|
(let ((ts (string->number ts)) (tz (string->number tz)))
|
|
|
|
(- ts (* (+ (* (quotient tz 100) 60) (remainder tz 100)) 60)))))
|
|
|
|
|
|
|
|
(define (with-output-to-blob* thunk)
|
2011-04-25 19:10:07 +02:00
|
|
|
(git-hash-object (with-output-to-string* thunk)))
|
2008-02-29 00:32:49 +01:00
|
|
|
|
2010-10-14 16:25:30 +02:00
|
|
|
(define-syntax with-output-to-blob
|
|
|
|
(syntax-rules ()
|
|
|
|
((_ f f* ...)
|
|
|
|
(with-output-to-blob* (lambda () f f* ...)))))
|
2008-02-29 00:32:49 +01:00
|
|
|
|
|
|
|
(define (with-input-from-blob* sha1 thunk)
|
2011-04-25 19:10:07 +02:00
|
|
|
(with-input-from-string* (git "show" sha1) thunk))
|
2008-02-29 00:32:49 +01:00
|
|
|
|
2010-10-14 16:25:30 +02:00
|
|
|
(define-syntax with-input-from-blob
|
|
|
|
(syntax-rules ()
|
|
|
|
((_ sha1 f f* ...)
|
|
|
|
(with-input-from-blob* sha1 (lambda () f f* ...)))))
|