Skip to content

Commit ae6e990

Browse files
authored
Gclone (#1)
* GClone commands * Package commands * Workflows * Demo * Bootstrap
1 parent a57de38 commit ae6e990

24 files changed

+1609
-109
lines changed

.github/workflows/dependabot.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# To get started with Dependabot version updates, you'll need to specify which
2+
# package ecosystems to update and where the package manifests are located.
3+
# Please see the documentation for all configuration options:
4+
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
5+
6+
version: 2
7+
updates:
8+
- package-ecosystem: "gomod" # See documentation for possible values
9+
directory: "/" # Location of package manifests
10+
schedule:
11+
interval: "weekly"

.gitignore

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ go.work.sum
2525
.env
2626

2727
# Binaries
28-
$PROJECT_NAME
28+
gclone
2929
dist
3030

3131
# Demo
32-
demo/$PROJECT_NAME.cast
33-
demo/$PROJECT_NAME.gif
32+
demo/gclone.cast
33+
demo/gclone.gif

Makefile

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,26 @@ VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null || echo "v0.
22
COMMIT ?= $(shell git rev-parse --short HEAD 2>/dev/null || echo "unknown")
33
BUILD_DATE ?= $(shell date -u +"%Y-%m-%dT%H:%M:%SZ")
44
BUILD_USER ?= $(shell whoami)@$(shell hostname)
5-
PKG := github.com/user-cube/$PROJECT_NAME
5+
PKG := github.com/user-cube/gclone
66
LDFLAGS := -ldflags "-X $(PKG)/cmd.Version=$(VERSION) -X $(PKG)/cmd.BuildDate=$(BUILD_DATE) -X $(PKG)/cmd.GitCommit=$(COMMIT) -X $(PKG)/cmd.BuildUser=$(BUILD_USER)"
77

88
.PHONY: all
99
all: clean build
1010

1111
.PHONY: build
1212
build:
13-
@echo "Building $PROJECT_NAME $(VERSION) ($(COMMIT))"
14-
@go build $(LDFLAGS) -o $PROJECT_NAME main.go
13+
@echo "Building gclone $(VERSION) ($(COMMIT))"
14+
@go build $(LDFLAGS) -o gclone main.go
1515

1616
.PHONY: install
1717
install:
18-
@echo "Installing $PROJECT_NAME $(VERSION) to GOPATH"
18+
@echo "Installing gclone $(VERSION) to GOPATH"
1919
@go install $(LDFLAGS)
2020

2121
.PHONY: clean
2222
clean:
2323
@echo "Cleaning build artifacts"
24-
@rm -f $PROJECT_NAME
24+
@rm -f gclone
2525
@rm -rf dist
2626

2727
.PHONY: test
@@ -58,26 +58,26 @@ release-snapshot: clean
5858

5959
.PHONY: build-release
6060
build-release: clean
61-
@echo "Building release version of $PROJECT_NAME $(VERSION) ($(COMMIT))"
62-
@go build $(LDFLAGS) -o $PROJECT_NAME main.go
63-
@echo "Built $PROJECT_NAME binary with release information"
61+
@echo "Building release version of gclone $(VERSION) ($(COMMIT))"
62+
@go build $(LDFLAGS) -o gclone main.go
63+
@echo "Built gclone binary with release information"
6464
@echo "Version: $(VERSION)"
6565
@echo "Commit: $(COMMIT)"
6666
@echo "Build Date: $(BUILD_DATE)"
67-
@echo "Run ./$PROJECT_NAME version to verify"
67+
@echo "Run ./gclone version to verify"
6868

6969
.PHONY: help
7070
help:
71-
@echo "$PROJECT_NAME Makefile"
71+
@echo "GClone Makefile"
7272
@echo "---------------"
7373
@echo "Available targets:"
74-
@echo " all - Clean and build $PROJECT_NAME"
75-
@echo " build - Build the $PROJECT_NAME binary"
76-
@echo " install - Install $PROJECT_NAME to your GOPATH/bin"
74+
@echo " all - Clean and build gclone"
75+
@echo " build - Build the gclone binary"
76+
@echo " install - Install gclone to your GOPATH/bin"
7777
@echo " clean - Remove built binary and dist directory"
7878
@echo " test - Run tests"
7979
@echo " lint - Run linters (requires golangci-lint)"
8080
@echo " release - Create a full release using GoReleaser"
8181
@echo " release-snapshot - Create a local release snapshot for testing (no publish)"
82-
@echo " build-release - Build $PROJECT_NAME binary with release information"
82+
@echo " build-release - Build gclone binary with release information"
8383
@echo " help - Show this help message"

README.md

Lines changed: 220 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,222 @@
1-
# $PROJECT_NAME
1+
# GClone - Git Repository Cloning Tool
22

3-
Command description
3+
GClone is a command-line tool that helps you manage Git repository clones with multiple profiles. It allows you to define different SSH hosts and Git configurations for different Git accounts (e.g., personal, work), and automatically applies the appropriate settings when cloning repositories.
44

5-
![demo](/demo/$PROJECT_NAME-demo.gif)
5+
![demo](/demo/gclone-demo.gif)
6+
7+
## Features
8+
9+
- Clone repositories using different SSH configurations based on profiles
10+
- Automatically applies Git configurations per profile (username, email, etc.)
11+
- Supports different profile configurations for work, personal, and other accounts
12+
- Colorful and easy-to-use CLI interface with a dedicated UI package
13+
14+
## Installation
15+
16+
```bash
17+
# Clone the repository
18+
git clone [email protected]:user-cube/gclone.git
19+
20+
# Build and install
21+
cd gclone
22+
go install
23+
```
24+
25+
## Usage
26+
27+
### Initialize Configuration
28+
29+
```bash
30+
# Initialize the default configuration
31+
gclone init
32+
```
33+
34+
This creates a configuration file at `~/.gclone/config.yml` with some sample profiles.
35+
36+
### Manage Profiles
37+
38+
```bash
39+
# List all profiles
40+
gclone profile list
41+
42+
# Add a new profile
43+
gclone profile add personal --ssh-host=git-personal --git-username="Your Name" --git-email="[email protected]"
44+
45+
# Add a profile with URL patterns for automatic detection
46+
gclone profile add personal --ssh-host=git-personal --git-username="Your Name" --git-email="[email protected]" --url-pattern="github.com/your-username" --url-pattern="gitlab.com/your-username"
47+
48+
# Remove a profile
49+
gclone profile remove personal
50+
```
51+
52+
### Clone Repositories
53+
54+
```bash
55+
# Clone a repository using a specific profile
56+
gclone clone [email protected]:user/repo.git --profile=personal
57+
58+
# Clone with automatic profile detection based on URL patterns
59+
gclone clone [email protected]:your-personal-username/repo.git
60+
# GClone will automatically use the personal profile if the URL matches a configured pattern
61+
62+
# Clone with additional options
63+
gclone clone [email protected]:user/repo.git my-repo --profile=work --depth=1 --branch=main
64+
```
65+
66+
> **Note:** GClone only supports SSH URLs ([email protected]:user/repo.git format). HTTP/HTTPS URLs are not supported.
67+
68+
### View Configuration
69+
70+
```bash
71+
# View the current configuration
72+
gclone config
73+
```
74+
75+
## How It Works
76+
77+
When you clone a repository with GClone, it:
78+
79+
1. Reads your profile configuration from `~/.gclone/config.yml`
80+
2. Attempts to automatically detect the appropriate profile based on URL patterns
81+
3. Transforms the repository URL to use the specified SSH host for that profile
82+
4. Clones the repository using the modified URL
83+
5. Applies any Git configurations specified in the profile to the cloned repository
84+
85+
For example, if you have a profile named `personal` with an SSH host of `git-personal`, when you clone `[email protected]:user/repo.git`, GClone will automatically change it to `git@git-personal:user/repo.git`.
86+
87+
> **Note:** GClone only works with SSH URLs in the format `[email protected]:user/repo.git`.
88+
89+
### URL Pattern Matching
90+
91+
GClone can automatically select the appropriate profile based on URL patterns. For example:
92+
93+
- If you have a personal profile with a URL pattern of `github.com/your-username`
94+
- When you run `gclone clone [email protected]:your-username/repo.git`
95+
- GClone will automatically use your personal profile without you needing to specify `--profile=personal`
96+
97+
## UI Package
98+
99+
GClone includes a dedicated UI package that provides consistent user interface components across the application. The UI package includes:
100+
101+
- **Colors**: Colorful output for different types of messages (success, info, warning, error)
102+
- **Prompts**: Interactive prompts for user input (selection lists, confirmations, text input)
103+
- **Operations**: Functions for displaying operation status and progress
104+
- **Tables**: Simple text-based tables for displaying structured data
105+
- **Spinners**: Progress indicators for long-running operations
106+
107+
### Using the UI Package
108+
109+
If you're developing for GClone, you can use the UI package in your code like this:
110+
111+
```go
112+
import "github.com/user-cube/gclone/pkg/ui"
113+
114+
// Display colorful messages
115+
ui.Success("Operation completed successfully")
116+
ui.Info("Processing %s", ui.Highlight("important information"))
117+
ui.Warning("This might take a while")
118+
ui.Error("Error occurred: %v", err)
119+
120+
// Interactive prompts
121+
selected, _ := ui.SelectFromList("Choose an option", []string{"Option 1", "Option 2"})
122+
confirmed, _ := ui.Confirm("Are you sure?")
123+
input, _ := ui.PromptInput("Enter your name", "", nil)
124+
125+
// Operation status
126+
ui.OperationInfo("Cloning", "personal", map[string]string{
127+
"URL": "[email protected]:user/repo.git",
128+
})
129+
ui.OperationSuccess("Repository cloned successfully")
130+
```
131+
132+
See `examples/ui_examples.go` for more examples of using the UI package.
133+
134+
## Configuration
135+
136+
The configuration file is stored at `~/.gclone/config.yml` and has the following structure:
137+
138+
```yaml
139+
profiles:
140+
personal:
141+
name: Personal
142+
ssh_host: git-personal
143+
url_patterns:
144+
- github.com/your-personal-username
145+
- github.com:your-personal-username
146+
git_configs:
147+
user.name: Your Name
148+
user.email: [email protected]
149+
work:
150+
name: Work
151+
ssh_host: git-work
152+
url_patterns:
153+
- github.com/your-work-organization
154+
- github.com:your-work-organization
155+
git_configs:
156+
user.name: Your Work Name
157+
user.email: [email protected]
158+
```
159+
160+
## SSH Configuration
161+
162+
GClone can help you manage your SSH configurations automatically. For each profile, GClone can generate and maintain the necessary SSH host configuration.
163+
164+
### Using the SSH Config Command
165+
166+
GClone provides a built-in command to create or update SSH configurations:
167+
168+
```bash
169+
# Generate SSH config for a specific profile
170+
gclone ssh-config personal
171+
172+
# Or run without arguments to select from available profiles
173+
gclone ssh-config
174+
```
175+
176+
This command will:
177+
178+
1. Create a `~/.gclone/ssh_config` file with the SSH host configuration for your profile
179+
2. Add an `Include ~/.gclone/ssh_config` directive to your main `~/.ssh/config` file if it doesn't exist
180+
181+
The generated configuration will look like this:
182+
183+
```
184+
# personal profile (added by gclone)
185+
Host github.com-personal
186+
Hostname github.com
187+
AddKeysToAgent yes
188+
UseKeychain yes
189+
IdentityFile ~/.ssh/github_personal
190+
```
191+
192+
### Manual Configuration
193+
194+
If you prefer to set up SSH configurations manually, you can add them directly to your `~/.ssh/config` file:
195+
196+
```
197+
# Personal GitHub account
198+
Host github.com-personal
199+
Hostname github.com
200+
AddKeysToAgent yes
201+
UseKeychain yes
202+
IdentityFile ~/.ssh/github_personal
203+
204+
# Work GitHub account
205+
Host github.com-work
206+
Hostname github.com
207+
AddKeysToAgent yes
208+
UseKeychain yes
209+
IdentityFile ~/.ssh/github_work
210+
```
211+
212+
In this example:
213+
214+
- `Host github.com-personal` defines the alias that matches the `ssh_host` in your GClone profile
215+
- `Hostname github.com` specifies the actual Git server to connect to
216+
- `IdentityFile ~/.ssh/github_personal` specifies which SSH key to use for this host
217+
218+
When GClone transforms a URL from `[email protected]:user/repo.git` to `[email protected]:user/repo.git`, SSH will use the configuration defined for the `github.com-personal` host.
219+
220+
## License
221+
222+
This project is licensed under the MIT License - see the LICENSE file for details.

0 commit comments

Comments
 (0)