vole
Clone
Read only, no credentials:
https://rodent.software/vole.git
Write over SSH with a registered key:
git clone ssh://git@rodent.software:2222/vole.git
A free and open-source forge that lives in your Git repo.
| 1 | package web |
| 2 | |
| 3 | // The role picker: one radio control for both kinds of role Vole has. An instance |
| 4 | // role says what an account may do on public repositories everywhere; a |
| 5 | // repository role says what one entry grants in one repository. They share a |
| 6 | // control because they are the same decision at two scopes, and the wording is |
| 7 | // the only difference. |
| 8 | |
| 9 | type roleOption struct { |
| 10 | Value string |
| 11 | Name string |
| 12 | Description string |
| 13 | } |
| 14 | |
| 15 | var instanceRoleOptions = []roleOption{ |
| 16 | {"none", "none", "no instance-wide access"}, |
| 17 | {"read", "read", "read and clone public repositories"}, |
| 18 | {"contribute", "contribute", "read, discuss, and push your own contrib branches"}, |
| 19 | {"maintain", "maintain", "push shared branches, triage, and approve on public repositories"}, |
| 20 | {"admin", "admin", "full admin on every repository, including private ones"}, |
| 21 | } |
| 22 | |
| 23 | // botRoleOptions is the instance-role list without admin. It is derived so a |
| 24 | // wording change to an instance role reaches both pickers. |
| 25 | var botRoleOptions = withoutAdminRole(instanceRoleOptions) |
| 26 | |
| 27 | func withoutAdminRole(options []roleOption) []roleOption { |
| 28 | kept := make([]roleOption, 0, len(options)) |
| 29 | for _, opt := range options { |
| 30 | if opt.Value != "admin" { |
| 31 | kept = append(kept, opt) |
| 32 | } |
| 33 | } |
| 34 | return kept |
| 35 | } |
| 36 | |
| 37 | var repoRoleOptions = []roleOption{ |
| 38 | {"none", "none", "no repository-specific entry"}, |
| 39 | {"read", "read", "clone, fetch, and browse"}, |
| 40 | {"contribute", "contribute", "discuss and push your own contrib branches"}, |
| 41 | {"maintain", "maintain", "push shared branches, triage, and approve"}, |
| 42 | {"admin", "admin", "manage access, protected branches, and settings"}, |
| 43 | } |
| 44 | |
| 45 | type rolePickerData struct { |
| 46 | Name string |
| 47 | Selected string |
| 48 | Legend string |
| 49 | Help string |
| 50 | Compact bool |
| 51 | Options []roleOption |
| 52 | } |
| 53 | |
| 54 | // newRolePicker is the one role-selection control. scope chooses the wording: |
| 55 | // instance roles apply to public repositories, while repository roles describe |
| 56 | // what the entry grants in one repository. A bot may hold an instance role but |
| 57 | // cannot be an instance admin, so its scope leaves that option out. compact is |
| 58 | // for table rows, where the descriptions live in the radio's accessible label |
| 59 | // rather than on screen. |
| 60 | func newRolePicker(name, selected, legend, help, scope string, compact bool) rolePickerData { |
| 61 | options := instanceRoleOptions |
| 62 | switch scope { |
| 63 | case "repo": |
| 64 | options = repoRoleOptions |
| 65 | case "bot": |
| 66 | options = botRoleOptions |
| 67 | } |
| 68 | return rolePickerData{ |
| 69 | Name: name, Selected: selected, Legend: legend, Help: help, |
| 70 | Compact: compact, Options: options, |
| 71 | } |
| 72 | } |
| 73 |