Skip to content
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

Several gitlab providers #151

Open
albfan opened this issue May 12, 2018 · 17 comments
Open

Several gitlab providers #151

albfan opened this issue May 12, 2018 · 17 comments
Projects

Comments

@albfan
Copy link

albfan commented May 12, 2018

I have repos in gitlab.com and gitlab.gnome.org.

I take a look into ~/.config/lab.hcl and seems there's only a core section, with host, user and token

Is it possible to manage several gitlab providers?

@zaquestion
Copy link
Owner

😆 I knew this day would come !!

@albfan This isn't currently supported by lab, but its actually something I've been thinking about a lot lately, but my only use case was for testing. Here's what I've been kicking around, LMK what you think

In the case you want to manually switch (add on first use) to the "default" profile.

lab meta use <profile> # or
lab meta profile <profile> 

Ideally though lab does the magic to

  • identify provider during clone
    • fork relative to forkFromRepo (origin/upstream)
  • clone and setup remotes
    • all possible remotes? In the case where a project is pushed to multiple gitlab instances
  • Uses the right profile for the remote for all API calls

Config wise that essentially means making core an array which is easy enough and back compatible. We could also consider a phased change to the structure or even just renaming to profiles perhaps

@zaquestion
Copy link
Owner

Side note: idea with lab meta is to bundle some of the more abstract operations including the gitlab locking functionality lab meta lock <file> and lab meta unlock <file> which still haven't found a home.

@albfan
Copy link
Author

albfan commented May 13, 2018

So it would be like:

"profiles" = [
  {
    "host" = "https://gitlab.com"
    "token" = "blablabla"
    "user" = "albfan"
  },
  {
    "host" = "https://gitlab.gnome.org"
    "token" = "blablabla"
    "user" = "albfan"
  },
]

The lab meta profile sounds good to me: I suppose it will be a default key in that array, but most of the time it would not be needed.

I think that we can add an alias, so you can refer to it in commands with an option like -p --profile

So this will be the config:

"profiles" = [
  {
    "host" = "https://gitlab.com"
    "token" = "blablabla"
    "user" = "albfan"
    "alias" = "gitlab"
  },
  {
    "host" = "https://gitlab.gnome.org"
    "token" = "blablabla"
    "user" = "albfan"
    "alias" = "gnome"
    "default" = "yes"
  },
]

This will be the commands:

$ cd /repo/on/gitlab.gnome.org
$ lab issue create (creates on gitlab.gnome.org)

$ cd repo/on/gitlab.com
$ lab issue list (list on gitlab.com)

$ cd re/with/mixed/remotes
$ lab meta use gitlab (selecting profile)
$ lab issue create (first upstream remote, then origin remote, then first profile in lab config)
$ lab -p gnome issue create (specific profile directly)

Maybe an option to choose profile based on configured profile or based on remote name is expected. It would live in core

"core" = {
  "useRemoteToChooseProfile" = "no"
}

Let me know if you find gaps in this analysis

@fauust
Copy link

fauust commented May 15, 2018

Hi,
why don't you use a ./lab.hcl file for every project (and ignore it with .gitignore)?

@albfan
Copy link
Author

albfan commented May 15, 2018

