Skip to content

Commit

Permalink
fix: project organization
Browse files Browse the repository at this point in the history
  • Loading branch information
lpmatos committed Jul 28, 2020
1 parent 96f122e commit 91e7af2
Show file tree
Hide file tree
Showing 5 changed files with 183 additions and 201 deletions.
2 changes: 1 addition & 1 deletion gitlabrc/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-

VERSION = (0, 0, 1)
VERSION = (1, 0, 0)

__version__ = ".".join(map(str, VERSION))
70 changes: 70 additions & 0 deletions gitlabrc/arguments.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# -*- coding: utf-8 -*-

import os
from .constants import CLI
from .settings import Config
from .method import CloneMethod
from typing import NoReturn, Text, Optional, Type, Dict
from argparse import ArgumentParser, RawTextHelpFormatter

# https://docs.python.org/3/library/argparse.html

class Arguments:

def __init__(self, argv: Optional[Type[Dict]] = None) -> NoReturn:
self._config = Config()
self._parser = self._create_parser_object()
self._adding_arguments()
self.args = self._parser.parse_args(argv)

def _create_parser_object(self) -> ArgumentParser:
return ArgumentParser(
description="GitlabRC is a CLI that help you to clone all projects inside a specific namespace in Gitlab",
prog="gitlabrc",
epilog=CLI,
formatter_class=RawTextHelpFormatter)

def _adding_arguments(self) -> NoReturn:
self._parser.add_argument("-u", "--url",
type = str,
dest = "url",
default = "https://gitlab.com",
metavar = "<url>",
help = "base URL of GitLab instance")
self._parser.add_argument("-t", "--token",
type = str,
dest = "token",
default = self._config.get_env("GITLAB_TOKEN"),
metavar = "<token>",
help = "token GitLab API")
self._parser.add_argument("-n", "--namespace",
type = str,
dest = "namespace",
default = "",
metavar = "<namespace>",
help = "namespace in GitLab to clone all projects")
self._parser.add_argument("-p", "--path",
dest = "path",
default = self._config.get_env("PWD"),
metavar = "<path>",
help = "destination path to cloned projects")
self._parser.add_argument("-m", "--method",
type = CloneMethod.parse,
dest = "method",
default = self._config.get_env("GITLAB_CLONE_METHOD", "http"),
metavar = "<method>",
choices = list(CloneMethod),
help = "method used in GitLabRC to cloning repositories (either <http> or <ssh>)")
self._parser.add_argument("--disable-root",
action ="store_true",
dest = "noroot",
default = False,
help = "don't create root namepace folder in path")
self._parser.add_argument("--dry-run",
action = "store_true",
dest = "dryrun",
default = False,
help = "list all repositories without clone/fetch")
self._parser.add_argument("--version",
action = "store_true",
help = "show version")
177 changes: 111 additions & 66 deletions gitlabrc/cli.py
Original file line number Diff line number Diff line change
@@ -1,70 +1,115 @@
# -*- coding: utf-8 -*-

import os
from .constants import CLI
from .settings import Config
import sys
import re
import shutil
import time
import gitlab
import optparse
from art import *
import subprocess
from .arguments import Arguments
from .method import CloneMethod
from typing import NoReturn, Text
from argparse import ArgumentParser, RawTextHelpFormatter

# https://docs.python.org/3/library/argparse.html

class Arguments:

def __init__(self, argv=None) -> NoReturn:
self._config = Config()
self._parser = self._create_parser_object()
self._adding_arguments()
self.args = self._parser.parse_args(argv)

def _create_parser_object(self) -> ArgumentParser:
return ArgumentParser(
description="GitlabRC is a CLI that help you to clone all projects inside a specific namespace in Gitlab",
prog="gitlabrc",
epilog=CLI,
formatter_class=RawTextHelpFormatter)

