Refactor codebase for Phase 3
This commit is contained in:
@@ -0,0 +1,521 @@
|
||||
# Gitocean Phase 2 Plan: Usability
|
||||
|
||||
Phase 2 focuses on making Gitocean feel usable as a day-to-day personal Git hosting environment. This phase is not about GitLab enterprise parity, CI/CD, or a web UI. It is about setup, common workflows, repository inspection, pull request ergonomics, and maintenance.
|
||||
|
||||
## Goals
|
||||
|
||||
- Make first-time setup simple.
|
||||
- Make CLI output readable by humans by default.
|
||||
- Support the common workflow of publishing an existing local repository.
|
||||
- Provide enough CLI inspection tools to compensate for no web UI.
|
||||
- Improve pull request workflows with diff and checkout commands.
|
||||
- Add simple repository metadata and settings.
|
||||
- Add lightweight collaboration support.
|
||||
- Add comments, token management, and basic admin/backup tooling.
|
||||
|
||||
---
|
||||
|
||||
## 1. Config + `gitocean init`
|
||||
|
||||
### Add server config file
|
||||
|
||||
Create a persistent server config file, likely:
|
||||
|
||||
```text
|
||||
storage/config.json
|
||||
```
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"addr": ":8080",
|
||||
"public_url": "http://localhost:8080",
|
||||
"storage": "storage",
|
||||
"mysql_dsn": "root:pass@tcp(127.0.0.1:3306)/gitocean?parseTime=true"
|
||||
}
|
||||
```
|
||||
|
||||
### Add command
|
||||
|
||||
```bash
|
||||
gitocean init
|
||||
```
|
||||
|
||||
It should:
|
||||
|
||||
1. Prompt for server listen address.
|
||||
2. Prompt for public URL.
|
||||
3. Prompt for storage directory.
|
||||
4. Prompt for MySQL DSN or individual MySQL fields.
|
||||
5. Create the database if missing.
|
||||
6. Run migrations.
|
||||
7. Create storage directories.
|
||||
8. Optionally create the first user account.
|
||||
9. Write config file.
|
||||
10. Print next-step instructions.
|
||||
|
||||
### Update server command
|
||||
|
||||
Allow:
|
||||
|
||||
```bash
|
||||
gitocean server
|
||||
```
|
||||
|
||||
without requiring `--dsn` if config exists.
|
||||
|
||||
Still allow overrides:
|
||||
|
||||
```bash
|
||||
gitocean server --config storage/config.json
|
||||
```
|
||||
|
||||
```bash
|
||||
gitocean server --dsn '...' --addr :8080 --storage storage
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2. Friendly CLI output
|
||||
|
||||
Most commands currently print JSON. Phase 2 should make human-friendly output the default.
|
||||
|
||||
### Add global or per-command JSON output
|
||||
|
||||
Support:
|
||||
|
||||
```bash
|
||||
gitocean repo search test --json
|
||||
```
|
||||
|
||||
or eventually a global flag:
|
||||
|
||||
```bash
|
||||
gitocean --json repo search test
|
||||
```
|
||||
|
||||
### Examples
|
||||
|
||||
Repo creation should print:
|
||||
|
||||
```text
|
||||
Created public repository owen/test
|
||||
|
||||
Clone:
|
||||
git clone http://localhost:8080/owen/test.git
|
||||
|
||||
Add existing repo:
|
||||
git remote add origin http://localhost:8080/owen/test.git
|
||||
git branch -M main
|
||||
git push -u origin main
|
||||
```
|
||||
|
||||
Search should print a table:
|
||||
|
||||
```text
|
||||
REPOSITORY VISIBILITY DESCRIPTION UPDATED
|
||||
owen/test public Test repository 2m ago
|
||||
alice/demo public Demo project 3h ago
|
||||
```
|
||||
|
||||
PR list should print:
|
||||
|
||||
```text
|
||||
#1 open Add config support bob:feature-config -> main
|
||||
#2 merged Fix clone auth alice:fix-auth -> main
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 3. `repo publish`
|
||||
|
||||
Add a command for publishing an existing local Git repository.
|
||||
|
||||
```bash
|
||||
gitocean repo publish NAME --public
|
||||
gitocean repo publish NAME --private
|
||||
```
|
||||
|
||||
Optional flags:
|
||||
|
||||
```bash
|
||||
gitocean repo publish NAME --public --remote origin
|
||||
gitocean repo publish NAME --public --branch main
|
||||
gitocean repo publish NAME --public --description "My project"
|
||||
```
|
||||
|
||||
### Behavior
|
||||
|
||||
From inside a local Git repository:
|
||||
|
||||
1. Verify current directory is a Git repository.
|
||||
2. Create remote repository through API.
|
||||
3. Add remote if missing.
|
||||
4. Set or rename current branch to `main` by default.
|
||||
5. Push current branch.
|
||||
6. Set upstream.
|
||||
7. Print success and clone URL.
|
||||
|
||||
Equivalent workflow:
|
||||
|
||||
```bash
|
||||
gitocean repo create test --public
|
||||
git remote add origin http://localhost:8080/owen/test.git
|
||||
git branch -M main
|
||||
git push -u origin main
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. `repo view`, branches, tags
|
||||
|
||||
Since there is no web UI, add basic repository inspection commands.
|
||||
|
||||
### Repo view
|
||||
|
||||
```bash
|
||||
gitocean repo view OWNER/REPO
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```text
|
||||
owen/test
|
||||
Visibility: public
|
||||
Default branch: main
|
||||
Description: My test project
|
||||
|
||||
Clone:
|
||||
git clone http://localhost:8080/owen/test.git
|
||||
|
||||
Open PRs: 2
|
||||
Branches: 4
|
||||
Tags: 1
|
||||
```
|
||||
|
||||
### Branch listing
|
||||
|
||||
```bash
|
||||
gitocean repo branches OWNER/REPO
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```text
|
||||
BRANCH COMMIT UPDATED MESSAGE
|
||||
main 8f31abc 2 hours ago Initial commit
|
||||
feature-x 1ab22df 1 day ago Add feature
|
||||
```
|
||||
|
||||
### Tag listing
|
||||
|
||||
```bash
|
||||
gitocean repo tags OWNER/REPO
|
||||
```
|
||||
|
||||
Output:
|
||||
|
||||
```text
|
||||
TAG COMMIT DATE MESSAGE
|
||||
v0.1.0 8f31abc 2026-06-08 First release
|
||||
```
|
||||
|
||||
### API additions
|
||||
|
||||
```http
|
||||
GET /api/repos/{owner}/{repo}/branches
|
||||
GET /api/repos/{owner}/{repo}/tags
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. PR diff + PR checkout
|
||||
|
||||
Pull requests are difficult to use without seeing and checking out changes.
|
||||
|
||||
### PR diff
|
||||
|
||||
```bash
|
||||
gitocean pr diff OWNER/REPO NUMBER
|
||||
```
|
||||
|
||||
Server should generate a diff between:
|
||||
|
||||
```text
|
||||
source_repo:source_branch
|
||||
```
|
||||
|
||||
and:
|
||||
|
||||
```text
|
||||
target_repo:target_branch
|
||||
```
|
||||
|
||||
API:
|
||||
|
||||
```http
|
||||
GET /api/repos/{owner}/{repo}/pulls/{number}/diff
|
||||
```
|
||||
|
||||
Return `text/plain` patch/diff output.
|
||||
|
||||
### PR checkout
|
||||
|
||||
```bash
|
||||
gitocean pr checkout OWNER/REPO NUMBER
|
||||
```
|
||||
|
||||
From inside a local Git repo, it should:
|
||||
|
||||
1. Fetch PR source branch from source repository URL.
|
||||
2. Create or update a local branch such as `pr-1`.
|
||||
3. Check out that branch.
|
||||
|
||||
Equivalent:
|
||||
|
||||
```bash
|
||||
git fetch http://localhost:8080/bob/test.git fix:pr-1
|
||||
git checkout pr-1
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. Repo description/default branch/visibility update
|
||||
|
||||
Add basic repository settings.
|
||||
|
||||
### Schema additions
|
||||
|
||||
Add columns to `repositories`:
|
||||
|
||||
- `description TEXT NOT NULL DEFAULT ''`
|
||||
- `default_branch VARCHAR(200) NOT NULL DEFAULT 'main'`
|
||||
- `archived BOOLEAN NOT NULL DEFAULT false`
|
||||
|
||||
### Commands
|
||||
|
||||
```bash
|
||||
gitocean repo set OWNER/REPO --description "My project"
|
||||
gitocean repo set OWNER/REPO --visibility private
|
||||
gitocean repo set OWNER/REPO --visibility public
|
||||
gitocean repo set OWNER/REPO --default-branch main
|
||||
gitocean repo archive OWNER/REPO
|
||||
gitocean repo unarchive OWNER/REPO
|
||||
```
|
||||
|
||||
### API additions
|
||||
|
||||
```http
|
||||
PATCH /api/repos/{owner}/{repo}
|
||||
```
|
||||
|
||||
Owner-only.
|
||||
|
||||
---
|
||||
|
||||
## 7. Collaborators
|
||||
|
||||
Owner-only permissions are too limiting for personal collaboration. Add simple collaborators.
|
||||
|
||||
### Roles
|
||||
|
||||
- `read`: can clone/fetch private repositories.
|
||||
- `write`: can clone/fetch/push.
|
||||
|
||||
Owner remains the only user who can:
|
||||
|
||||
- delete repository
|
||||
- update settings
|
||||
- manage collaborators
|
||||
- merge/close PRs, unless explicitly changed later
|
||||
|
||||
### Schema
|
||||
|
||||
Add table:
|
||||
|
||||
```text
|
||||
repository_collaborators
|
||||
id
|
||||
repository_id
|
||||
user_id
|
||||
role: read/write
|
||||
created_at
|
||||
```
|
||||
|
||||
Unique key:
|
||||
|
||||
```text
|
||||
(repository_id, user_id)
|
||||
```
|
||||
|
||||
### Commands
|
||||
|
||||
```bash
|
||||
gitocean repo collaborators OWNER/REPO
|
||||
gitocean repo collaborator add OWNER/REPO USER --role read
|
||||
gitocean repo collaborator add OWNER/REPO USER --role write
|
||||
gitocean repo collaborator remove OWNER/REPO USER
|
||||
```
|
||||
|
||||
### API additions
|
||||
|
||||
```http
|
||||
GET /api/repos/{owner}/{repo}/collaborators
|
||||
POST /api/repos/{owner}/{repo}/collaborators
|
||||
DELETE /api/repos/{owner}/{repo}/collaborators/{username}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. PR comments
|
||||
|
||||
Add simple general comments on pull requests. Line comments can wait.
|
||||
|
||||
### Schema
|
||||
|
||||
Add table:
|
||||
|
||||
```text
|
||||
pull_request_comments
|
||||
id
|
||||
pull_request_id
|
||||
author_user_id
|
||||
body
|
||||
created_at
|
||||
updated_at
|
||||
```
|
||||
|
||||
### Commands
|
||||
|
||||
```bash
|
||||
gitocean pr comment OWNER/REPO NUMBER "Looks good"
|
||||
gitocean pr comments OWNER/REPO NUMBER
|
||||
```
|
||||
|
||||
Optional editor support later:
|
||||
|
||||
```bash
|
||||
gitocean pr comment OWNER/REPO NUMBER --editor
|
||||
```
|
||||
|
||||
### API additions
|
||||
|
||||
```http
|
||||
GET /api/repos/{owner}/{repo}/pulls/{number}/comments
|
||||
POST /api/repos/{owner}/{repo}/pulls/{number}/comments
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. Token management
|
||||
|
||||
Tokens expire after 7 days, but users need visibility and revocation.
|
||||
|
||||
### Commands
|
||||
|
||||
```bash
|
||||
gitocean token list
|
||||
gitocean token revoke TOKEN_ID
|
||||
gitocean token prune
|
||||
```
|
||||
|
||||
### Behavior
|
||||
|
||||
- `token list`: show active tokens for current user.
|
||||
- `token revoke`: revoke one token.
|
||||
- `token prune`: remove expired/revoked tokens from database. Owner/admin-only if global, current-user only otherwise.
|
||||
|
||||
### API additions
|
||||
|
||||
```http
|
||||
GET /api/tokens
|
||||
DELETE /api/tokens/{id}
|
||||
POST /api/tokens/prune
|
||||
```
|
||||
|
||||
### CLI expired-session UX
|
||||
|
||||
When API returns unauthorized, show:
|
||||
|
||||
```text
|
||||
Your session may have expired. Run:
|
||||
gitocean login
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. Backup/admin commands
|
||||
|
||||
Personal servers need reliable maintenance tooling.
|
||||
|
||||
### Admin commands
|
||||
|
||||
```bash
|
||||
gitocean admin users list
|
||||
gitocean admin users delete USER
|
||||
gitocean admin repos list
|
||||
gitocean admin storage check
|
||||
gitocean admin tokens prune
|
||||
```
|
||||
|
||||
For MVP, admin can be:
|
||||
|
||||
- the first registered user, or
|
||||
- a boolean `is_admin` column on `users`.
|
||||
|
||||
### Backup commands
|
||||
|
||||
```bash
|
||||
gitocean backup create backup.tar.gz
|
||||
gitocean backup restore backup.tar.gz
|
||||
```
|
||||
|
||||
Backup should include:
|
||||
|
||||
- server config
|
||||
- `storage/repos/`
|
||||
- MySQL dump of metadata
|
||||
|
||||
Possible implementation:
|
||||
|
||||
```bash
|
||||
mysqldump ... > metadata.sql
|
||||
tar -czf backup.tar.gz storage/config.json storage/repos metadata.sql
|
||||
```
|
||||
|
||||
Restore should:
|
||||
|
||||
1. Stop or warn about running server.
|
||||
2. Restore config.
|
||||
3. Restore repositories.
|
||||
4. Restore database from SQL dump.
|
||||
5. Run migrations after restore.
|
||||
|
||||
---
|
||||
|
||||
## Recommended implementation order
|
||||
|
||||
1. Config file support and `gitocean init`.
|
||||
2. Friendly CLI output with `--json` escape hatch.
|
||||
3. `repo publish`.
|
||||
4. Repository metadata fields and `repo view`.
|
||||
5. Branch/tag listing.
|
||||
6. PR diff.
|
||||
7. PR checkout.
|
||||
8. Collaborators.
|
||||
9. PR comments.
|
||||
10. Token management.
|
||||
11. Backup/admin commands.
|
||||
|
||||
## Success criteria
|
||||
|
||||
Phase 2 is successful when a user can comfortably:
|
||||
|
||||
1. Initialize the server without memorizing flags.
|
||||
2. Register/login from CLI.
|
||||
3. Publish an existing local Git repository with one command.
|
||||
4. Clone, push, search, and inspect repositories.
|
||||
5. Open, inspect, checkout, and merge PRs.
|
||||
6. Share private repositories with specific users.
|
||||
7. Revoke tokens and back up the server.
|
||||
Reference in New Issue
Block a user