refactor config loader and add github config

This commit is contained in:
Massaki Archambault 2024-08-04 15:44:50 -04:00
parent dca46e8c69
commit abf8507673
15 changed files with 263 additions and 96 deletions

View File

@ -6,6 +6,10 @@ fs:
# See mount.fuse(8) for the full list of options.
#mountoptions: nodev,nosuid
# The git platform to use as the backend.
# Must be one of "gitlab", or "github"
platform: gitlab
gitlab:
# The gitlab url.
url: https://gitlab.com
@ -16,7 +20,7 @@ gitlab:
# Must be set to either "http" or "ssh".
# The protocol to configure the git remote on.
# "http" may not work on private repos unless a credential manager is configured
# "http" may not work on private projects unless a credential manager is configured
# If possible, prefer "ssh" over "http"
pull_method: http
@ -28,7 +32,7 @@ gitlab:
user_ids: []
# Set how archived projects are handled.
# If set to "show", it will add them to the filesystem and treat them like any other repository
# If set to "show", it will add them to the filesystem and treat them like any other project
# If set to "hide", it will add them to the filesystem, but prefix the symlink with a "."
# If set to "ignore", it will make them absent from the filesystem
# Default to "hide"
@ -37,6 +41,35 @@ gitlab:
# If set to true, the user the api token belongs to will automatically be added to the list of users exposed by the filesystem.
include_current_user: true
github:
# The github api token
# Default to anonymous (only public repositories will be visible)
#token:
# Must be set to either "http" or "ssh".
# The protocol to configure the git remote on.
# "http" may not work on private repositories unless a credential manager is configured
# If possible, prefer "ssh" over "http"
pull_method: http
# A list of the name of the organizations to expose in the filesystem
org_names: []
# A list of the name of the user to expose their repositories un the filesystem
user_names: []
# Set how archived repositories are handled.
# If set to "show", it will add them to the filesystem and treat them like any other repository
# If set to "hide", it will add them to the filesystem, but prefix the symlink with a "."
# If set to "ignore", it will make them absent from the filesystem
# Default to "hide"
archived_repo_handling: hide
# If set to true, the personal repositories and the repositories of the organizations the user the api token belongs to
# will be automatically be added to the list of users exposed by the filesystem.
include_current_user: true
git:
# Path to the local repository cache. Repositories in the filesystem will symlink to a folder in this path.
# Default to $XDG_DATA_HOME/gitlabfs, or $HOME/.local/share/gitlabfs if the environment variable $XDG_DATA_HOME is unset.

View File

@ -1,19 +1,31 @@
fs:
mountpoint: /tmp/gitlabfs/test/mnt
mountpoint: /tmp/gitlabfs/test/mnt/gitlab
mountoptions: nodev
platform: gitlab
gitlab:
url: https://example.com
token: "12345"
pull_method: ssh
group_ids:
- 123
user_ids:
- 456
archived_project_handling: hide
include_current_user: true
github:
token: "12345"
pull_method: http
org_names:
- test-org
user_names:
- test-user
archived_repo_handling: hide
include_current_user: true
pull_method: ssh
git:
clone_location: /tmp/gitlabfs/test/clone
clone_location: /tmp/gitlabfs/test/cache/gitlab
remote: origin
on_clone: clone
auto_pull: false

View File

