Skip to content

Gclone #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
May 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .github/workflows/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file

version: 2
updates:
- package-ecosystem: "gomod" # See documentation for possible values
directory: "/" # Location of package manifests
schedule:
interval: "weekly"
6 changes: 3 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@ go.work.sum
.env

# Binaries
$PROJECT_NAME
gclone
dist

# Demo
demo/$PROJECT_NAME.cast
demo/$PROJECT_NAME.gif
demo/gclone.cast
demo/gclone.gif
28 changes: 14 additions & 14 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,26 @@ VERSION ?= $(shell git describe --tags --always --dirty 2>/dev/null || echo "v0.
COMMIT ?= $(shell git rev-parse --short HEAD 2>/dev/null || echo "unknown")
BUILD_DATE ?= $(shell date -u +"%Y-%m-%dT%H:%M:%SZ")
BUILD_USER ?= $(shell whoami)@$(shell hostname)
PKG := github.com/user-cube/$PROJECT_NAME
PKG := github.com/user-cube/gclone
LDFLAGS := -ldflags "-X $(PKG)/cmd.Version=$(VERSION) -X $(PKG)/cmd.BuildDate=$(BUILD_DATE) -X $(PKG)/cmd.GitCommit=$(COMMIT) -X $(PKG)/cmd.BuildUser=$(BUILD_USER)"

.PHONY: all
all: clean build

.PHONY: build
build:
@echo "Building $PROJECT_NAME $(VERSION) ($(COMMIT))"
@go build $(LDFLAGS) -o $PROJECT_NAME main.go
@echo "Building gclone $(VERSION) ($(COMMIT))"
@go build $(LDFLAGS) -o gclone main.go

.PHONY: install
install:
@echo "Installing $PROJECT_NAME $(VERSION) to GOPATH"
@echo "Installing gclone $(VERSION) to GOPATH"
@go install $(LDFLAGS)

.PHONY: clean
clean:
@echo "Cleaning build artifacts"
@rm -f $PROJECT_NAME
@rm -f gclone
@rm -rf dist

.PHONY: test
Expand Down Expand Up @@ -58,26 +58,26 @@ release-snapshot: clean

.PHONY: build-release
build-release: clean
@echo "Building release version of $PROJECT_NAME $(VERSION) ($(COMMIT))"
@go build $(LDFLAGS) -o $PROJECT_NAME main.go
@echo "Built $PROJECT_NAME binary with release information"
@echo "Building release version of gclone $(VERSION) ($(COMMIT))"
@go build $(LDFLAGS) -o gclone main.go
@echo "Built gclone binary with release information"
@echo "Version: $(VERSION)"
@echo "Commit: $(COMMIT)"
@echo "Build Date: $(BUILD_DATE)"
@echo "Run ./$PROJECT_NAME version to verify"
@echo "Run ./gclone version to verify"

.PHONY: help
help:
@echo "$PROJECT_NAME Makefile"
@echo "GClone Makefile"
@echo "---------------"
@echo "Available targets:"
@echo " all - Clean and build $PROJECT_NAME"
@echo " build - Build the $PROJECT_NAME binary"
@echo " install - Install $PROJECT_NAME to your GOPATH/bin"
@echo " all - Clean and build gclone"
@echo " build - Build the gclone binary"
@echo " install - Install gclone to your GOPATH/bin"
@echo " clean - Remove built binary and dist directory"
@echo " test - Run tests"
@echo " lint - Run linters (requires golangci-lint)"
@echo " release - Create a full release using GoReleaser"
@echo " release-snapshot - Create a local release snapshot for testing (no publish)"
@echo " build-release - Build $PROJECT_NAME binary with release information"
@echo " build-release - Build gclone binary with release information"
@echo " help - Show this help message"
223 changes: 220 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,222 @@
# $PROJECT_NAME
# GClone - Git Repository Cloning Tool

Command description
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.

![demo](/demo/$PROJECT_NAME-demo.gif)
![demo](/demo/gclone-demo.gif)

## Features

- Clone repositories using different SSH configurations based on profiles
- Automatically applies Git configurations per profile (username, email, etc.)
- Supports different profile configurations for work, personal, and other accounts
- Colorful and easy-to-use CLI interface with a dedicated UI package

## Installation

```bash
# Clone the repository
git clone [email protected]:user-cube/gclone.git

# Build and install
cd gclone
go install
```

## Usage

### Initialize Configuration

```bash
# Initialize the default configuration
gclone init
```

This creates a configuration file at `~/.gclone/config.yml` with some sample profiles.

### Manage Profiles

```bash
# List all profiles
gclone profile list

# Add a new profile
gclone profile add personal --ssh-host=git-personal --git-username="Your Name" --git-email="[email protected]"

# Add a profile with URL patterns for automatic detection
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"

# Remove a profile
gclone profile remove personal
```

### Clone Repositories

```bash
# Clone a repository using a specific profile
gclone clone [email protected]:user/repo.git --profile=personal

# Clone with automatic profile detection based on URL patterns
gclone clone [email protected]:your-personal-username/repo.git
# GClone will automatically use the personal profile if the URL matches a configured pattern

# Clone with additional options
gclone clone [email protected]:user/repo.git my-repo --profile=work --depth=1 --branch=main
```

> **Note:** GClone only supports SSH URLs ([email protected]:user/repo.git format). HTTP/HTTPS URLs are not supported.

### View Configuration

```bash
# View the current configuration
gclone config
```

## How It Works

When you clone a repository with GClone, it:

1. Reads your profile configuration from `~/.gclone/config.yml`
2. Attempts to automatically detect the appropriate profile based on URL patterns
3. Transforms the repository URL to use the specified SSH host for that profile
4. Clones the repository using the modified URL
5. Applies any Git configurations specified in the profile to the cloned repository

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`.

> **Note:** GClone only works with SSH URLs in the format `[email protected]:user/repo.git`.

### URL Pattern Matching

GClone can automatically select the appropriate profile based on URL patterns. For example:

- If you have a personal profile with a URL pattern of `github.com/your-username`
- When you run `gclone clone [email protected]:your-username/repo.git`
- GClone will automatically use your personal profile without you needing to specify `--profile=personal`

## UI Package

GClone includes a dedicated UI package that provides consistent user interface components across the application. The UI package includes:

- **Colors**: Colorful output for different types of messages (success, info, warning, error)
- **Prompts**: Interactive prompts for user input (selection lists, confirmations, text input)
- **Operations**: Functions for displaying operation status and progress
- **Tables**: Simple text-based tables for displaying structured data
- **Spinners**: Progress indicators for long-running operations

### Using the UI Package

If you're developing for GClone, you can use the UI package in your code like this:

```go
import "github.com/user-cube/gclone/pkg/ui"

// Display colorful messages
ui.Success("Operation completed successfully")
ui.Info("Processing %s", ui.Highlight("important information"))
ui.Warning("This might take a while")
ui.Error("Error occurred: %v", err)

// Interactive prompts
selected, _ := ui.SelectFromList("Choose an option", []string{"Option 1", "Option 2"})
confirmed, _ := ui.Confirm("Are you sure?")
input, _ := ui.PromptInput("Enter your name", "", nil)

// Operation status
ui.OperationInfo("Cloning", "personal", map[string]string{
"URL": "[email protected]:user/repo.git",
})
ui.OperationSuccess("Repository cloned successfully")
```

See `examples/ui_examples.go` for more examples of using the UI package.

## Configuration

The configuration file is stored at `~/.gclone/config.yml` and has the following structure:

```yaml
profiles:
personal:
name: Personal
ssh_host: git-personal
url_patterns:
- github.com/your-personal-username
- github.com:your-personal-username
git_configs:
user.name: Your Name
user.email: [email protected]
work:
name: Work
ssh_host: git-work
url_patterns:
- github.com/your-work-organization
- github.com:your-work-organization
git_configs:
user.name: Your Work Name
user.email: [email protected]
```

## SSH Configuration

GClone can help you manage your SSH configurations automatically. For each profile, GClone can generate and maintain the necessary SSH host configuration.

### Using the SSH Config Command

GClone provides a built-in command to create or update SSH configurations:

```bash
# Generate SSH config for a specific profile
gclone ssh-config personal

# Or run without arguments to select from available profiles
gclone ssh-config
```

This command will:

1. Create a `~/.gclone/ssh_config` file with the SSH host configuration for your profile
2. Add an `Include ~/.gclone/ssh_config` directive to your main `~/.ssh/config` file if it doesn't exist

The generated configuration will look like this:

```
# personal profile (added by gclone)
Host github.com-personal
Hostname github.com
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/github_personal
```

### Manual Configuration

If you prefer to set up SSH configurations manually, you can add them directly to your `~/.ssh/config` file:

```
# Personal GitHub account
Host github.com-personal
Hostname github.com
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/github_personal

# Work GitHub account
Host github.com-work
Hostname github.com
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/github_work
```

In this example:

- `Host github.com-personal` defines the alias that matches the `ssh_host` in your GClone profile
- `Hostname github.com` specifies the actual Git server to connect to
- `IdentityFile ~/.ssh/github_personal` specifies which SSH key to use for this host

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.

## License

This project is licensed under the MIT License - see the LICENSE file for details.
Loading