Skip to content

Commit 5e54096

Browse files
implemented threading
1 parent ec0de54 commit 5e54096

File tree

5 files changed

+209
-79
lines changed

5 files changed

+209
-79
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,5 @@ __pycache__/
99
/build/
1010
/my_gitmodules/
1111
/manual_test.py
12+
/dev/config.yaml
13+
/config.yaml

README.md

Lines changed: 103 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
# Not Gitmodules
22

33
---
4+
45
# What's `not_gitmodules`?
56

6-
`not_gitmodules` is a lightweight, production-ready Python utility designed to simplify managing external modules in your project.
7+
`not_gitmodules` is a lightweight, production-ready Python utility designed to simplify managing external modules in
8+
your project.
79

810
---
11+
912
# Why `not_gitmodules`?
1013

1114
1. Simplicity: Minimalistic design—no unnecessary complexities.
@@ -14,39 +17,44 @@
1417
4. OS-Agnostic: Works seamlessly on Linux, MacOS and any other platforms where Python is available by default.
1518

1619
---
20+
1721
## Installation and Usage
1822

1923
### Installation
2024

2125
Choose one of the following methods to install `not_gitmodules`:
2226

2327
#### 1. Clone the repository:
28+
2429
```bash
2530
git clone https://github.com/Armen-Jean-Andreasian/not_gitmodules.git
2631
```
27-
28-
#### 2. Install via pip:
32+
33+
#### 2. Install via pip:
34+
2935
```bash
3036
pip install not-gitmodules
3137
```
3238

3339
---
34-
# Preparation and Usage Options
3540

36-
## 1. Preparation (IMPORTANT)
37-
38-
Create a `notgitmodules.yaml` file in your project's root directory.
39-
41+
# Preparation and Usage Options
42+
43+
## 1. Preparation (IMPORTANT)
44+
45+
Create a `notgitmodules.yaml` file in your project's root directory.
46+
4047
```yaml
4148
# directory_name: url (ssh or https)
42-
49+
4350
# Example:
4451
file_reader: https://github.com/Free-Apps-for-All/file_manager_git_module
4552
```
4653
4754
## 2. Usage Options
4855
4956
You can use `not_gitmodules` in two ways:
57+
5058
1. **As a part of your project's code.**
5159
Just clone/download this repository and include it to your project.
5260
- **Pros:** No additional dependencies or overhead.
@@ -55,110 +63,130 @@ You can use `not_gitmodules` in two ways:
5563

5664
2. **As a Python Package (Recommended).**
5765
Install using **pip**
58-
- **Pros:** This method allows you to leverage CLI commands for better flexibility, ease with Docker, keeps the project lightweight
66+
67+
- **Pros:** This method allows you to leverage CLI commands for better flexibility, ease with Docker, keeps the project
68+
lightweight
5969
- **Cons:** Additional dependency
6070

6171
**Not recommended** option: clone/download this repository and run `pip install .`
6272

6373
---
74+
6475
# Usage
65-
76+
6677
## A. As Part of Your Project's Code
6778

6879
### Command:
6980

7081
```bash
7182
git clone https://github.com/Armen-Jean-Andreasian/not_gitmodules.git
7283
```
73-
74-
### Implementation:
75-
76-
- If `notgitmodules.yaml` is located in the project root:
77-
84+
85+
### Implementation:
86+
87+
- If `notgitmodules.yaml` is located in the project root:
88+
7889
```python
79-
from not_gitmodules import initializer
80-
90+
from not_gitmodules import initializer
91+
8192
initializer()
8293
```
8394

8495
- If `notgitmodules.yaml` is located somewhere else. _Or has a different name._
96+
8597
```python
86-
from not_gitmodules import initializer
87-
88-
initializer('custom/path/to/config.yaml') # Specify a custom path
98+
from not_gitmodules import initializer
99+
100+
initializer('custom/path/to/config.yaml') # Specify a custom path
89101
```
102+
90103

91104
---
105+
92106
## B. As a Python Package (Recommended)
93107

94108
This method allows you to leverage CLI commands for better flexibility.
95109

96-
97110
### 1. Install the package
98111

