repopy 0.1.0__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.
repopy-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Janitha Manatunga
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
repopy-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,108 @@
1
+ Metadata-Version: 2.4
2
+ Name: repopy
3
+ Version: 0.1.0
4
+ Summary: A modular CLI workspace initializer and cloning automation tool.
5
+ License: MIT
6
+ Classifier: Programming Language :: Python :: 3
7
+ Classifier: License :: OSI Approved :: MIT License
8
+ Classifier: Operating System :: OS Independent
9
+ Requires-Python: >=3.8
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE
12
+ Dynamic: license-file
13
+
14
+ # repopy
15
+
16
+ A highly modular, cross-platform Python CLI scaffolding tool and library designed to automate the initial configuration of local Python developer workspaces and remote Python repository deployment.
17
+
18
+ [![PyPI Version](https://shields.io)](https://pypi.org)
19
+ [![Python Versions](https://shields.io)](https://pypi.org)
20
+ [![License: MIT](https://shields.io)](https://opensource.org)
21
+
22
+ ---
23
+
24
+ ## 🌟 Key Features
25
+
26
+ - **Local Scaffolding (`repopy local`)**: Instantly generates standardized directory trees, configures automated multi-line `.gitignore` presets, and initializes clean local Git repositories.
27
+
28
+ - **Remote Automation (`repopy clone`)**: Downloads remote repositories, parses project structures, and automatically updates localized environment constraints.
29
+
30
+ - **Isolated Virtual Environments**: Automatically builds localized `.venv` footprints using Python's native compilation layer.
31
+
32
+ - **Cross-Platform Compatibility**: Automatically detects structural variances between Windows, macOS, and Linux to run direct executions seamlessly.
33
+
34
+ ---
35
+
36
+ ## 🛠️ Architectural Highlights
37
+
38
+ This package was designed following production-grade software engineering principles:
39
+ - **Decoupled Low-Level Engines**: Features standalone layers (`FileSystemEngine` & `GitEngine`) that are entirely decoupled from CLI routing logic, making them fully reusable as an importable library API.
40
+
41
+ - **Single Responsibility Validation**: Separates terminal argument compilation (`argparse`) from explicit data sanitization filters (`validators.py`) and environmental prerequisite verification (`dependencies.py`).
42
+
43
+ - **Defensive Error Handling & Auto-Rollback**: Leverages short-circuit evaluations and interactive terminal input cascades. In the event of network or environment breaks during deployment, it offers automated transactional folder cleanups (`shutil.rmtree`) to prevent workspace pollution.
44
+
45
+ - **Direct-Execution Strategy**: Bypasses unstable, platform-dependent shell environment injections by directly target-executing localized virtual environment binaries (`pip`).
46
+
47
+ ---
48
+
49
+ ## 📥 Installation
50
+
51
+ You can install `repopy` globally from PyPI using pip:
52
+
53
+ ```bash
54
+ pip install repopy
55
+ ```
56
+
57
+ Alternatively, you can install the latest development version directly from source:
58
+
59
+ ```bash
60
+ git clone https://github.com/manatunga/repopy.git
61
+ cd repopy
62
+ pip install -e .
63
+ ```
64
+
65
+ ---
66
+
67
+ ## 🚀 Usage Guide
68
+
69
+ ### 1. Initialize a Local Project from Scratch
70
+ Generate a clean, standardized local environment with an operational virtual environment and pre-seeded `.gitignore` file:
71
+
72
+ ```bash
73
+ repopy local my-new-app
74
+ ```
75
+
76
+ ### 2. Clone and Auto-Provision a Remote Codebase
77
+ Clone an external codebase, create a virtual environment, scan for a `requirements.txt` file, and automatically install its dependencies:
78
+
79
+ ```bash
80
+ repopy clone https://github.comencode/httpx.git -n my-custom-workspace
81
+ ```
82
+
83
+ ---
84
+
85
+ ## 🗂️ Project Structure
86
+
87
+ ```text
88
+ repopy/
89
+ ├── src/
90
+ │ └── repopy/
91
+ │ ├── __init__.py # Package initialization
92
+ │ ├── __main__.py # Application root entry point
93
+ │ ├── cli.py # CLI Argument Parsing layer
94
+ │ ├── orchestrators.py # Architectural workflow supervision
95
+ │ ├── os_detector.py # Cross-platform OS translation utility
96
+ │ ├── dependencies.py # Binary prerequisite verification
97
+ │ ├── validators.py # Data input and path path verification
98
+ │ ├── file_system.py # Low-level file system engine
99
+ │ └── git_engine.py # Low-level shell compilation engine
100
+ ├── pyproject.toml # Build-system manifest & CLI script configuration
101
+ ├── .gitignore
102
+ ├── LICENSE # MIT License
103
+ └── README.md # Project documentation
104
+ ```
105
+
106
+ ## 📄 License
107
+
108
+ Distributed under the MIT License. See `LICENSE` for more details.
repopy-0.1.0/README.md ADDED
@@ -0,0 +1,95 @@
1
+ # repopy
2
+
3
+ A highly modular, cross-platform Python CLI scaffolding tool and library designed to automate the initial configuration of local Python developer workspaces and remote Python repository deployment.
4
+
5
+ [![PyPI Version](https://shields.io)](https://pypi.org)
6
+ [![Python Versions](https://shields.io)](https://pypi.org)
7
+ [![License: MIT](https://shields.io)](https://opensource.org)
8
+
9
+ ---
10
+
11
+ ## 🌟 Key Features
12
+
13
+ - **Local Scaffolding (`repopy local`)**: Instantly generates standardized directory trees, configures automated multi-line `.gitignore` presets, and initializes clean local Git repositories.
14
+
15
+ - **Remote Automation (`repopy clone`)**: Downloads remote repositories, parses project structures, and automatically updates localized environment constraints.
16
+
17
+ - **Isolated Virtual Environments**: Automatically builds localized `.venv` footprints using Python's native compilation layer.
18
+
19
+ - **Cross-Platform Compatibility**: Automatically detects structural variances between Windows, macOS, and Linux to run direct executions seamlessly.
20
+
21
+ ---
22
+
23
+ ## 🛠️ Architectural Highlights
24
+
25
+ This package was designed following production-grade software engineering principles:
26
+ - **Decoupled Low-Level Engines**: Features standalone layers (`FileSystemEngine` & `GitEngine`) that are entirely decoupled from CLI routing logic, making them fully reusable as an importable library API.
27
+
28
+ - **Single Responsibility Validation**: Separates terminal argument compilation (`argparse`) from explicit data sanitization filters (`validators.py`) and environmental prerequisite verification (`dependencies.py`).
29
+
30
+ - **Defensive Error Handling & Auto-Rollback**: Leverages short-circuit evaluations and interactive terminal input cascades. In the event of network or environment breaks during deployment, it offers automated transactional folder cleanups (`shutil.rmtree`) to prevent workspace pollution.
31
+
32
+ - **Direct-Execution Strategy**: Bypasses unstable, platform-dependent shell environment injections by directly target-executing localized virtual environment binaries (`pip`).
33
+
34
+ ---
35
+
36
+ ## 📥 Installation
37
+
38
+ You can install `repopy` globally from PyPI using pip:
39
+
40
+ ```bash
41
+ pip install repopy
42
+ ```
43
+
44
+ Alternatively, you can install the latest development version directly from source:
45
+
46
+ ```bash
47
+ git clone https://github.com/manatunga/repopy.git
48
+ cd repopy
49
+ pip install -e .
50
+ ```
51
+
52
+ ---
53
+
54
+ ## 🚀 Usage Guide
55
+
56
+ ### 1. Initialize a Local Project from Scratch
57
+ Generate a clean, standardized local environment with an operational virtual environment and pre-seeded `.gitignore` file:
58
+
59
+ ```bash
60
+ repopy local my-new-app
61
+ ```
62
+
63
+ ### 2. Clone and Auto-Provision a Remote Codebase
64
+ Clone an external codebase, create a virtual environment, scan for a `requirements.txt` file, and automatically install its dependencies:
65
+
66
+ ```bash
67
+ repopy clone https://github.comencode/httpx.git -n my-custom-workspace
68
+ ```
69
+
70
+ ---
71
+
72
+ ## 🗂️ Project Structure
73
+
74
+ ```text
75
+ repopy/
76
+ ├── src/
77
+ │ └── repopy/
78
+ │ ├── __init__.py # Package initialization
79
+ │ ├── __main__.py # Application root entry point
80
+ │ ├── cli.py # CLI Argument Parsing layer
81
+ │ ├── orchestrators.py # Architectural workflow supervision
82
+ │ ├── os_detector.py # Cross-platform OS translation utility
83
+ │ ├── dependencies.py # Binary prerequisite verification
84
+ │ ├── validators.py # Data input and path path verification
85
+ │ ├── file_system.py # Low-level file system engine
86
+ │ └── git_engine.py # Low-level shell compilation engine
87
+ ├── pyproject.toml # Build-system manifest & CLI script configuration
88
+ ├── .gitignore
89
+ ├── LICENSE # MIT License
90
+ └── README.md # Project documentation
91
+ ```
92
+
93
+ ## 📄 License
94
+
95
+ Distributed under the MIT License. See `LICENSE` for more details.
@@ -0,0 +1,19 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "repopy"
7
+ version = "0.1.0"
8
+ description = "A modular CLI workspace initializer and cloning automation tool."
9
+ readme = "README.md"
10
+ license = {text = "MIT"}
11
+ requires-python = ">=3.8"
12
+ classifiers = [
13
+ "Programming Language :: Python :: 3",
14
+ "License :: OSI Approved :: MIT License",
15
+ "Operating System :: OS Independent",
16
+ ]
17
+
18
+ [project.scripts]
19
+ repopy = "repopy.__main__:main"
repopy-0.1.0/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
File without changes
@@ -0,0 +1,27 @@
1
+ '''
2
+ Main entrypoint of repopy. Brings together the argument parser and
3
+ the orchestrators together under a main function.
4
+ '''
5
+
6
+ from repopy.cli import parse_arguments
7
+ from repopy.orchestrators import LocalInitializer, CloneInitializer
8
+
9
+ def main() -> None:
10
+ args = parse_arguments()
11
+
12
+ if args.command == 'local':
13
+ print('Working on it...')
14
+ initializer = LocalInitializer(args.project_name)
15
+ initializer.run()
16
+
17
+ elif args.command == 'clone':
18
+ print('Working on it...')
19
+ initializer = CloneInitializer(args.repo_url, args.name)
20
+ initializer.run()
21
+
22
+ else:
23
+ print('Usage: repopy [local | clone] --help')
24
+ print('Error: Please specify a subcommand')
25
+
26
+ if __name__ == '__main__':
27
+ main()
@@ -0,0 +1,19 @@
1
+ '''
2
+ Parser layer. Imports Python's built-in argparse module
3
+ to identify user intent and any extra information passed.
4
+ '''
5
+
6
+ import argparse
7
+
8
+ def parse_arguments() -> argparse.Namespace:
9
+ parser = argparse.ArgumentParser()
10
+ subparsers = parser.add_subparsers(dest='command', required=True)
11
+
12
+ local_parser = subparsers.add_parser('local')
13
+ local_parser.add_argument('project_name', help='Name of the project folder')
14
+
15
+ clone_parser = subparsers.add_parser('clone')
16
+ clone_parser.add_argument('repo_url', help='Repository URL from Github to clone')
17
+ clone_parser.add_argument('-n', '--name', action='store', help='Name of the project folder')
18
+
19
+ return parser.parse_args()
@@ -0,0 +1,13 @@
1
+ '''
2
+ Layer for Dependency-checking. Contains functions to check whether
3
+ expected dependencies (such as python and git) are installed.
4
+ '''
5
+
6
+ import shutil
7
+
8
+ def has_python() -> bool:
9
+ return bool(shutil.which('python') or shutil.which('python3'))
10
+
11
+
12
+ def has_git() -> bool:
13
+ return bool(shutil.which('git'))
@@ -0,0 +1,108 @@
1
+ '''
2
+ Core Engine for the `repopy local` command. Houses the FileSystemEngine class
3
+ that holds the methods required to manipulate directories, create virtural
4
+ environments and create .gitignore and README.md templates.
5
+ '''
6
+
7
+ import venv
8
+ import shutil
9
+ import logging
10
+ import subprocess
11
+ from pathlib import Path
12
+
13
+ logger = logging.getLogger(__name__)
14
+
15
+ class FileSystemEngine:
16
+
17
+ GITIGNORE_TEMPLATE = '''# Compiled Python files
18
+ __pycache__/
19
+ *.pyc
20
+
21
+ # Virtual environments
22
+ # .venv/
23
+ venv/
24
+ env/
25
+ ENV/
26
+
27
+ # IDEs and Editors
28
+ .vscode/
29
+ .idea/
30
+ *.swp
31
+ *.swo
32
+
33
+ # OS files
34
+ .DS_Store
35
+ Thumbs_db'''
36
+
37
+ def __init__(self, project_path: Path):
38
+ self.project_path = project_path
39
+
40
+
41
+ def create_root_directory(self) -> bool:
42
+ '''Creates new project directory with user-specified project name'''
43
+ try:
44
+ self.project_path.mkdir(parents=True, exist_ok=True)
45
+ return True
46
+
47
+ except OSError as e:
48
+ logger.error(f'Failed to create directory at {self.project_path}: {e}')
49
+ return False
50
+
51
+
52
+ def create_gitignore(self) -> bool:
53
+ '''Generates a .gitignore file with a basic python gitignore template'''
54
+ gitignore_file = self.project_path / '.gitignore'
55
+
56
+ try:
57
+ with open(gitignore_file, 'w') as f:
58
+ f.write(self.GITIGNORE_TEMPLATE)
59
+ return True
60
+
61
+ except OSError as e:
62
+ logger.error(f'Failed to create gitignore file at {self.project_path}: {e}')
63
+ return False
64
+
65
+
66
+ def create_virtual_environment(self) -> bool:
67
+ '''Initializes a python virtual environment'''
68
+ venv_dir = self.project_path / '.venv'
69
+
70
+ try:
71
+ venv.create(venv_dir, with_pip=True)
72
+ return True
73
+
74
+ except Exception as e:
75
+ logger.exception(f'Failed to create virtual environment at {self.project_path}: {e}')
76
+ return False
77
+
78
+
79
+ def initialize_git(self) -> bool:
80
+ '''Initializes git within the newly created project directory'''
81
+ try:
82
+ result = subprocess.run(['git', 'init'], cwd=self.project_path, capture_output=True, text=True)
83
+ return result.returncode == 0
84
+ except OSError as e:
85
+ logger.error(f'Unable to initialize git at {self.project_path}: {e}')
86
+ return False
87
+
88
+
89
+ def cleanup(self) -> None:
90
+ '''Removes any partially created project directories if a failure occurs'''
91
+ if self.project_path.exists():
92
+ try:
93
+ shutil.rmtree(self.project_path)
94
+ logger.info(f'Successfully cleaned up half-baked workspace at {self.project_path}')
95
+ except OSError as e:
96
+ logger.error(f'Failed to clean up directory at {self.project_path}: {e}')
97
+
98
+
99
+ def build_workspace(self) -> bool:
100
+ '''Orchestrate entire file-system creation sequence'''
101
+
102
+ if self.create_root_directory():
103
+ if self.initialize_git():
104
+ if self.create_gitignore():
105
+ if self.create_virtual_environment():
106
+ return True
107
+
108
+ return False
@@ -0,0 +1,64 @@
1
+ '''
2
+ Core Engine for the `repopy clone` command. Houses the GitEngine class that
3
+ holds the methods required to cone a GitHub repository and install
4
+ dependencies.
5
+ '''
6
+
7
+ import shutil
8
+ import logging
9
+ import subprocess
10
+ from pathlib import Path
11
+
12
+ from repopy.os_detector import is_windows
13
+
14
+ logger = logging.getLogger(__name__)
15
+
16
+ class GitEngine:
17
+
18
+ def __init__(self, repo_url: str, dir_name: str | None):
19
+ self.repo_url = repo_url
20
+
21
+ cleaned_url = repo_url.removesuffix('.git')
22
+ final_name = dir_name if dir_name else Path(cleaned_url).name
23
+
24
+ self.project_path = Path(final_name)
25
+
26
+
27
+ def clone_repository(self) -> bool:
28
+ '''Clone GitHub repository using the given url to the given directory name'''
29
+ try:
30
+ result = subprocess.run(['git', 'clone', self.repo_url, str(self.project_path)], capture_output=True, text=True)
31
+ return result.returncode == 0
32
+ except OSError as e:
33
+ logger.error(f'Failed to clone repository at {self.project_path}: {e}')
34
+ return False
35
+
36
+
37
+ def install_dependencies(self) -> bool:
38
+ '''Install repository dependencies if requirements.txt is present'''
39
+ req_file = self.project_path / 'requirements.txt'
40
+
41
+ if not req_file.exists():
42
+ return True
43
+
44
+ if is_windows():
45
+ pip_path = self.project_path / '.venv' / 'Scripts' / 'pip.exe'
46
+ else:
47
+ pip_path = self.project_path / '.venv' / 'bin' / 'pip'
48
+
49
+ try:
50
+ result = subprocess.run([str(pip_path), 'install', '-r', str(req_file)], capture_output=True, text=True)
51
+ return result.returncode == 0
52
+ except OSError as e:
53
+ logger.error(f'Failed to install dependencies at {self.project_path}: {e}')
54
+ return False
55
+
56
+ def cleanup(self) -> None:
57
+ '''Removes any partially created project directories if a failure occurs'''
58
+ if self.project_path.exists():
59
+ try:
60
+ shutil.rmtree(self.project_path)
61
+ logger.info(f'Successfully cleaned up half-baked workspace at {self.project_path}')
62
+ except OSError as e:
63
+ logger.error(f'Failed to clean up directory at {self.project_path}: {e}')
64
+
@@ -0,0 +1,126 @@
1
+ '''
2
+ Orchestration Layer. Core supervisor that amalgamates all inspectors and building
3
+ tools and manages the entire user request loop from start to finish.
4
+ '''
5
+
6
+ from pathlib import Path
7
+
8
+ from repopy.file_system import FileSystemEngine
9
+ from repopy.git_engine import GitEngine
10
+ from repopy.dependencies import has_python, has_git
11
+ from repopy.validators import is_valid_project_name, is_valid_git_url
12
+ from repopy.os_detector import is_windows
13
+
14
+ class LocalInitializer:
15
+
16
+ def __init__(self, project_name: str):
17
+ self.project_name = project_name
18
+ self.project_path = Path(project_name)
19
+
20
+
21
+ def run(self) -> bool:
22
+ '''Runs when `repopy local` is called'''
23
+ if has_python():
24
+ if is_valid_project_name(self.project_name):
25
+ fs_engine = FileSystemEngine(self.project_path)
26
+ if fs_engine.build_workspace():
27
+ print(f'Success! Your project directory has been created at {self.project_path}.')
28
+ print('Git has been initialized.\n.gitignore has been generated.')
29
+ print('To activate your venv, enter the following on the terminal:\n')
30
+ print(f'cd {self.project_path}\n')
31
+ if is_windows():
32
+ print('.\\.venv\\Scripts\\Activate.ps1 (On Powershell)')
33
+ print('.\\.venv\\Scripts\\activate.bat (On cmd)\n')
34
+ return True
35
+ else:
36
+ print('source .venv/bin/activate\n')
37
+ return True
38
+
39
+ else:
40
+ print(f'\nFailed to create {self.project_path} directory. Cleaning up half-baked files...')
41
+ fs_engine.cleanup()
42
+ return False
43
+
44
+ else:
45
+ print(f'"\n{self.project_name}" is not a valid directory name.')
46
+ return False
47
+
48
+ else:
49
+ print('\nPython is not installed in the local machine.')
50
+ return False
51
+
52
+
53
+ class CloneInitializer:
54
+
55
+ def __init__(self, repo_url: str, dir_name: str | None):
56
+ self.repo_url = repo_url
57
+ self.dir_name = dir_name if dir_name else None
58
+
59
+ def run(self) -> bool:
60
+ '''Runs when `repopy clone` is called'''
61
+ if has_python() and has_git():
62
+ if not is_valid_git_url(self.repo_url):
63
+ print('Invalid Git URL format')
64
+ return False
65
+
66
+ if self.dir_name:
67
+ predicted_name = self.dir_name
68
+ else:
69
+ cleaned_url = self.repo_url.removesuffix('.git')
70
+ predicted_name = Path(cleaned_url).name
71
+
72
+ if is_valid_project_name(str(predicted_name)):
73
+ git_engine = GitEngine(self.repo_url, self.dir_name)
74
+ fs_engine = FileSystemEngine(git_engine.project_path)
75
+
76
+ if git_engine.clone_repository():
77
+ if fs_engine.create_virtual_environment():
78
+ if git_engine.install_dependencies():
79
+ print(f'Success! GitHub repository has been cloned at {git_engine.project_path}.')
80
+ print(f'All dependancies have been installed from requirements.txt (if requirements.txt exists)')
81
+ print('To activate your venv, enter the following on the terminal:\n')
82
+ print(f'cd {git_engine.project_path}\n')
83
+ if is_windows():
84
+ print('.\\.venv\\Scripts\\Activate.ps1 (On Powershell)')
85
+ print('.\\.venv\\Scripts\\activate.bat (On cmd)\n')
86
+ return True
87
+ else:
88
+ print('source .venv/bin/activate\n')
89
+ return True
90
+
91
+ else:
92
+ print(f'GitHub repository has been clones at {git_engine.project_path}')
93
+ print(f'Failed to install dependencies from requirements.txt at {git_engine.project_path}')
94
+ print('To install dependencies, run the following on your terminal:\n')
95
+ print(f'cd {git_engine.project_path}\n')
96
+ if is_windows():
97
+ print('.\\.venv\\Scripts\\Activate.ps1 (On Powershell)')
98
+ print('.\\.venv\\Scripts\\activate.bat (On cmd)\n')
99
+ else:
100
+ print('source .venv/bin/activate\n')
101
+ print('pip install -r requirements.txt\n')
102
+ print('Or install them individually by `pip install <module>`\n')
103
+ answer = input('If not, would you like to cleanup the new directory? (Y/n): ')
104
+
105
+ if answer.strip().lower() in ['y', 'yes']:
106
+ print('Cleaning up half-baked files...')
107
+ git_engine.cleanup()
108
+ return False
109
+ else:
110
+ return True
111
+
112
+ else:
113
+ print(f'Failed to create {git_engine.project_path} directory. Cleaning up half-baked files...')
114
+ git_engine.cleanup()
115
+ return False
116
+
117
+ else:
118
+ return False
119
+
120
+ else:
121
+ print(f'"{predicted_name}" is not a valid directory name.')
122
+ return False
123
+
124
+ else:
125
+ print(f'Failed to initiate repopy due to absence of Python or Git on local machine.')
126
+ return False
@@ -0,0 +1,25 @@
1
+ '''
2
+ OS Detection layer. Contains the importable logic required to
3
+ find the local machine's underlying operating system.
4
+ '''
5
+
6
+ import platform
7
+
8
+ def get_os() -> str:
9
+ system = platform.system()
10
+
11
+ if system == 'Windows':
12
+ return 'windows'
13
+ if system == 'Darwin':
14
+ return 'mac'
15
+
16
+ return 'linux'
17
+
18
+ def is_windows() -> bool:
19
+ return get_os() == 'windows'
20
+
21
+ def is_mac() -> bool:
22
+ return get_os() == 'mac'
23
+
24
+ def is_linux() -> bool:
25
+ return get_os() == 'linux'
@@ -0,0 +1,53 @@
1
+ '''
2
+ Validation layer. Checks the validity of positional arguments
3
+ for both `repopy local` and `repopy clone`.
4
+ '''
5
+
6
+ from pathlib import Path
7
+ from urllib.parse import urlsplit
8
+
9
+ def is_valid_project_name(name: str) -> bool:
10
+ if not name or name.strip() == '':
11
+ return False
12
+
13
+ illegal_chars = {'<', '>', '/', '\\', ':', '*', '?', '"', '|', '!', '#'}
14
+ if not illegal_chars.isdisjoint(name):
15
+ return False
16
+
17
+ target_path = Path(name)
18
+ if target_path.is_dir():
19
+ return False
20
+
21
+ return True
22
+
23
+
24
+ def is_valid_git_url(url: str) -> bool:
25
+ if not url or not url.strip():
26
+ return False
27
+
28
+ if url.startswith('git@'):
29
+ if not url.startswith('git@github.com:'):
30
+ return False
31
+ try:
32
+ _, path = url.split(':', 1)
33
+ except ValueError:
34
+ return False
35
+
36
+ elif url.startswith(('https://', 'http://')):
37
+ if not url.startswith('https://github.com'):
38
+ return False
39
+ path = urlsplit(url).path
40
+
41
+ else:
42
+ return False
43
+
44
+ cleaned_path = path.rstrip('/')
45
+
46
+ if not cleaned_path.endswith('.git'):
47
+ return False
48
+
49
+ path_segments = [seg for seg in cleaned_path.split('/') if seg]
50
+ if len(path_segments) < 2 or path_segments[-1] == '.git':
51
+ return False
52
+
53
+ return True
@@ -0,0 +1,108 @@
1
+ Metadata-Version: 2.4
2
+ Name: repopy
3
+ Version: 0.1.0
4
+ Summary: A modular CLI workspace initializer and cloning automation tool.
5
+ License: MIT
6
+ Classifier: Programming Language :: Python :: 3
7
+ Classifier: License :: OSI Approved :: MIT License
8
+ Classifier: Operating System :: OS Independent
9
+ Requires-Python: >=3.8
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE
12
+ Dynamic: license-file
13
+
14
+ # repopy
15
+
16
+ A highly modular, cross-platform Python CLI scaffolding tool and library designed to automate the initial configuration of local Python developer workspaces and remote Python repository deployment.
17
+
18
+ [![PyPI Version](https://shields.io)](https://pypi.org)
19
+ [![Python Versions](https://shields.io)](https://pypi.org)
20
+ [![License: MIT](https://shields.io)](https://opensource.org)
21
+
22
+ ---
23
+
24
+ ## 🌟 Key Features
25
+
26
+ - **Local Scaffolding (`repopy local`)**: Instantly generates standardized directory trees, configures automated multi-line `.gitignore` presets, and initializes clean local Git repositories.
27
+
28
+ - **Remote Automation (`repopy clone`)**: Downloads remote repositories, parses project structures, and automatically updates localized environment constraints.
29
+
30
+ - **Isolated Virtual Environments**: Automatically builds localized `.venv` footprints using Python's native compilation layer.
31
+
32
+ - **Cross-Platform Compatibility**: Automatically detects structural variances between Windows, macOS, and Linux to run direct executions seamlessly.
33
+
34
+ ---
35
+
36
+ ## 🛠️ Architectural Highlights
37
+
38
+ This package was designed following production-grade software engineering principles:
39
+ - **Decoupled Low-Level Engines**: Features standalone layers (`FileSystemEngine` & `GitEngine`) that are entirely decoupled from CLI routing logic, making them fully reusable as an importable library API.
40
+
41
+ - **Single Responsibility Validation**: Separates terminal argument compilation (`argparse`) from explicit data sanitization filters (`validators.py`) and environmental prerequisite verification (`dependencies.py`).
42
+
43
+ - **Defensive Error Handling & Auto-Rollback**: Leverages short-circuit evaluations and interactive terminal input cascades. In the event of network or environment breaks during deployment, it offers automated transactional folder cleanups (`shutil.rmtree`) to prevent workspace pollution.
44
+
45
+ - **Direct-Execution Strategy**: Bypasses unstable, platform-dependent shell environment injections by directly target-executing localized virtual environment binaries (`pip`).
46
+
47
+ ---
48
+
49
+ ## 📥 Installation
50
+
51
+ You can install `repopy` globally from PyPI using pip:
52
+
53
+ ```bash
54
+ pip install repopy
55
+ ```
56
+
57
+ Alternatively, you can install the latest development version directly from source:
58
+
59
+ ```bash
60
+ git clone https://github.com/manatunga/repopy.git
61
+ cd repopy
62
+ pip install -e .
63
+ ```
64
+
65
+ ---
66
+
67
+ ## 🚀 Usage Guide
68
+
69
+ ### 1. Initialize a Local Project from Scratch
70
+ Generate a clean, standardized local environment with an operational virtual environment and pre-seeded `.gitignore` file:
71
+
72
+ ```bash
73
+ repopy local my-new-app
74
+ ```
75
+
76
+ ### 2. Clone and Auto-Provision a Remote Codebase
77
+ Clone an external codebase, create a virtual environment, scan for a `requirements.txt` file, and automatically install its dependencies:
78
+
79
+ ```bash
80
+ repopy clone https://github.comencode/httpx.git -n my-custom-workspace
81
+ ```
82
+
83
+ ---
84
+
85
+ ## 🗂️ Project Structure
86
+
87
+ ```text
88
+ repopy/
89
+ ├── src/
90
+ │ └── repopy/
91
+ │ ├── __init__.py # Package initialization
92
+ │ ├── __main__.py # Application root entry point
93
+ │ ├── cli.py # CLI Argument Parsing layer
94
+ │ ├── orchestrators.py # Architectural workflow supervision
95
+ │ ├── os_detector.py # Cross-platform OS translation utility
96
+ │ ├── dependencies.py # Binary prerequisite verification
97
+ │ ├── validators.py # Data input and path path verification
98
+ │ ├── file_system.py # Low-level file system engine
99
+ │ └── git_engine.py # Low-level shell compilation engine
100
+ ├── pyproject.toml # Build-system manifest & CLI script configuration
101
+ ├── .gitignore
102
+ ├── LICENSE # MIT License
103
+ └── README.md # Project documentation
104
+ ```
105
+
106
+ ## 📄 License
107
+
108
+ Distributed under the MIT License. See `LICENSE` for more details.
@@ -0,0 +1,17 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ src/repopy/__init__.py
5
+ src/repopy/__main__.py
6
+ src/repopy/cli.py
7
+ src/repopy/dependencies.py
8
+ src/repopy/file_system.py
9
+ src/repopy/git_engine.py
10
+ src/repopy/orchestrators.py
11
+ src/repopy/os_detector.py
12
+ src/repopy/validators.py
13
+ src/repopy.egg-info/PKG-INFO
14
+ src/repopy.egg-info/SOURCES.txt
15
+ src/repopy.egg-info/dependency_links.txt
16
+ src/repopy.egg-info/entry_points.txt
17
+ src/repopy.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ repopy = repopy.__main__:main
@@ -0,0 +1 @@
1
+ repopy