@fauust That would work (don't know if lab reads on repo directory before look for global file.

But as you create an access token for every gitlab provider, seems a boilerplate workaround.

I'm ok with workarounds, @zaquestion is that an option?

@zaquestion
Copy link
Owner

@albfan, indeed it's true, lab will look in the current directory for a config first before looking for the global one. Thinking about it more, that should probably be the current git dir so it will work anywhere in the repo

@albfan
Copy link
Author

albfan commented Jul 12, 2018

Nice!

@nkprince007
Copy link
Contributor

I like the way how hub mitigates this problem with GitHub's enterprise version by using multiple hosts within the config. IMO, it'd be super cool to have lab autodetect the host from the list of hosts in configuration and use it based on the the default remote of current repo.

@joshtriplett
Copy link

Ideally, lab clone would automatically detect the host and use a corresponding config, without having to create one manually.

@zaquestion
Copy link
Owner

Just to get hopes up -- Im facing this now as well, so I'll probably try to tackle this soon.

@0xjac
Copy link

0xjac commented Nov 19, 2018

I would like to suggest implementing something similar to git's config include logic.
Namely, include, and specifically conditional includes.

This is how I use it for git config (and it would be awesome to replicate for lab):
I have a main ~/code dir which contains all of the projects I work on with the following structure:

~/code
├── <some FOSS project>
├── <some other FOSS project>
├── <company_name>
│   ├── .gitconfig
│   ├── company-backend
│   └── company-frontend
└── <some FOSS with custom hosting>
    ├── .gitconfig
    ├── <foss-module1>
    └── <foss-module1>
  • All the projects in the root ~/code are on gitlab.com and github.com.
  • Anything in <Company name> is hosted on the company's private Gitlab instance and commits are made with my company email address
  • Anything in <Some FOSS with custom hosting> is on a separate Gitlab instance used by that open source project (such as the previously mentioned gitlab.gnome.org)

To achieve different configurations, I have a main git config file (~/.gitconfig) which includes conditional includes for the dirs in ~/code:

[user]
    name = Jacques Dafflon
    email = jacques@dafflon.tech
[includeIf "gitdir:~/code/<company_name>/*"]
    path = ~/code/<company_name>/.gitconfig
[includeIf "gitdir:~/code/<some FOSS with custom hosting>/*"]
    path = ~/code/<some FOSS with custom hosting>/.gitconfig

Then in ~/code/<company_name>/.gitconfig, I have:

[user]
name = Jacques Dafflon
email = jacques@company_name.com

and similarly for ~/code/<some FOSS with custom hosting>/.gitconfig.

Note that this scheme is flexible enough such that:

  • People can have the custom config files at other location (for example ~/.gitconfig-<company_name> instead of ~/code/<company_name>/.gitconfig)
  • The projects don't need to necessarly be organized in sub-folders but can use prefix/suffix instead such as ~/code/company_name-backend and [includeIf "gitdir:~/code/<company_name>-*"].
    You can do anything else if you can write the regex for it.

Hub uses something similar directly in the .gitconfig and hopefully a similar approach should be fairly easy to implement in lab since git is doing most of the heavy-lifting.

Lab is a really cool project and I would love to see this feature added.

@reneroth
Copy link

reneroth commented Nov 28, 2018

Semi-helpful: for now, I'm using different files in the .config folder (lab.gitlab.com.hcl, lab.client-server.com.hcl…) and a bash function lab-use

lab-use () {
  cp ~/.config/lab.$1.hcl ~/.config/lab.hcl
}

so I'll simply do lab-use gitlab.com or lab-use client-server.com to switch between contexts. imo a better solution than having to put a config file into every single project root.

What could work okay too is if lab would traverse the directory root upwards until it finds a lab.hcl file.

@0xjac
Copy link

0xjac commented Nov 29, 2018

@reneroth I would argue that traversing the directory root is expensive. But more importantly this can result in unexpected behavior where if I delete a file or move a folder around, the config might change without warning because the path to the root has changed.

I prefer the ability to define where the various config files are in a more declarative and explicit way, and keep everything encapsulated.

@unode
Copy link

unode commented Feb 11, 2019

So this follows what @albfan suggested above but simplifies the command-line interface by not requiring to manually specify the profile.

For me it's not uncommon to have a single git clone with multiple remotes with different URL/sources.

$ git remote -v
github   git@github.com:userA/repo.git (fetch)
github   git@github.com:userA/repo.git (push)
gitlab   git@gitlab.com:userB/repo.git (fetch)
gitlab   git@gitlab.com:userB/repo.git (push)
origin   git@gitlab.custom.com:userA/repoXYZ.git (fetch)
origin   git@gitlab.custom.com:userA/repoXYZ.git (push)
upstream git@github.com:organization/repo.git (fetch)
upstream git@github.com:organization/repo.git (push)

The first two are clones handled by different users, origin is my main clone and the last is the official repository.

Given the above, wouldn't matching the profile based on the URL be sufficient?

For HTTPS one can add the username to the URL https://user@gitlab.com/org/repo.git.
For SSH if you need to use different users/ssh-keys you can create a host alias:

Host bobgithub
    HostName github.com
    User git
    IdentityFile ~/.ssh/bobgithub
    ...

Host johngithub
    HostName github.com
    User git
    IdentityFile ~/.ssh/johngithub
    ...

And then have:

$ git remote -v
bob	bobgithub:user/repo.git (fetch)
bob	bobgithub:user/repo.git (push)
john	johngithub:john/repo.git (fetch)
john	johngithub:john/repo.git (push)

In this case you'd only need something like:

"profiles" = [
  {
    "host" = "userA@gitlab.com"    # 'userA@' is optional here
    "token" = "blablabla1"
   },
  {
    "host" = "userB@gitlab.com"    # 'userB@' again optional
    "token" = "blablabla2"
   },
  {
    "host" = "gitlab.gnome.org"
    "token" = "blablabla"
   },
  {
    "host" = "bobgithub"
    "token" = "blablabla"
   },
]

Notice the lack of https:// or git@ in the SSH URL which would be unnecessary. The host would be matched as-is against the hostname part of the remote's URL.

This is identical to what git already does under the hood when looking for which SSH credentials to use and what pass-git-helper uses to match credentials when using HTTPS..

At this moment I can't think of a situation that isn't covered by this proposal.
Anyone else in the thread care to disagree?

PS: On a slight tangent, with security in mind, I might find it useful to store tokens in someplace encrypted such as pass and use a hook-like mechanism to retrieve it (such as in pass-git-helper). As such having tokens in plaintext on disk or in a .git/config is sub-optimal.

@omerpr23
Copy link

omerpr23 commented Jun 4, 2019

Side note: idea with lab meta is to bundle some of the more abstract operations including the gitlab locking functionality lab meta lock <file> and lab meta unlock <file> which still haven't found a home.

First of all, Thanks for this great tool (:
Is there still a plan to implement the lock/unlock feature?

@zaquestion
Copy link
Owner

@omerpr23 Yeah I still want to support it, implementation is in the air currently, and since the design here has converged away from a lab meta command, its less likely file locking will be implemented with that syntax.

That said, I created a placeholder issue at #325 and would love to move/continue discussion there and field any suggestions on how to properly home the functionality in lab.

@zaquestion zaquestion added this to To Do in 1.0 via automation Jul 26, 2019
@lazyfrosch
Copy link

Is anyone working on this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
1.0
  
To Do
Development

No branches or pull requests

10 participants