123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147 |
- #!/usr/bin/env -S guile --no-auto-compile -e (src-clean) -s
- !#
- ;;;; src-clean --- Guile script which cleans up src directory
- ;;;; Copyright © 2020 Oleg Pykhalov <go.wigust@gmail.com>
- ;;;; Released under the GNU GPLv3 or any later version.
- (define-module (src-clean)
- #:use-module (ice-9 format)
- #:use-module (ice-9 ftw)
- #:use-module (ice-9 match)
- #:use-module (ice-9 popen)
- #:use-module (ice-9 popen)
- #:use-module (ice-9 rdelim)
- #:use-module (srfi srfi-1)
- #:use-module (srfi srfi-26)
- #:use-module (srfi srfi-37)
- #:export (main))
- ;;; Commentary:
- ;;;
- ;;; This script only depends on Guile, which you could get either with Guix:
- ;;; guix environment --ad-hoc guile
- ;;; or Nix:
- ;;; nix-shell -p guile git
- ;;;
- ;;; src-clean --directory=src --author=go.wigust@gmail.com --ignore=dotfiles,rofi-themes
- ;;;
- ;;; Code:
- (define %options
- (let ((display-and-exit-proc (lambda (msg)
- (lambda (opt name arg loads)
- (display msg) (quit)))))
- (list (option '(#\v "version") #f #f
- (display-and-exit-proc "src-clean version 0.0.1\n"))
- (option '(#\a "author") #t #f
- (lambda (opt name arg result)
- (alist-cons 'author arg result)))
- (option '(#\d "directory") #t #f
- (lambda (opt name arg result)
- (alist-cons 'directory arg result)))
- (option '(#\i "ignore") #t #f
- (lambda (opt name arg result)
- (alist-cons 'ignore arg result)))
- (option '(#\h "help") #f #f
- (display-and-exit-proc
- "Usage: src-clean ...")))))
- (define %default-options
- '())
- (define (system->string . args)
- (let* ((port (apply open-pipe* OPEN_READ args))
- (output (read-string port)))
- (close-pipe port)
- output))
- (define %cache-file
- (and=> (getenv "HOME")
- (lambda (home)
- (string-append home "/.cache/src-clean.txt"))))
- (define (git-origins directory)
- (map (cut string-split <> #\tab)
- (string-split (string-trim-right (system->string "git" "-C" directory
- "remote" "--verbose"))
- #\newline)))
- (define (main args)
- (define opts
- (args-fold (cdr (program-arguments))
- %options
- (lambda (opt name arg loads)
- (error "Unrecognized option `~A'" name))
- (lambda (op loads)
- (cons op loads))
- %default-options))
- (define author
- (assoc-ref opts 'author))
- (define ignore
- (and=> (assoc-ref opts 'ignore)
- (lambda (ignore)
- (string-split (assoc-ref opts 'ignore) #\,))))
- (define cache
- (open-file %cache-file "a"))
- (define cache-existing
- (string-split (with-input-from-file %cache-file read-string) #\newline))
- (define directories
- (let ((directories (let ((directory (assoc-ref opts 'directory)))
- (match (scandir directory)
- (("." ".." files ...)
- (map (cut string-append directory "/" <>)
- files))))))
- (if ignore
- (fold (lambda (directory directories)
- (if (any (cut string= directory <>)
- (append ignore cache-existing))
- directories
- (cons directory directories)))
- '() directories)
- directories)))
- (setenv "PAGER" "")
- (for-each (lambda (directory)
- (format #t "Checking ~s directory...~%" directory)
- (if (any (cut string= ".git" <>)
- (match (scandir directory)
- (("." ".." file ...) file)))
- (let ((output (system->string "git" "-C" directory
- "log" "--all" "--format=%H"
- (string-append "--author=" author))))
- (cond ((string-null? output)
- (format #t "~s repository does not contain ~a commits.~%" directory author)
- (system* "git" "-C" directory "status")
- (exit 1))
- ((equal? '("") (git-origins directory))
- (format #t "No remotes in ~s repository.~%"
- directory)
- (exit 1))
- ((let ((origin (assoc-ref "origin" (git-origins directory))))
- (and origin
- (string-prefix? "https://github.com/"
- origin)))
- (format #t "origin's remote in ~s repository is GitHub.~%"
- directory)
- (exit 1))
- ((not (assoc "github" (git-origins directory)))
- (format #t "No github remote in ~s repository.~%"
- directory)
- (exit 1))
- (else (with-output-to-port cache
- (lambda ()
- (display directory)
- (newline))))))
- ;; TODO: Output to STDERR
- (begin (format #t "~s directory is not a Git repository.~%" directory)
- (exit 1))))
- directories))
- ;;; src-clean ends here
|