Initial import of rash-git-cli
This commit is contained in:
@@ -1,18 +1,21 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2026 hans
|
Copyright (c) 2026 Hans Dijkema
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
associated documentation files (the "Software"), to deal in the Software without restriction, including
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
in the Software without restriction, including without limitation the rights
|
||||||
copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
following conditions:
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all copies or substantial
|
The above copyright notice and this permission notice shall be included in all
|
||||||
portions of the Software.
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
USE OR OTHER DEALINGS IN THE SOFTWARE.
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|||||||
@@ -1,3 +1,26 @@
|
|||||||
# rash-git-cli
|
# rash-git-cli
|
||||||
|
|
||||||
A rash module of the racket module git-cli
|
Rash line-mode integration for `git-cli`.
|
||||||
|
|
||||||
|
`git-cli` remains a pure Racket package. Install and require `rash-git-cli`
|
||||||
|
only when the Rash command form is wanted.
|
||||||
|
|
||||||
|
```racket
|
||||||
|
#lang rash
|
||||||
|
|
||||||
|
(require rash-git-cli)
|
||||||
|
|
||||||
|
git status
|
||||||
|
git add -A
|
||||||
|
git log --oneline -5
|
||||||
|
git commit -m "Update documentation"
|
||||||
|
|
||||||
|
;; The ordinary git-cli procedure is still available in Racket expressions.
|
||||||
|
(git 'status)
|
||||||
|
```
|
||||||
|
|
||||||
|
Bare words in the Rash line form are quoted as command arguments. Quoted
|
||||||
|
strings and parenthesized Racket expressions keep their normal Racket meaning.
|
||||||
|
|
||||||
|
The package depends on `git-cli`, `rash`, and `linea`. `git-cli` does not
|
||||||
|
depend on this package.
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#lang rash
|
||||||
|
|
||||||
|
(require rash-git-cli)
|
||||||
|
|
||||||
|
git status
|
||||||
|
git log --oneline -5
|
||||||
|
|
||||||
|
(git 'status)
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
#lang info
|
||||||
|
|
||||||
|
(define collection "rash-git-cli")
|
||||||
|
(define pkg-desc "Rash line-mode integration for git-cli")
|
||||||
|
(define version "0.1.0")
|
||||||
|
(define pkg-authors '("Hans Dijkema"))
|
||||||
|
(define license 'MIT)
|
||||||
|
|
||||||
|
(define deps
|
||||||
|
'("base"
|
||||||
|
"git-cli"
|
||||||
|
"linea"
|
||||||
|
"rash"))
|
||||||
|
|
||||||
|
(define build-deps
|
||||||
|
'("rackunit-lib"
|
||||||
|
"racket-doc"
|
||||||
|
"scribble-lib"))
|
||||||
|
|
||||||
|
(define scribblings
|
||||||
|
'(("scribblings/rash-git-cli.scrbl" () ("rash-git-cli"))))
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
#lang racket/base
|
||||||
|
|
||||||
|
(require (except-in git-cli git)
|
||||||
|
(only-in git-cli [git git/procedure])
|
||||||
|
(for-syntax racket/base
|
||||||
|
syntax/parse
|
||||||
|
linea/line-macro-prop))
|
||||||
|
|
||||||
|
(provide (except-out (all-from-out git-cli) git/procedure)
|
||||||
|
git)
|
||||||
|
|
||||||
|
;; `git` remains the ordinary git-cli procedure in Racket expression mode.
|
||||||
|
;; In Linea/Rash line mode, bare command words are quoted and passed to that
|
||||||
|
;; same procedure.
|
||||||
|
(begin-for-syntax
|
||||||
|
(define (git-argument->expression stx)
|
||||||
|
(syntax-parse stx
|
||||||
|
[(quote value)
|
||||||
|
stx]
|
||||||
|
[id:id
|
||||||
|
#`(quote #,(syntax-e #'id))]
|
||||||
|
[_
|
||||||
|
stx]))
|
||||||
|
|
||||||
|
(struct git-line-binding (target)
|
||||||
|
#:property prop:procedure
|
||||||
|
(λ (self stx)
|
||||||
|
(syntax-parse stx
|
||||||
|
[id:id
|
||||||
|
(git-line-binding-target self)]
|
||||||
|
[(id argument ...)
|
||||||
|
#`(#,(git-line-binding-target self) argument ...)]))
|
||||||
|
#:property prop:line-macro
|
||||||
|
(λ (self stx)
|
||||||
|
(syntax-parse stx
|
||||||
|
[(_ argument ...)
|
||||||
|
(define arguments
|
||||||
|
(map git-argument->expression
|
||||||
|
(syntax->list #'(argument ...))))
|
||||||
|
#`(#,(git-line-binding-target self) #,@arguments)]))))
|
||||||
|
|
||||||
|
(define-syntax git
|
||||||
|
(git-line-binding #'git/procedure))
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
#lang scribble/manual
|
||||||
|
|
||||||
|
@(require (for-label racket/base
|
||||||
|
git-cli))
|
||||||
|
|
||||||
|
@title[#:tag "top"]{rash-git-cli}
|
||||||
|
@author["Hans Dijkema / hans@dijkewijk.nl"]
|
||||||
|
|
||||||
|
@section{Rash integration}
|
||||||
|
|
||||||
|
The @tt{rash-git-cli} package adds a Linea/Rash line meaning to the
|
||||||
|
@racket[git] procedure from @racketmodname[git-cli].
|
||||||
|
|
||||||
|
@verbatim{
|
||||||
|
#lang rash
|
||||||
|
|
||||||
|
(require rash-git-cli)
|
||||||
|
|
||||||
|
git status
|
||||||
|
git add -A
|
||||||
|
git log --oneline -5
|
||||||
|
git commit -m "Update documentation"
|
||||||
|
}
|
||||||
|
|
||||||
|
In an ordinary Racket expression, @racket[git] remains the first-class
|
||||||
|
procedure exported by @racketmodname[git-cli]:
|
||||||
|
|
||||||
|
@racketblock[
|
||||||
|
(git 'status)
|
||||||
|
(procedure? git)
|
||||||
|
]
|
||||||
|
|
||||||
|
Bare words in line mode are quoted before they are passed to @racket[git].
|
||||||
|
Quoted strings and parenthesized Racket expressions retain their normal Racket
|
||||||
|
meaning.
|
||||||
|
|
||||||
|
The base @tt{git-cli} package has no dependency on Rash, Linea, or this package.
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
#lang racket
|
||||||
|
|
||||||
|
(require rackunit
|
||||||
|
racket/file
|
||||||
|
linea/read)
|
||||||
|
|
||||||
|
(define tmp (make-temporary-file "rash-git-cli~a" 'directory))
|
||||||
|
|
||||||
|
(dynamic-wind
|
||||||
|
void
|
||||||
|
(λ ()
|
||||||
|
(define module-path (build-path tmp "Rash.rkt"))
|
||||||
|
|
||||||
|
(call-with-output-file module-path
|
||||||
|
#:exists 'truncate/replace
|
||||||
|
(λ (out)
|
||||||
|
(displayln "#lang rash" out)
|
||||||
|
(displayln "(require rash-git-cli)" out)))
|
||||||
|
|
||||||
|
(define module-name `(file ,(path->string module-path)))
|
||||||
|
|
||||||
|
(parameterize ([current-directory tmp])
|
||||||
|
(dynamic-require module-name #f))
|
||||||
|
|
||||||
|
(define ns (module->namespace module-name))
|
||||||
|
(parameterize ([current-directory tmp]
|
||||||
|
[current-namespace ns])
|
||||||
|
;; In expression mode the same binding remains callable as git-cli's
|
||||||
|
;; first-class Git procedure.
|
||||||
|
(check-true (eval #'(procedure? git)))
|
||||||
|
|
||||||
|
;; The Rash line form initializes a repository.
|
||||||
|
(define init-line
|
||||||
|
(linea-read-syntax 'drracket-interaction
|
||||||
|
(open-input-string "git init\n")))
|
||||||
|
(eval init-line)
|
||||||
|
(check-true (directory-exists? (build-path tmp ".git")))
|
||||||
|
|
||||||
|
(check-true (eval #'(git 'config 'set! "user.name" "Rash Test")))
|
||||||
|
(check-true (eval #'(git 'config 'set! "user.email" "rash@example.invalid")))
|
||||||
|
|
||||||
|
(call-with-output-file (build-path tmp "test.txt")
|
||||||
|
#:exists 'truncate/replace
|
||||||
|
(λ (out)
|
||||||
|
(displayln "rash" out)))
|
||||||
|
|
||||||
|
(eval
|
||||||
|
(linea-read-syntax 'drracket-interaction
|
||||||
|
(open-input-string "git add test.txt\n")))
|
||||||
|
|
||||||
|
(check-true
|
||||||
|
(eval
|
||||||
|
(linea-read-syntax 'drracket-interaction
|
||||||
|
(open-input-string
|
||||||
|
"git commit -m \"Rash commit\"\n"))))
|
||||||
|
|
||||||
|
(check-equal?
|
||||||
|
(eval
|
||||||
|
(linea-read-syntax 'drracket-interaction
|
||||||
|
(open-input-string "git status\n")))
|
||||||
|
'())
|
||||||
|
(check-equal? (eval #'(git 'status)) '())))
|
||||||
|
(λ ()
|
||||||
|
(delete-directory/files tmp #:must-exist? #f)))
|
||||||
Reference in New Issue
Block a user