odoogci 0.2.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
odoogci-0.2.2/PKG-INFO ADDED
@@ -0,0 +1,101 @@
1
+ Metadata-Version: 2.4
2
+ Name: odoogci
3
+ Version: 0.2.2
4
+ Summary: Utility to clone odoo modules repository with requirements installation
5
+ License: GNU/GPL V2
6
+ Author: Alitux
7
+ Author-email: alitux@disroot.org
8
+ Requires-Python: >=3.9,<4.0
9
+ Classifier: License :: Other/Proprietary License
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.9
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Classifier: Programming Language :: Python :: 3.14
17
+ Requires-Dist: typer (>=0.15.1,<0.16.0)
18
+ Description-Content-Type: text/markdown
19
+
20
+ # odoogci
21
+
22
+ A utility for cloning Git repositories, removing unnecessary files, and installing dependencies from `requirements.txt`. It is specifically designed to facilitate building Odoo Docker images.
23
+
24
+ ## Requirements
25
+
26
+ Ensure you have the following tools installed on your system:
27
+
28
+ - Python ^3.9
29
+ - Git
30
+ - pip (Python package manager)
31
+
32
+ ## Installation
33
+
34
+ ### Via pipx (Recommended for CLI)
35
+ ```sh
36
+ pipx install odoogci
37
+ ```
38
+
39
+ ### Via pip
40
+ ```sh
41
+ pip install odoogci
42
+ ```
43
+
44
+ ### In a Dockerfile (From source)
45
+ Add the following line to your Dockerfile:
46
+
47
+ ```Dockerfile
48
+ RUN pip3 install git+https://gitlab.com/alitux/odoogci.git
49
+ ```
50
+
51
+ ## Usage
52
+
53
+ The general usage of the tool is:
54
+
55
+ ```sh
56
+ odoogci [URL] [OPTIONS]
57
+ ```
58
+
59
+ ### Arguments
60
+
61
+ * `URL`: URL of the repository to clone.
62
+
63
+ ### Options
64
+
65
+ * `--branch TEXT`: Branch of the repository.
66
+ * `--repositories TEXT`: JSON string with a list of repositories to clone.
67
+ * `--requirements / --no-requirements`: Install dependencies from `requirements.txt`. [default: no-requirements]
68
+ * `--repopath TEXT`: Local path where the repository will be cloned.
69
+ * `--token TEXT`: Access token for the repository (supports GitHub and GitLab).
70
+
71
+ ### Examples
72
+
73
+ #### Simple Clone
74
+ ```sh
75
+ odoogci https://github.com/ingadhoc/odoo-argentina --branch 16.0
76
+ ```
77
+
78
+ #### Clone Multiple Repositories using JSON
79
+ ```sh
80
+ odoogci --repositories '[
81
+ {
82
+ "url": "https://github.com/org/repo1",
83
+ "branch": "18.0",
84
+ "repo_path": "repo1"
85
+ },
86
+ {
87
+ "url": "https://github.com/OCA/commission",
88
+ "branch": "18.0",
89
+ "repo_path": "oca/commission"
90
+ }
91
+ ]'
92
+ ```
93
+
94
+ #### Usage in a Dockerfile
95
+
96
+ ```Dockerfile
97
+ RUN cd /usr/lib/python3/dist-packages/odoo/addons/ && \
98
+ odoogci https://github.com/ingadhoc/odoo-argentina --branch 16.0 && \
99
+ odoogci https://github.com/ingadhoc/account-invoicing --branch 16.0
100
+ ```
101
+
@@ -0,0 +1,81 @@
1
+ # odoogci
2
+
3
+ A utility for cloning Git repositories, removing unnecessary files, and installing dependencies from `requirements.txt`. It is specifically designed to facilitate building Odoo Docker images.
4
+
5
+ ## Requirements
6
+
7
+ Ensure you have the following tools installed on your system:
8
+
9
+ - Python ^3.9
10
+ - Git
11
+ - pip (Python package manager)
12
+
13
+ ## Installation
14
+
15
+ ### Via pipx (Recommended for CLI)
16
+ ```sh
17
+ pipx install odoogci
18
+ ```
19
+
20
+ ### Via pip
21
+ ```sh
22
+ pip install odoogci
23
+ ```
24
+
25
+ ### In a Dockerfile (From source)
26
+ Add the following line to your Dockerfile:
27
+
28
+ ```Dockerfile
29
+ RUN pip3 install git+https://gitlab.com/alitux/odoogci.git
30
+ ```
31
+
32
+ ## Usage
33
+
34
+ The general usage of the tool is:
35
+
36
+ ```sh
37
+ odoogci [URL] [OPTIONS]
38
+ ```
39
+
40
+ ### Arguments
41
+
42
+ * `URL`: URL of the repository to clone.
43
+
44
+ ### Options
45
+
46
+ * `--branch TEXT`: Branch of the repository.
47
+ * `--repositories TEXT`: JSON string with a list of repositories to clone.
48
+ * `--requirements / --no-requirements`: Install dependencies from `requirements.txt`. [default: no-requirements]
49
+ * `--repopath TEXT`: Local path where the repository will be cloned.
50
+ * `--token TEXT`: Access token for the repository (supports GitHub and GitLab).
51
+
52
+ ### Examples
53
+
54
+ #### Simple Clone
55
+ ```sh
56
+ odoogci https://github.com/ingadhoc/odoo-argentina --branch 16.0
57
+ ```
58
+
59
+ #### Clone Multiple Repositories using JSON
60
+ ```sh
61
+ odoogci --repositories '[
62
+ {
63
+ "url": "https://github.com/org/repo1",
64
+ "branch": "18.0",
65
+ "repo_path": "repo1"
66
+ },
67
+ {
68
+ "url": "https://github.com/OCA/commission",
69
+ "branch": "18.0",
70
+ "repo_path": "oca/commission"
71
+ }
72
+ ]'
73
+ ```
74
+
75
+ #### Usage in a Dockerfile
76
+
77
+ ```Dockerfile
78
+ RUN cd /usr/lib/python3/dist-packages/odoo/addons/ && \
79
+ odoogci https://github.com/ingadhoc/odoo-argentina --branch 16.0 && \
80
+ odoogci https://github.com/ingadhoc/account-invoicing --branch 16.0
81
+ ```
File without changes
@@ -0,0 +1,189 @@
1
+ # import uuid
2
+ import json
3
+ import os
4
+ import subprocess
5
+ import sys
6
+ import typer
7
+ from rich.progress import Progress, SpinnerColumn, TextColumn
8
+ from rich.console import Console
9
+ from typing import Optional
10
+ from typing_extensions import Annotated
11
+
12
+ app = typer.Typer()
13
+ err_console = Console(stderr=True)
14
+ ABS_PATH = os.path.join(os.path.dirname(__file__))
15
+
16
+
17
+ def install_req(repo_path: str, archive: str = "requirements.txt"):
18
+ """Install dependencies from requirements.txt"""
19
+ archive_abs_path = f"{repo_path}/{archive}"
20
+ if os.path.exists(archive_abs_path):
21
+ print("Instalando dependencias ", end=" ")
22
+ try:
23
+ command = f"pip install -r {archive_abs_path}"
24
+ subprocess.run(command, shell=True, check=True)
25
+ print("[OK]")
26
+ except:
27
+ print("[ERROR]")
28
+ else:
29
+ print("No hay archivo de dependencias[OK]")
30
+
31
+
32
+ def remove_garbage(repo_path: str):
33
+ """Remove unnecessary files"""
34
+ print("Removiendo archivos innecesarios ", end=" ")
35
+ items = os.listdir(f"{repo_path}/")
36
+ try:
37
+ for item in items:
38
+ if os.path.isfile(f"{repo_path}/{item}"):
39
+ command = f"rm -rf {repo_path}/{item}"
40
+ subprocess.run(command, shell=True, check=True)
41
+ subprocess.run(f"rm -rf {repo_path}/.git", shell=True, check=True)
42
+ subprocess.run(f"rm -rf {repo_path}/setup", shell=True, check=True)
43
+ print("[OK]")
44
+ except:
45
+ print("[ERROR]")
46
+ sys.exit(1)
47
+
48
+
49
+ def move_folders(repo_path: str):
50
+ """Move folders to current directory"""
51
+ print("Moviendo repositorio a carpeta actual ", end=" ")
52
+ try:
53
+ subprocess.run(f"mv {repo_path}/* .", shell=True, check=True)
54
+ subprocess.run(f"rm -rf {repo_path}", shell=True, check=True)
55
+ print("[OK]")
56
+ except:
57
+ print("[ERROR]")
58
+ sys.exit(1)
59
+
60
+ def git_clone_update(url: str, branch: str, token: str = None, repo_path: str = None):
61
+ """Clona o actualiza un repositorio Git.
62
+ Si en local hay cambios directamente hace un hard reset y vuelve a pullear
63
+ """
64
+ url_old = url
65
+
66
+ if not repo_path:
67
+ if ".git" in url:
68
+ repo_path = url.split(".git")[0].split("/")[-1]
69
+ if not ".git" in url:
70
+ repo_path = url.split("/")[-1]
71
+
72
+
73
+ if token:
74
+ if "github.com" in url:
75
+ url = url.replace("github.com", f"{token}@github.com") + ".git"
76
+ elif "gitlab.com" in url:
77
+ url = url.replace("gitlab.com", f"oauth2:{token}@gitlab.com")+".git"
78
+ if os.path.exists(repo_path) and os.path.exists(f"{repo_path}/.git"):
79
+ message = f"[cyan] Actualizando {repo_path}... [/cyan]"
80
+ command = ["git", "-C", repo_path, "pull"]
81
+ ## Se hace un reset para obviar cambios locales
82
+ subprocess.run(["git", "-C", repo_path, "reset", "--hard"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
83
+ else:
84
+ message = f"[cyan] Clonando {url_old} ({branch})... [/cyan]"
85
+ command = ["git", "clone", "--recurse-submodules", url, "-b", branch, repo_path]
86
+
87
+ with Progress(SpinnerColumn(), TextColumn("{task.description}")) as progress:
88
+ task = progress.add_task(description=message, total=None)
89
+
90
+ try:
91
+ process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)
92
+ stdout, stderr = process.communicate()
93
+
94
+ if process.returncode == 0:
95
+ progress.update(task, description=f"[green]{message} ✔[/green]", completed=1)
96
+ else:
97
+ progress.update(task, description=f"[red]Error en {repo_path} ✖[/red]", completed=1)
98
+ print(f"\n[red]Salida de Git:[/red]\n{stderr.strip()}")
99
+ sys.exit(1)
100
+
101
+ except Exception as e:
102
+ progress.update(task, description=f"[red]Error en {repo_path} ✖[/red]", completed=1)
103
+ print(f"\n[red]Error inesperado:[/red] {e}")
104
+ sys.exit(1)
105
+
106
+
107
+ def git_update_all():
108
+ """Update all repositories in the current directory"""
109
+ with Progress(SpinnerColumn(), TextColumn("{task.description}")) as progress:
110
+ for carpeta in os.listdir():
111
+ ruta_completa = os.path.join(os.getcwd(), carpeta)
112
+ if os.path.isdir(ruta_completa) and os.path.isdir(os.path.join(ruta_completa, ".git")):
113
+ try:
114
+ message = f"[cyan] Actualizando {carpeta}... [/cyan]"
115
+ task = progress.add_task(description=message, total=None)
116
+ subprocess.run(["git", "-C", ruta_completa, "pull"], check=True)
117
+ progress.update(task, description=f"[green]{message} ✔[/green]", completed=1)
118
+ except subprocess.CalledProcessError:
119
+ progress.update(task, description=f"[red]Error en {carpeta} ✖[/red]", completed=1)
120
+
121
+ @app.command()
122
+ def main(
123
+ url: Annotated[Optional[str], typer.Argument(help="URL del repositorio")]=None,
124
+ repositories: Annotated[
125
+ Optional[str], typer.Option(help="JSON con con repositorios a clonar"),
126
+ ] = None,
127
+ branch: Annotated[Optional[str], typer.Option(help="Branch del repositorio")] = None,
128
+ requirements : Annotated[
129
+ Optional[bool], typer.Option(help="No instala dependencias"),
130
+ ] = False,
131
+ # update: Annotated[
132
+ # Optional[bool], typer.Option(help="Actualiza todos los repositorios"),
133
+ # ] = False,
134
+ # garbage: Annotated[
135
+ # Optional[bool], typer.Option(help="No elimina archivos innecesarios"),
136
+ # ] = True,
137
+ repopath: Annotated[
138
+ Optional[str], typer.Option(help="Ruta del repositorio"),
139
+ ] = None,
140
+ token: Annotated[
141
+ Optional[str], typer.Option(help="Token de acceso a repositorio"),
142
+ ] = None,
143
+ ):
144
+
145
+ """Utility for cloning Git repositories, removing unnecessary files, and installing dependencies from requirements.txt."""
146
+
147
+ # if update:
148
+ # git_update_all()
149
+ # sys.exit(0)
150
+
151
+ if not repositories:
152
+ """Clonado simple de un repositorio"""
153
+ git_clone_update(url=url, branch=branch, token=token, repo_path=repopath)
154
+
155
+ if requirements:
156
+ install_req(repo_path=repopath)
157
+ # if garbage:
158
+ # remove_garbage(repo_path=repopath)
159
+ # if not repopath:
160
+ # move_folders(repo_path=repopath)
161
+
162
+ if repositories:
163
+ """
164
+ Clonado de varios repositorios
165
+ Formato de JSON:
166
+ [
167
+ {
168
+ "url": "https://github.com/org/repo1",
169
+ "branch": "18.0",
170
+ "repo_path": "repo1"
171
+ },
172
+ {
173
+ "url": "https://github.com/OCA/commission",
174
+ "branch": "18.0",
175
+ "repo_path": "oca/commission"
176
+ }
177
+ ]
178
+ """
179
+ for repo in json.loads(repositories):
180
+ if "branch" not in repo and not branch:
181
+ err_console.print("✖[red] Branch Not defined [/red]")
182
+ raise typer.Exit(1)
183
+ branch = branch if branch else repo["branch"]
184
+ repo_path = repo["repo_path"] if "repo_path" in repo else None
185
+ git_clone_update(url=repo["url"], branch=branch, token=token, repo_path=repo_path)
186
+
187
+
188
+ if __name__ == "__main__":
189
+ app()
@@ -0,0 +1,18 @@
1
+ [tool.poetry]
2
+ name = "odoogci"
3
+ version = "0.2.2"
4
+ description = "Utility to clone odoo modules repository with requirements installation"
5
+ authors = ["Alitux <alitux@disroot.org>"]
6
+ license = "GNU/GPL V2"
7
+ readme = "README.md"
8
+
9
+ [tool.poetry.dependencies]
10
+ python = ">=3.9,<4.0"
11
+ typer = "^0.15.1"
12
+
13
+ [build-system]
14
+ requires = ["poetry-core"]
15
+ build-backend = "poetry.core.masonry.api"
16
+
17
+ [tool.poetry.scripts]
18
+ odoogci = "odoogci.main:app"