summaryrefslogtreecommitdiff
path: root/readme.org
blob: 1aeb9a1e31a846f4d154f9a4c3f1b9c23a701263 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#+TITLE: Shackle Shell
#+AUTHOR: Justin Wernick

A shell for restricting access on a version control server.

This is intended as a replacement for [[https://git-scm.com/docs/git-shell][Git Shell]], but with a few opinionated
differences:

- Additional commands, like creating new repos, are built in. No extension with
  shell scripts.
- Strict enforcement of a specified directory structure. Git push / pull
  commands only work for these paths. New repos are created in these paths.
  - Private git repos are created in =~/git/<username>/<reponame>.git=
  - Shared git repos are created in =~/git/<groupname>/<reponame>.git=
- Better interactive UX than Git Shell, including:
  - Command history (limited to the current session).
  - Emacs-style shortcuts (eg =Ctrl+a= to move cursor to the beginning of line).
  - Docs available for all commands, available in the shell itself.
- (coming soon!) Support for other other version control systems.

* Getting Started

** Usage

Shackle Shell is intended to be set as the default shell for a user on a git
server, where the user connects over SSH (see the Installation section below).

When you log in over SSH, you'll see a prompt, ready for you to type commands.

#+begin_src fundamental
  >
#+end_src

You can see the built in help by running the =help= command.

#+begin_src fundamental
  > help
  Usage: <COMMAND>

  Commands:
    init              Create a new repository
    list              List all repositories available
    set-description   Sets the description of a repository, as shown in the CLI listing and web interfaces
    set-branch        Sets the main branch of the repository
    exit              Quit the shell
    git-upload-pack   Server side command required to git fetch from the server
    git-receive-pack  Server side command required by git push to the server
    help              Print this message or the help of the given subcommand(s)

  Options:
    -h, --help  Print help
#+end_src

The =init= command is used to create a new repo. In its simplest form, you just
provide it with the name of your new repo. This will create a git repo with
individual ownership.

#+begin_src fundamental
  > init awesome-project-idea
  Successfully created "git/shukkie/awesome-project-idea.git"
#+end_src

The path given here is relative to your home directory. So the full URL to clone
this repo is =<username>@<server domain>:<git path>=

#+begin_src fundamental
  $ git clone shukkie@example.com:git/shukkie/awesome-project-idea.git
#+end_src

You can learn its advanced options by using the =--help= flag. This works for
all of the options, and is a great way to learn what all the commands do.

#+begin_src fundamental
  > init --help
  Create a new repository

  Usage: init [OPTIONS] <REPO_NAME>

  Arguments:
    <REPO_NAME>  Name of the new repository

  Options:
        --group <GROUP>              Share repository ownership with the specified group (user must be a member of the group)
        --description <DESCRIPTION>  Sets the description of the repository, as shown in the CLI listing and web interfaces
        --branch <BRANCH>            Sets the main branch of the repository [default: main]
    -h, --help                       Print help
#+end_src

** Installation

# TODO

# cargo install to build from source
# set as the user's shell
# create the appropriate directory structure

* Development Guide

# TODO

# need to have docker installed
# cargo test --workspace
# cargo clippy

* Roadmap / Issue Tracker TODO list

** MVP

- [X] interactive command prompt
- [X] non-interactive commands can be run with -c
- [X] exit command
- [X] git init of private repo
- [X] responds to unknown commands
- [X] Isolation of workdir between tests
- [X] git fetch with git upload-pack
- [X] git push with git receive-pack
- [X] proper shell argument lexing, with quote stuff
- [X] history (only within same session)
- [X] don't quit interactive shell sessions if there's an error
- [X] help command
- [X] restrict repos to only acceptable paths
  - [X] clone / pull
  - [X] push
- [X] git init of shared repos
  - [X] create the shared repo in the right place
  - [X] use the right file permissions and config
  - [X] don't allow this to be a group the user isn't in
  - [X] allow pull and push from shared repos
- [X] listing of repos
- [X] set repo descriptions
  - [X] init new repo
  - [X] change an existing repo
- [X] Change ~git-init~ name to just be ~init~. Later, the ~git~ part will be an
  option which defaults to git.
- [X] set the main branch of a repo
- [X] help docs on all the commands

** Post-MVP

- [X] proper licensing
- [ ] all the getting started stuff in the readme
- [ ] consider having the workspace root abstract so that --workspace isn't needed
- [ ] publish to crates.io
- [ ] project website
- [ ] functions correctly when the git path isn't created yet
- [ ] git archive with git upload-archive
- [ ] git config management around protected branches
- [ ] move a repo to a different group
- [ ] housekeeping git tasks (git fsck, git gc)
- [ ] pijul fetch and pijul push
- [ ] pijul support on other commands

* License

Licensed under [[./LICENSE][MIT License]].