99112
```
100113
pip install not_gitmodules
101114
```
102115
103116
---
104-
### 2. Add it to `requirements.txt`
105-
106-
As this package is not used in code itself, it's easy to forget to add. So better to add in advance.
107-
108-
#### Run:
117+
118+
### 2. Add it to `requirements.txt`
119+
120+
As this package is not used in code itself, it's easy to forget to add. So better to add in advance.
121+
122+
#### Run:
109123
110124
```bash
111125
pip show not_gitmodules
112126
```
113-
114-
**Check the `Version` and include it to `requirements.txt` with `~=` assignment:**
115-
116-
- Example:
127+
128+
**Check the `Version` and include it to `requirements.txt` with `~=` assignment:**
129+
130+
- Example:
117131
```text
118132
not_gitmodules~=0.2
119133
```
120-
134+
121135
---
122-
### 3. Install the modules:
123-
124-
>#### Flags
125-
>
126-
>| Flag | Description |
127-
>|---------------------|-------------------------------------------------------------------------|
128-
>| `-d`, `--dir_name` | Specify a directory name where the modules will be saved (optional). |
129-
>| `-y`, `--yaml-path` | Specify a custom location for the `notgitmodules.yaml` file (optional). |
130-
131-
### To install modules via the terminal:
132-
133-
- ### Default command:
134-
135-
This will look for `notgitmodules.yaml` in the project root and create a directory named `my_gitmodules` in the root to download the modules into.
136+
137+
### 3. Install the modules:
138+
139+
| Flag (all of them are optional) | Description | Example |
140+
|---------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------|
141+
| `-d`, `--dir_name` | Specify the directory name where the modules will be saved. <br>By default, the modules will be saved in a directory named `my_gitmodules`. | • `not_gitmodules -d custom_folder`: Saves the repositories in `custom_folder` folder |
142+
| `-y`, `--yaml-path` | Specify a custom path for the `notgitmodules.yaml` configuration file. <br>By default, it looks for `notgitmodules.yaml` in the current working directory. Naming it `notgitmodules` is a matter of best practices; you can name it as you want. | • `not_gitmodules -y /path/to/custom_notgitmodules.yaml`: Uses a custom YAML file located at `/path/to/custom_notgitmodules.yaml` |
143+
| `-t`, `--threaded` | Enable threaded execution, where repositories are cloned in parallel (using threads). This flag is mutually exclusive with `-s`. <br> This is the default behavior if neither `-t` nor `-s` is specified. | • `not_gitmodules -t`: Clones repositories in parallel using threads <br> • `not_gitmodules --threaded`: Same as `-t`, using long form |
144+
| `-s`, `--sequential` | Enable sequential execution, where repositories are cloned one by one in the order they appear in the YAML file. This flag is mutually exclusive with `-t`. | • `not_gitmodules -s`: Clones repositories one by one in order <br> • `not_gitmodules --sequential`: Same as `-s`, using long form |
145+
146+
### More command examples:
147+
148+
- ### Default command:
149+
150+
This will look for `notgitmodules.yaml` in the project root and create a directory named `my_gitmodules` in the root to
151+
download the modules into, in parallel mode using threads.
136152
137153
```bash
138154
not_gitmodules install
139155
```
140156

141-
- ### Command pattern:
157+
- ### Command pattern:
142158

143159
```bash
144-
not_gitmodules install --yaml-path </path/to/notgitmodules.yaml> --dir_name <directory_name>
160+
not_gitmodules install --yaml-path </path/to/notgitmodules.yaml> --dir_name <directory_name> --threaded
145161
```
146162

147-
or
163+
or
148164

149165
```bash
150-
not_gitmodules install -y </path/to/notgitmodules.yaml> -d <directory_name>
166+
not_gitmodules install -y </path/to/notgitmodules.yaml> -d <directory_name> -t
151167
```
152168

169+
---
170+
## Comparison
171+
For eleven repos with undefined amount of workers in `ThereadPool` :
172+
173+
- The execution of in sequential mode took 35.13206000009086 seconds.
174+
- The execution of in parallel mode took 16.677515499992296 seconds.
175+
176+
We get **52.53%** performance boost.
177+
153178
---
154-
### 4. Dockerizing
155179

156-
Double-check that you:
157-
1. Created a `notgitmodules.yaml`
158-
2. Included `not_gitmodules` version to `requirements.txt`
180+
### 4. Dockerizing
181+
182+
Double-check that you:
183+
184+
1. Created a `notgitmodules.yaml`
185+
2. Included `not_gitmodules` version to `requirements.txt`
186+
187+
Then:
159188

160-
Then:
161-
3. Create your `Dockerfile`. Example:
189+
3. Create your `Dockerfile`. Example:
162190