def _adding_arguments(self) -> NoReturn:
self._parser.add_argument("-u", "--url",
type = str,
dest = "url",
default = "https://gitlab.com",
metavar = "<url>",
help = "base URL of GitLab instance")
self._parser.add_argument("-t", "--token",
type = str,
dest = "token",
default = self._config.get_env("GITLAB_TOKEN"),
metavar = "<token>",
help = "token GitLab API")
self._parser.add_argument("-n", "--namespace",
type = str,
dest = "namespace",
default = "",
metavar = "<namespace>",
help = "namespace in GitLab to clone all projects")
self._parser.add_argument("-p", "--path",
dest = "path",
default = self._config.get_env("PWD"),
metavar = "<path>",
help = "destination path to cloned projects")
self._parser.add_argument("-m", "--method",
type = CloneMethod.parse,
dest = "method",
default = self._config.get_env("GITLAB_CLONE_METHOD", "http"),
metavar = "<method>",
choices = list(CloneMethod),
help = "method used in GitLabRC to cloning repositories (either <http> or <ssh>)")
self._parser.add_argument("--disable-root",
action ="store_true",
dest = "noroot",
default = False,
help = "don't create root namepace folder in path")
self._parser.add_argument("--dry-run",
action = "store_true",
dest = "dryrun",
default = False,
help = "list all repositories without clone/fetch")
self._parser.add_argument("--version",
action = "store_true",
help = "show version")
from . import __version__ as VERSION

def pname():
return f"[gitlabrc - {str(os.getpid())}]"

def main():
Art=text2art("GitLabRC")
print(Art)
args = Arguments(argv=None if sys.argv[1:] else ["--help"]).args
if args.version:
print(f"Version: {VERSION}")
sys.exit(0)
perform(args)

def perform(options):
url, token, namespace = options.url, options.token, options.namespace

if not url:
sys.stderr.write("\nError: we need gitlab url information\n\n")
exit(1)

if not token:
sys.stderr.write("\nError: we need gitlab token information\n\n")
exit(1)

if not namespace:
sys.stderr.write("\nError: we need gitlab namespace information\n\n")
exit(1)

if not os.path.isdir(options.path):
sys.stderr.write("\nError: destination path does not exist " + options.path + "\n\n")
exit(1)

git_path = shutil.which("git")
if git_path == "None":
sys.stderr.write("Error: git executable not installed or not in $PATH" + "\n")
exit(2)
else:
print(pname() + " using " + git_path)

t = time.time()

gl = gitlab.Gitlab(url, token)

group = gl.groups.get(namespace, lazy=True, include_subgroups=True)

projects = []

# Get all projects inside the namespace
for project in group.projects.list(all=True):
projects.append(project)
print(pname() + " found " + project.path_with_namespace)

# Get all projects inside the subgroups
for group in gl.groups.list(all=True, owned=True, query_parameters={"id": namespace}):
for project in group.projects.list(all=True):
projects.append(project)
print(pname() + " found " + project.path_with_namespace)

subgroups = group.subgroups.list(all=True)
while True:
for subgroup in subgroups:
real_group = gl.groups.get(subgroup.id, lazy=True)
for project in real_group.projects.list(all=True):
projects.append(project)
print(pname() + " found " + project.path_with_namespace)
subgroups = real_group.subgroups.list(all=True)
if len(subgroups) == 0: next
if len(subgroups) == 0: break

if not options.dryrun:
for project in projects:
print(pname() + " clone/fetch project " + project.path_with_namespace)
folders = [f.strip().lower() for f in project.path_with_namespace.split("/")]
if options.noroot:
folders.remove(namespace)
mkdir = options.path
for i in range(len(folders) - 1):
mkdir = mkdir + "/" + folders[i]
if not os.path.isdir(mkdir):
os.mkdir(mkdir)
clone_path = options.path + "/" + "/".join(str(x) for x in folders)
clone_path = re.sub("/+", "/", clone_path)
print(pname() + " folder " + clone_path)
project_url = project.http_url_to_repo if options.method is CloneMethod.HTTP else project.ssh_url_to_repo
if not os.path.isdir(clone_path):
print(pname() + " cloning " + project_url)
try:
subprocess.run(["git", "clone", project_url, clone_path])
except:
sys.stderr.write("Unexpected error while cloning: terminating\n")
exit(2)
else:
print(pname() + " fetching " + project_url)
try:
subprocess.run(["git", "-C", clone_path, "fetch", "--all"])
except:
sys.stderr.write("Unexpected error while fetching: terminating\n")
exit(3)

print(pname() + " mission accomplished in " + str(round(time.time() - t, 2)) + "s")
exit(0)
133 changes: 0 additions & 133 deletions gitlabrc/clone.py

This file was deleted.

Loading

0 comments on commit 91e7af2

Please sign in to comment.