-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
headyj
committed
Sep 30, 2020
0 parents
commit 9509272
Showing
15 changed files
with
1,026 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
giterate | ||
.DS_Store | ||
.vscode | ||
__debug_bin | ||
*.json | ||
*.yaml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
# Project | ||
Giterate is a wrapper that allows you to clone and pull multiple repositories from multiple providers with a single command | ||
|
||
## Configuration | ||
By default, giterate will use config.json or config.yaml file (in this order) in ~/.giterate folder | ||
Each git provider will have the same available parameters: | ||
|
||
- BaseURL: Base URL of the git provider | ||
- API: Type of api (can be gitlab, bitbucketv1, bitbucketv2 or github) | ||
- ApiURI: URI of the api | ||
- ApiToken: API token (required with ssh authentication) | ||
- CloneType: Type of authentication (can be ssh or http) | ||
- Username: username for authentication | ||
- Password: password for authentication | ||
- SSHPrivateKeyPath: absolute path to private key (required with ssh authentication) | ||
- Destination: default destination directory | ||
- Entities: List of repositories and groups to clone | ||
- Type: Type of entity, can be repository or group | ||
- Path: path to the entity (e.g. group, project, etc) | ||
- Name: name to the entity (e.g. name of the group, name of the repository) | ||
- Destination: destination absolute path. If not given, will take the default destination + path of entity | ||
- Recurse: in case of group, will clone recursively | ||
- CloneOptions: clone options array | ||
- Key: Name of the clone option | ||
- Value: Value of the clone option | ||
|
||
You can find an example of configuration file on this repository | ||
|
||
## Available services | ||
- Gitlab | ||
- Bitbucket V1 | ||
- Bitbucket V2 | ||
- Github | ||
|
||
## Available commands | ||
- [x] clone: clone repositories according to configuration file | ||
- if the repository already exists or is already clone, it will not be updated | ||
- parameters: | ||
- [ ] --force: will clean all an recreate from conf | ||
|
||
- [x] pull: pull repositories on current branches according to configuration file | ||
- if a new repository has been added to the configuration/to the git provider, it will not be cloned | ||
- parameters | ||
- [ ] --force: reset to configured branch | ||
|
||
- [x] status: check status of each git repositories according to configuration file | ||
|
||
- [ ] commit: check changes and ask for commit message in case of changes | ||
- if you don't provide any message, it will go to the next one without commiting | ||
- parameters | ||
- [ ] --target: target one or multiple repositories | ||
- [ ] -m: define a single message for all commits (you'll have to answer "yes" instead of providing a message) | ||
|
||
- [ ] push: check commited changes and ask for push | ||
- if you don't provide any message, it will go to the next one without commiting | ||
- parameters | ||
- [ ] --force: push without asking | ||
- [ ] --target: target one or multiple repositories | ||
|
||
## Global parameters | ||
- [x] --config-file: set json/yaml configuration file path | ||
|
||
## Roadmap | ||
[ ] tests | ||
[ ] commit command | ||
[ ] push command | ||
[ ] implement parameters |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
[ | ||
{ | ||
"BaseURL": "https://gitlab.*****.com", | ||
"API": "gitlab", | ||
"ApiURI": "/api/v4", | ||
"ApiToken": "******", | ||
"CloneType": "ssh", | ||
"SSHPrivateKeyPath": "/home/usr/.ssh/id_rsa", | ||
"Destination": "/home/usr/giterate/gitlab", | ||
"Entities": [ | ||
{ | ||
"Type": "repository", | ||
"Path": "link/to/repository", | ||
"Name": "repository_name", | ||
"Destination": "/home/usr/giterate/openjdk", | ||
"CloneOptions": [ | ||
{ | ||
"Name": "RemoteName", | ||
"Value": "master" | ||
} | ||
] | ||
}, | ||
{ | ||
"Type": "group", | ||
"Path": "link/to/group", | ||
"Name": "group_name", | ||
"Recurse": true | ||
} | ||
] | ||
}, | ||
{ | ||
"BaseURL": "https://git.*****.com", | ||
"API": "bitbucketv1", | ||
"ApiURI": "/rest", | ||
"CloneType": "http", | ||
"Username": "usr", | ||
"Password": "*****", | ||
"Destination": "/home/usr/giterate/bitbucketv1", | ||
"Entities": [ | ||
{ | ||
"Type": "repository", | ||
"Path": "group_name", | ||
"Name": "repository_name", | ||
"Destination": "/home/usr/giterate/bitbucketv1/repository_name" | ||
}, | ||
{ | ||
"Type": "group", | ||
"Name": "group_name" | ||
} | ||
] | ||
}, | ||
{ | ||
"BaseURL": "https://api.bitbucket.org", | ||
"API": "bitbucketv2", | ||
"ApiURI": "/2.0", | ||
"CloneType": "ssh", | ||
"Username": "usr", | ||
"SSHPrivateKeyPath": "/home/usr/.ssh/id_rsa", | ||
"Password": "*****", | ||
"Destination": "/home/usr/giterate/bitbucketv2", | ||
"Entities": [ | ||
{ | ||
"Type": "group", | ||
"Name": "group_name" | ||
} | ||
] | ||
}, | ||
{ | ||
"BaseURL": "https://github.com", | ||
"API": "github", | ||
"ApiURI": "/2.0", | ||
"CloneType": "none", | ||
"Destination": "/home/usr/giterate/github", | ||
"Entities": [ | ||
{ | ||
"Type": "group", | ||
"Name": "group_name" | ||
} | ||
] | ||
} | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
--- | ||
- BaseURL: https://gitlab.*****.com | ||
API: gitlab | ||
ApiURI: "/api/v4" | ||
ApiToken: "******" | ||
CloneType: ssh | ||
SSHPrivateKeyPath: "/home/usr/.ssh/id_rsa" | ||
Destination: "/home/usr/giterate/gitlab" | ||
Entities: | ||
- Type: repository | ||
Path: link/to/repository | ||
Name: repository_name | ||
Destination: "/home/usr/giterate/openjdk" | ||
CloneOptions: | ||
- Name: RemoteName | ||
Value: master | ||
- Type: group | ||
Path: link/to/group | ||
Name: group_name | ||
Recurse: true | ||
- BaseURL: https://git.*****.com | ||
API: bitbucketv1 | ||
ApiURI: "/rest" | ||
CloneType: http | ||
Username: usr | ||
Password: "*****" | ||
Destination: "/home/usr/giterate/bitbucketv1" | ||
Entities: | ||
- Type: repository | ||
Path: group_name | ||
Name: repository_name | ||
Destination: "/home/usr/giterate/bitbucketv1/repository_name" | ||
- Type: group | ||
Name: group_name | ||
- BaseURL: https://api.bitbucket.org | ||
API: bitbucketv2 | ||
ApiURI: "/2.0" | ||
CloneType: ssh | ||
Username: usr | ||
SSHPrivateKeyPath: "/home/usr/.ssh/id_rsa" | ||
Password: "*****" | ||
Destination: "/home/usr/giterate/bitbucketv2" | ||
Entities: | ||
- Type: group | ||
Name: group_name | ||
- BaseURL: https://github.com | ||
API: github | ||
ApiURI: "/2.0" | ||
CloneType: none | ||
Destination: "/home/usr/giterate/github" | ||
Entities: | ||
- Type: group | ||
Name: group_name |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package main | ||
|
||
import ( | ||
command "giterate/pkg/commands" | ||
"log" | ||
"os" | ||
|
||
"github.com/mitchellh/cli" | ||
) | ||
|
||
func main() { | ||
args := os.Args[1:] | ||
cli := cli.CLI{ | ||
Args: args, | ||
Commands: Commands, | ||
HelpFunc: cli.BasicHelpFunc("giterate"), | ||
Version: "0.1", | ||
} | ||
|
||
status, err := cli.Run() | ||
if err != nil { | ||
log.Fatalf("Cannot run command: %s", err) | ||
} | ||
|
||
os.Exit(status) | ||
|
||
} | ||
|
||
var Commands map[string]cli.CommandFactory | ||
|
||
func init() { | ||
ui := &cli.BasicUi{Writer: os.Stdout} | ||
|
||
Commands = map[string]cli.CommandFactory{ | ||
"clone": func() (cli.Command, error) { | ||
return &command.CloneCommand{ | ||
Ui: ui, | ||
}, nil | ||
}, | ||
"pull": func() (cli.Command, error) { | ||
return &command.PullCommand{ | ||
Ui: ui, | ||
}, nil | ||
}, | ||
"status": func() (cli.Command, error) { | ||
return &command.StatusCommand{ | ||
Ui: ui, | ||
}, nil | ||
}, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package command | ||
|
||
type Arguments struct { | ||
ConfigFile string | ||
} | ||
|
||
func (a *Arguments) process(args []string) *Arguments { | ||
for i, v := range args { | ||
switch v { | ||
case "--config-file": | ||
a.ConfigFile = args[i+1] | ||
} | ||
} | ||
return a | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
package command | ||
|
||
import ( | ||
"fmt" | ||
"giterate/pkg/entities" | ||
"log" | ||
"os" | ||
"strings" | ||
|
||
"github.com/go-git/go-git" | ||
"github.com/go-git/go-git/plumbing/transport" | ||
"github.com/go-git/go-git/plumbing/transport/http" | ||
"github.com/go-git/go-git/plumbing/transport/ssh" | ||
"github.com/mitchellh/cli" | ||
) | ||
|
||
type CloneCommand struct { | ||
Ui cli.Ui | ||
Arguments | ||
} | ||
|
||
func (c *CloneCommand) Run(args []string) int { | ||
file := initConf(c.Arguments.process(args)) | ||
services := entities.PopulateRepositories(file) | ||
Clone(services) | ||
//servicesJSON, _ := json.Marshal(services) | ||
//fmt.Printf("%s", servicesJSON) | ||
return 0 | ||
} | ||
|
||
func (c *CloneCommand) Help() string { | ||
helpText := ` | ||
Usage: giterate clone [options] | ||
Clone repositories accordint to configuration file | ||
By default, giterate will use config.json or config.yaml file (in this order) in ~/.giterate/ folder | ||
Options: | ||
--config-file set json/yaml configuration file path | ||
` | ||
|
||
return strings.TrimSpace(helpText) | ||
} | ||
|
||
func (c *CloneCommand) Synopsis() string { | ||
return "clone repositories according to configuration file" | ||
} | ||
|
||
func Clone(services []entities.Service) { | ||
for _, service := range services { | ||
var cloneOptions = git.CloneOptions{Progress: os.Stdout} | ||
if service.SSHPrivateKeyPath != "" { | ||
publicKeys, err := ssh.NewPublicKeysFromFile("git", service.SSHPrivateKeyPath, "") | ||
if err != nil { | ||
log.Fatalf("Cannot get public key: %s", err) | ||
} | ||
cloneOptions.Auth = publicKeys | ||
} else if service.Username != "" && service.Password != "" { | ||
cloneOptions.Auth = &http.BasicAuth{ | ||
Username: service.Username, | ||
Password: service.Password, | ||
} | ||
} | ||
for _, repository := range service.Repositories { | ||
cloneOptions.URL = repository.URL | ||
if repository.CloneOptions != nil { | ||
entities.ProcessCloneOptions(&repository.CloneOptions, &cloneOptions) | ||
} | ||
fmt.Println("[INFO] Cloning " + repository.URL + "...") | ||
_, err := git.PlainClone(repository.Destination, false, &cloneOptions) | ||
if err != nil { | ||
if err == transport.ErrEmptyRemoteRepository || err == git.ErrRepositoryAlreadyExists { | ||
fmt.Println("[INFO] Repository already cloned, ignoring...") | ||
continue | ||
} else { | ||
log.Fatalf("Cannot clone repository: %s", err) | ||
} | ||
} else { | ||
fmt.Println("[INFO] Cloned " + repository.URL + "...") | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.