@ -5,20 +5,62 @@ import (
"os"
"path/filepath"
"github.com/badjware/gitlabfs/git"
"github.com/badjware/gitlabfs/platforms/gitlab"
"gopkg.in/yaml.v2"
)
const (
PlatformGitlab = "gitlab"
PlatformGithub = "github"
PullMethodHTTP = "http"
PullMethodSSH = "ssh"
ArchivedProjectShow = "show"
ArchivedProjectHide = "hide"
ArchivedProjectIgnore = "ignore"
)
type (
Config struct {
FS FSConfig `yaml:"fs,omitempty"`
Gitlab gitlab.GitlabClientConfig `yaml:"gitlab,omitempty"`
Git git.GitClientParam `yaml:"git,omitempty"`
Gitlab GitlabClientConfig `yaml:"gitlab,omitempty"`
Github GithubClientConfig `yaml:"github,omitempty"`
Git GitClientConfig `yaml:"git,omitempty"`
}
FSConfig struct {
Mountpoint string `yaml:"mountpoint,omitempty"`
MountOptions string `yaml:"mountoptions,omitempty"`
Platform string `yaml:"platform,omitempty"`
}
GitlabClientConfig struct {
URL string `yaml:"url,omitempty"`
Token string `yaml:"token,omitempty"`
GroupIDs []int `yaml:"group_ids,omitempty"`
UserIDs []int `yaml:"user_ids,omitempty"`
ArchivedProjectHandling string `yaml:"archived_project_handling,omitempty"`
IncludeCurrentUser bool `yaml:"include_current_user,omitempty"`
PullMethod string `yaml:"pull_method,omitempty"`
}
GithubClientConfig struct {
Token string `yaml:"token,omitempty"`
OrgNames []string `yaml:"org_names,omitempty"`
UserNames []string `yaml:"user_names,omitempty"`
ArchivedRepoHandling string `yaml:"archived_repo_handling,omitempty"`
IncludeCurrentUser bool `yaml:"include_current_user,omitempty"`
PullMethod string `yaml:"pull_method,omitempty"`
}
GitClientConfig struct {
CloneLocation string `yaml:"clone_location,omitempty"`
Remote string `yaml:"remote,omitempty"`
OnClone string `yaml:"on_clone,omitempty"`
AutoPull bool `yaml:"auto_pull,omitempty"`
Depth int `yaml:"depth,omitempty"`
QueueSize int `yaml:"queue_size,omitempty"`
QueueWorkerCount int `yaml:"worker_count,omitempty"`
}
)
@ -34,8 +76,9 @@ func LoadConfig(configPath string) (*Config, error) {
FS: FSConfig{
Mountpoint: "",
MountOptions: "nodev,nosuid",
Platform: "",
},
Gitlab: gitlab.GitlabClientConfig{
Gitlab: GitlabClientConfig{
URL: "https://gitlab.com",
Token: "",
PullMethod: "http",
@ -44,7 +87,15 @@ func LoadConfig(configPath string) (*Config, error) {
ArchivedProjectHandling: "hide",
IncludeCurrentUser: true,
},
Git: git.GitClientParam{
Github: GithubClientConfig{
Token: "",
PullMethod: "http",
OrgNames: []string{},
UserNames: []string{},
ArchivedRepoHandling: "hide",
IncludeCurrentUser: true,
},
Git: GitClientConfig{
CloneLocation: defaultCloneLocation,
Remote: "origin",
OnClone: "init",
@ -68,28 +119,47 @@ func LoadConfig(configPath string) (*Config, error) {
}
}
// validate platform is set
if config.FS.Platform != PlatformGithub && config.FS.Platform != PlatformGitlab {
return nil, fmt.Errorf("fs.platform must be either \"%v\", or \"%v\"", PlatformGitlab, PlatformGithub)
}
return config, nil
}
func MakeGitConfig(config *Config) (*git.GitClientParam, error) {
// parse on_clone
if config.Git.OnClone != "init" && config.Git.OnClone != "clone" {
return nil, fmt.Errorf("on_clone must be either \"init\" or \"clone\"")
}
return &config.Git, nil
}
func MakeGitlabConfig(config *Config) (*gitlab.GitlabClientConfig, error) {
func MakeGitlabConfig(config *Config) (*GitlabClientConfig, error) {
// parse pull_method
if config.Gitlab.PullMethod != gitlab.PullMethodHTTP && config.Gitlab.PullMethod != gitlab.PullMethodSSH {
return nil, fmt.Errorf("pull_method must be either \"%v\" or \"%v\"", gitlab.PullMethodHTTP, gitlab.PullMethodSSH)
if config.Gitlab.PullMethod != PullMethodHTTP && config.Gitlab.PullMethod != PullMethodSSH {
return nil, fmt.Errorf("gitlab.pull_method must be either \"%v\" or \"%v\"", PullMethodHTTP, PullMethodSSH)
}
// parse archive_handing
if config.Gitlab.ArchivedProjectHandling != gitlab.ArchivedProjectShow && config.Gitlab.ArchivedProjectHandling != gitlab.ArchivedProjectHide && config.Gitlab.ArchivedProjectHandling != gitlab.ArchivedProjectIgnore {
return nil, fmt.Errorf("pull_method must be either \"%v\", \"%v\" or \"%v\"", gitlab.ArchivedProjectShow, gitlab.ArchivedProjectHide, gitlab.ArchivedProjectIgnore)
if config.Gitlab.ArchivedProjectHandling != ArchivedProjectShow && config.Gitlab.ArchivedProjectHandling != ArchivedProjectHide && config.Gitlab.ArchivedProjectHandling != ArchivedProjectIgnore {
return nil, fmt.Errorf("gitlab.archived_project_handling must be either \"%v\", \"%v\" or \"%v\"", ArchivedProjectShow, ArchivedProjectHide, ArchivedProjectIgnore)
}
return &config.Gitlab, nil
}
func MakeGithubConfig(config *Config) (*GithubClientConfig, error) {
// parse pull_method
if config.Gitlab.PullMethod != PullMethodHTTP && config.Gitlab.PullMethod != PullMethodSSH {
return nil, fmt.Errorf("github.pull_method must be either \"%v\" or \"%v\"", PullMethodHTTP, PullMethodSSH)
}
// parse archive_handing
if config.Gitlab.ArchivedProjectHandling != ArchivedProjectShow && config.Gitlab.ArchivedProjectHandling != ArchivedProjectHide && config.Gitlab.ArchivedProjectHandling != ArchivedProjectIgnore {
return nil, fmt.Errorf("github.archived_repo_handling must be either \"%v\", \"%v\" or \"%v\"", ArchivedProjectShow, ArchivedProjectHide, ArchivedProjectIgnore)
}
return &config.Github, nil
}
func MakeGitConfig(config *Config) (*GitClientConfig, error) {
// parse on_clone
if config.Git.OnClone != "init" && config.Git.OnClone != "clone" {
return nil, fmt.Errorf("git.on_clone must be either \"init\" or \"clone\"")
}
return &config.Git, nil
}

View File

@ -5,8 +5,6 @@ import (
"testing"
"github.com/badjware/gitlabfs/config"
"github.com/badjware/gitlabfs/git"
"github.com/badjware/gitlabfs/platforms/gitlab"
)
func TestLoadConfig(t *testing.T) {
@ -18,10 +16,11 @@ func TestLoadConfig(t *testing.T) {
input: "config.test.yaml",
expected: &config.Config{
FS: config.FSConfig{
Mountpoint: "/tmp/gitlabfs/test/mnt",
Mountpoint: "/tmp/gitlabfs/test/mnt/gitlab",
MountOptions: "nodev",
Platform: "gitlab",
},
Gitlab: gitlab.GitlabClientConfig{
Gitlab: config.GitlabClientConfig{
URL: "https://example.com",
Token: "12345",
PullMethod: "ssh",
@ -30,8 +29,16 @@ func TestLoadConfig(t *testing.T) {
ArchivedProjectHandling: "hide",
IncludeCurrentUser: true,
},
Git: git.GitClientParam{
CloneLocation: "/tmp/gitlabfs/test/clone",
Github: config.GithubClientConfig{
Token: "12345",
PullMethod: "http",
OrgNames: []string{"test-org"},
UserNames: []string{"test-user"},
ArchivedRepoHandling: "hide",
IncludeCurrentUser: true,
},
Git: config.GitClientConfig{
CloneLocation: "/tmp/gitlabfs/test/cache/gitlab",
Remote: "origin",
OnClone: "clone",
AutoPull: false,
@ -58,11 +65,14 @@ func TestLoadConfig(t *testing.T) {
func TestMakeGitConfig(t *testing.T) {
tests := map[string]struct {
input *config.Config
expected *git.GitClientParam
expected *config.GitClientConfig
}{
"ValidConfig": {
input: &config.Config{
Git: git.GitClientParam{
FS: config.FSConfig{
Platform: "gitlab",
},
Git: config.GitClientConfig{
CloneLocation: "/tmp",
Remote: "origin",
OnClone: "init",
@ -72,7 +82,7 @@ func TestMakeGitConfig(t *testing.T) {
QueueWorkerCount: 5,
},
},
expected: &git.GitClientParam{
expected: &config.GitClientConfig{
CloneLocation: "/tmp",
Remote: "origin",
OnClone: "init",
@ -84,7 +94,10 @@ func TestMakeGitConfig(t *testing.T) {
},
"InvalidOnClone": {
input: &config.Config{
Git: git.GitClientParam{
FS: config.FSConfig{
Platform: "gitlab",
},
Git: config.GitClientConfig{
CloneLocation: "/tmp",
Remote: "origin",
OnClone: "invalid",
@ -114,11 +127,14 @@ func TestMakeGitConfig(t *testing.T) {
func TestMakeGitlabConfig(t *testing.T) {
tests := map[string]struct {
input *config.Config
expected *gitlab.GitlabClientConfig
expected *config.GitlabClientConfig
}{
"ValidConfig": {
input: &config.Config{
Gitlab: gitlab.GitlabClientConfig{
FS: config.FSConfig{
Platform: "gitlab",
},
Gitlab: config.GitlabClientConfig{
URL: "https://gitlab.com",
PullMethod: "http",
Token: "",
@ -128,7 +144,7 @@ func TestMakeGitlabConfig(t *testing.T) {
IncludeCurrentUser: true,
},
},
expected: &gitlab.GitlabClientConfig{
expected: &config.GitlabClientConfig{
URL: "https://gitlab.com",
PullMethod: "http",
Token: "",
@ -140,7 +156,10 @@ func TestMakeGitlabConfig(t *testing.T) {
},
"InvalidPullMethod": {
input: &config.Config{
Gitlab: gitlab.GitlabClientConfig{
FS: config.FSConfig{
Platform: "gitlab",
},
Gitlab: config.GitlabClientConfig{
URL: "https://gitlab.com",
PullMethod: "invalid",
Token: "",
@ -154,7 +173,7 @@ func TestMakeGitlabConfig(t *testing.T) {
},
"InvalidArchiveHandling": {
input: &config.Config{
Gitlab: gitlab.GitlabClientConfig{
Gitlab: config.GitlabClientConfig{
URL: "https://gitlab.com",
PullMethod: "http",
Token: "",

View File

@ -10,24 +10,15 @@ import (
"strconv"
"time"
"github.com/badjware/gitlabfs/config"
"github.com/badjware/gitlabfs/fstree"
"github.com/badjware/gitlabfs/utils"
"github.com/vmihailenco/taskq/v3"
"github.com/vmihailenco/taskq/v3/memqueue"
)
type GitClientParam struct {
CloneLocation string `yaml:"clone_location,omitempty"`
Remote string `yaml:"remote,omitempty"`
OnClone string `yaml:"on_clone,omitempty"`
AutoPull bool `yaml:"auto_pull,omitempty"`
Depth int `yaml:"depth,omitempty"`
QueueSize int `yaml:"queue_size,omitempty"`
QueueWorkerCount int `yaml:"worker_count,omitempty"`
}
type gitClient struct {
GitClientParam
config.GitClientConfig
logger *slog.Logger
@ -42,11 +33,11 @@ type gitClient struct {
pullTask *taskq.Task
}
func NewClient(logger *slog.Logger, p GitClientParam) (*gitClient, error) {
func NewClient(logger *slog.Logger, p config.GitClientConfig) (*gitClient, error) {
queueFactory := memqueue.NewFactory()
// Create the client
c := &gitClient{
GitClientParam: p,
GitClientConfig: p,
logger: logger,

View File

@ -8,7 +8,7 @@ import (
)
func (c *gitClient) clone(url string, defaultBranch string, dst string) error {
if c.GitClientParam.OnClone == "init" {
if c.GitClientConfig.OnClone == "init" {
// "Fake" cloning the repo by never actually talking to the git server
// This skip a fetch operation that we would do if we where to do a proper clone
// We can save a lot of time and network i/o doing it this way, at the cost of
@ -40,7 +40,7 @@ func (c *gitClient) clone(url string, defaultBranch string, dst string) error {
"git", "remote", "add",
"-m", defaultBranch,
"--",
c.GitClientParam.Remote, // name
c.GitClientConfig.Remote, // name
url, // url
)
if err != nil {
@ -54,7 +54,7 @@ func (c *gitClient) clone(url string, defaultBranch string, dst string) error {
"git", "config", "--local",
"--",
fmt.Sprintf("branch.%s.remote", defaultBranch), // key
c.GitClientParam.Remote, // value
c.GitClientConfig.Remote, // value
)
if err != nil {
@ -77,10 +77,10 @@ func (c *gitClient) clone(url string, defaultBranch string, dst string) error {
c.logger.Info("Cloning git repository", "directory", dst, "repository", url)
args := []string{
"clone",
"--origin", c.GitClientParam.Remote,
"--origin", c.GitClientConfig.Remote,
}
if c.GitClientParam.Depth != 0 {
args = append(args, "--depth", strconv.Itoa(c.GitClientParam.Depth))
if c.GitClientConfig.Depth != 0 {
args = append(args, "--depth", strconv.Itoa(c.GitClientConfig.Depth))
}
args = append(args,
"--",

View File

@ -24,12 +24,12 @@ func (c *gitClient) pull(repoPath string, defaultBranch string) error {
args := []string{
"pull",
}
if c.GitClientParam.Depth != 0 {
args = append(args, "--depth", strconv.Itoa(c.GitClientParam.Depth))
if c.GitClientConfig.Depth != 0 {
args = append(args, "--depth", strconv.Itoa(c.GitClientConfig.Depth))
}
args = append(args,
"--",
c.GitClientParam.Remote, // repository
c.GitClientConfig.Remote, // repository
defaultBranch, // refspec
)

1
go.mod
View File

@ -18,6 +18,7 @@ require (
github.com/go-redis/redis/v8 v8.11.4 // indirect
github.com/go-redis/redis_rate/v9 v9.1.2 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/go-github/v63 v63.0.0 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
github.com/hashicorp/go-retryablehttp v0.6.8 // indirect

2
go.sum
View File

@ -114,6 +114,8 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-github/v63 v63.0.0 h1:13xwK/wk9alSokujB9lJkuzdmQuVn2QCPeck76wR3nE=
github.com/google/go-github/v63 v63.0.0/go.mod h1:IqbcrgUmIcEaioWrGYei/09o+ge5vhffGOcxrO0AfmA=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=

16
main.go
View File

@ -10,6 +10,7 @@ import (
"github.com/badjware/gitlabfs/config"
"github.com/badjware/gitlabfs/fstree"
"github.com/badjware/gitlabfs/git"
"github.com/badjware/gitlabfs/platforms/github"
"github.com/badjware/gitlabfs/platforms/gitlab"
)
@ -64,20 +65,31 @@ func main() {
}
gitClient, _ := git.NewClient(logger, *gitClientParam)
var gitPlatformClient fstree.GitPlatform
if loadedConfig.FS.Platform == config.PlatformGitlab {
// Create the gitlab client
GitlabClientConfig, err := config.MakeGitlabConfig(loadedConfig)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
gitlabClient, _ := gitlab.NewClient(logger, loadedConfig.Gitlab.URL, loadedConfig.Gitlab.Token, *GitlabClientConfig)
gitPlatformClient, _ = gitlab.NewClient(logger, loadedConfig.Gitlab.URL, loadedConfig.Gitlab.Token, *GitlabClientConfig)
} else if loadedConfig.FS.Platform == config.PlatformGithub {
// Create the github client
GithubClientConfig, err := config.MakeGithubConfig(loadedConfig)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
gitPlatformClient, _ = github.NewClient(logger, *GithubClientConfig)
}
// Start the filesystem
err = fstree.Start(
logger,
mountpoint,
parsedMountoptions,
&fstree.FSParam{GitClient: gitClient, GitPlatform: gitlabClient},
&fstree.FSParam{GitClient: gitClient, GitPlatform: gitPlatformClient},
*debug,
)
if err != nil {

View File

@ -0,0 +1,42 @@
package github
import (
"log/slog"
"github.com/badjware/gitlabfs/config"
"github.com/badjware/gitlabfs/fstree"
"github.com/google/go-github/v63/github"
)
type githubClient struct {
config.GithubClientConfig
client *github.Client
logger *slog.Logger
rootContent map[string]fstree.GroupSource
}
func NewClient(logger *slog.Logger, config config.GithubClientConfig) (*githubClient, error) {
client := github.NewClient(nil)
if config.Token != "" {
client = client.WithAuthToken(config.Token)
}
gitHubClient := &githubClient{
GithubClientConfig: config,
client: client,
logger: logger,
}
return gitHubClient, nil
}
func (c *githubClient) FetchRootGroupContent() (map[string]fstree.GroupSource, error) {
return nil, nil
}
func (c *githubClient) FetchGroupContent(gid uint64) (map[string]fstree.GroupSource, map[string]fstree.RepositorySource, error) {
return nil, nil, nil
}

View File

@ -0,0 +1 @@
package github

1
platforms/github/user.go Normal file
View File

@ -0,0 +1 @@
package github

View File

@ -6,31 +6,13 @@ import (
"slices"
"sync"
"github.com/badjware/gitlabfs/config"
"github.com/badjware/gitlabfs/fstree"
"github.com/xanzy/go-gitlab"
)
const (
PullMethodHTTP = "http"
PullMethodSSH = "ssh"
ArchivedProjectShow = "show"
ArchivedProjectHide = "hide"
ArchivedProjectIgnore = "ignore"
)
type GitlabClientConfig struct {
URL string `yaml:"url,omitempty"`
Token string `yaml:"token,omitempty"`
GroupIDs []int `yaml:"group_ids,omitempty"`
UserIDs []int `yaml:"user_ids,omitempty"`
ArchivedProjectHandling string `yaml:"archived_project_handling,omitempty"`
IncludeCurrentUser bool `yaml:"include_current_user,omitempty"`
PullMethod string `yaml:"pull_method,omitempty"`
}
type gitlabClient struct {
GitlabClientConfig
config.GitlabClientConfig
client *gitlab.Client
logger *slog.Logger
@ -46,7 +28,7 @@ type gitlabClient struct {
userCache map[int]*User
}
func NewClient(logger *slog.Logger, gitlabUrl string, gitlabToken string, p GitlabClientConfig) (*gitlabClient, error) {
func NewClient(logger *slog.Logger, gitlabUrl string, gitlabToken string, p config.GitlabClientConfig) (*gitlabClient, error) {
client, err := gitlab.NewClient(
gitlabToken,
gitlab.WithBaseURL(gitlabUrl),

View File

@ -3,6 +3,7 @@ package gitlab
import (
"path"
"github.com/badjware/gitlabfs/config"
"github.com/xanzy/go-gitlab"
)
@ -27,7 +28,7 @@ func (p *Project) GetDefaultBranch() string {
func (c *gitlabClient) newProjectFromGitlabProject(project *gitlab.Project) *Project {
// https://godoc.org/github.com/xanzy/go-gitlab#Project
if c.ArchivedProjectHandling == ArchivedProjectIgnore && project.Archived {
if c.ArchivedProjectHandling == config.ArchivedProjectIgnore && project.Archived {
return nil
}
p := Project{
@ -38,12 +39,12 @@ func (c *gitlabClient) newProjectFromGitlabProject(project *gitlab.Project) *Pro
if p.DefaultBranch == "" {
p.DefaultBranch = "master"
}
if c.PullMethod == PullMethodSSH {
if c.PullMethod == config.PullMethodSSH {
p.CloneURL = project.SSHURLToRepo
} else {
p.CloneURL = project.HTTPURLToRepo
}
if c.ArchivedProjectHandling == ArchivedProjectHide && project.Archived {
if c.ArchivedProjectHandling == config.ArchivedProjectHide && project.Archived {
p.Path = path.Join(path.Dir(p.Path), "."+path.Base(p.Path))
}
return &p