163191
```dockerfile
164192
FROM python:3.10-slim
@@ -176,36 +204,41 @@ RUN pip install --no-cache-dir -r requirements.txt
176204
COPY notgitmodules.yaml .
177205

178206
# install modules using not_gitmodules
179-
RUN not_gitmodules install -y notgitmodules.yaml -d my_directory
207+
RUN not_gitmodules install -y notgitmodules.yaml -d my_directory -t
180208

181209
CMD ["python", "main.py"]
182210
```
183211

184212
---
185-
## Possible Issues with Private Repositories
186-
213+
214+
## Possible Issues with Private Repositories
215+
187216
If cloning fails but you have access to the repository, provide the HTTPS repo URL instead of SSH
188-
in `notgitmodules.yaml`.
217+
in `notgitmodules.yaml`.
189218

190219
---
220+
191221
## Worth to mention
192222

193-
- `not_gitmodules` doesn't require for you to keep the folders with modules. You can safely .gitignore/delete them.
194-
- Do not use matching names for the repositories in `notgitmodules.yaml` file. In that case only the first repository will be downloaded and the second one - skipped.
223+
- `not_gitmodules` doesn't require for you to keep the folders with modules. You can safely .gitignore/delete them.
224+
- Do not use matching names for the repositories in `notgitmodules.yaml` file. In that case only the first repository
225+
will be downloaded and the second one - skipped.
195226

196227
---
197-
## License
198-
199-
This project is licensed under a **Custom License**. See the [LICENSE](./LICENSE) file for full details.
200-
201-
Key points:
202-
203-
- You may use this project for commercial or personal purposes.
228+
229+
## License
230+
231+
This project is licensed under a **Custom License**. See the [LICENSE](./LICENSE) file for full details.
232+
233+
Key points:
234+
235+
- You may use this project for commercial or personal purposes.
204236

205237
---
238+
206239
## Author
207240

208-
Armen-Jean Andreasian, 2024
241+
Armen-Jean Andreasian, 2024
209242

210243
---
211244
<div style="text-align: center;">

dev/speed_comparison.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import time
2+
from not_gitmodules import initializer
3+
4+
5+
def timer(func):
6+
def executor():
7+
start = time.perf_counter()
8+
func()
9+
end = time.perf_counter()
10+
return f'The execution of {func.__name__} took {end - start} seconds.'
11+
12+
return executor
13+
14+
15+
@timer
16+
def test_sequentially():
17+
initializer(
18+
yaml_config_path='config.yaml',
19+
download_in_threads=False,
20+
root_dir_name='my_libs'
21+
)
22+
23+
24+
@timer
25+
def test_parallely():
26+
initializer(
27+
yaml_config_path='config.yaml',
28+
download_in_threads=True,
29+
root_dir_name='my_gitmodules'
30+
)
31+
32+
33+
def compare():
34+
result1 = test_sequentially()
35+
time.sleep(2)
36+
result2 = test_parallely()
37+
38+
print(70 * '=')
39+
print(result1)
40+
print(result2)
41+
42+
43+
if __name__ == '__main__':
44+
compare()

not_gitmodules/cli.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
def cli():
66
arg_parser = argparse.ArgumentParser(description="GitHub repositories installation with not_gitmodules.")
77

8+
# arguments
89
arg_parser.add_argument(
910
"-y", "--yaml-path",
1011
nargs="?", # optional
@@ -19,6 +20,26 @@ def cli():
1920
help="The name of the directory the modules will be saved in. By default it's my_gitmodules."
2021
)
2122

23+
# modes
24+
mode_group = arg_parser.add_mutually_exclusive_group()
25+
26+
mode_group.add_argument(
27+
"-t", "--threaded",
28+
action="store_true",
29+
help="Enable threaded mode for parallel execution."
30+
)
31+
mode_group.add_argument(
32+
"-s", "--sequential",
33+
action="store_true",
34+
help="Enable sequential mode for sequential execution."
35+
)
36+
2237
args, unknown = arg_parser.parse_known_args()
2338

24-
initializer(yaml_config_path=args.yaml_path, root_dir_name=args.dir_name)
39+
download_in_threads = False if args.sequential else True
40+
41+
initializer(
42+
yaml_config_path=args.yaml_path,
43+
root_dir_name=args.dir_name,
44+
download_in_threads=download_in_threads
45+
)

0 commit comments

Comments
 (0)