repopy 0.1.0__tar.gz → 0.2.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.2.0/PKG-INFO ADDED
@@ -0,0 +1,176 @@
1
+ Metadata-Version: 2.4
2
+ Name: repopy
3
+ Version: 0.2.0
4
+ Summary: A modular CLI workspace initializer and cloning automation tool.
5
+ Author-email: Janitha Manatunga <janithamanatunga@gmail.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/manatunga/repopy
8
+ Project-URL: Repository, https://github.com/manatunga/repopy
9
+ Project-URL: Bug Tracker, https://github.com/manatunga/repopy/issues
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3 :: Only
12
+ Classifier: Programming Language :: Python :: 3.8
13
+ Classifier: Programming Language :: Python :: 3.9
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Programming Language :: Python :: 3.14
19
+ Classifier: Operating System :: OS Independent
20
+ Classifier: License :: OSI Approved :: MIT License
21
+ Requires-Python: >=3.8
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Dynamic: license-file
25
+
26
+ # repopy
27
+
28
+ A modular, cross-platform Python CLI workspace manager and developer tooling suite designed to automate reproducible local scaffolding, virtual environment creation, and remote repository synchronization.
29
+
30
+ ![PyPI - Version](https://img.shields.io/pypi/v/repopy?color=orange)&nbsp;&nbsp;&nbsp;
31
+ [![CI](https://github.com/manatunga/repopy/actions/workflows/tests.yml/badge.svg)](https://github.com/manatunga/repopy/actions/workflows/tests.yml)&nbsp;&nbsp;&nbsp;
32
+ [![Python Versions](https://img.shields.io/pypi/pyversions/repopy.svg)](https://pypi.org)&nbsp;&nbsp;&nbsp;
33
+ [![License: MIT](https://img.shields.io/pypi/l/repopy.svg)](https://opensource.org/license/mit)
34
+
35
+ ---
36
+
37
+ ## 🌟 Key Features
38
+
39
+ - **Lifecycle Project Scaffolding (`repopy init`)**: Replaces manual setup by provisioning clean directory structures, virtual environments, automated `.gitignore` presets, and standardized metadata configurations (`pyproject.toml` or `requirements.txt`).
40
+
41
+ - **Remote Cloning (`repopy clone`)**: Clones remote Git repositories into structured local footprints and auto-provisions dedicated virtual environments and dependencies.
42
+
43
+ - **Upstream Linking (`repopy link`)**: Instantly connects an unlinked local workspace to a remote Git upstream, staging files, executing initial commits, and pushing to the default branch in one step.
44
+
45
+ - **Architectural Themes**: Supports presets (`minimal`, `web_api`, `cli_package`, `data_science`) tailored to the specific packaging needs of the application.
46
+
47
+ - **Transactional Cleanups**: Employs defensive rollback mechanisms (`shutil.rmtree`) to purge incomplete workspaces if initialization fails midway.
48
+
49
+ - **Automated Test Suite & CI**: Fully covered by local `pytest` test suites and verified via continuous integration on GitHub Actions.
50
+
51
+ ---
52
+
53
+ ## 🛠️ Architecture & Separation of Concerns
54
+
55
+ `repopy` is organized into single-responsibility layers:
56
+ - **Presentation & Routing (`cli.py`, `prompts.py`, `__main__.py`)**: Evaluates native terminal arguments via `argparse`, orchestrates interactive prompt flows, and handles OS interrupts gracefully.
57
+
58
+ - **Supervision (`orchestrators.py`)**: Broker layer executing lifecycle validation checks, branch sequencing, and command handoffs.
59
+
60
+ - **Low-Level Engines (`file_system.py`, `git_engine.py`)**: Decoupled engines handling transactional directory allocations, venv isolation, and direct subprocess execution.
61
+
62
+ - **Validation & Translation (`validators.py`, `dependencies.py`, `os_detector.py`)**: Sanitizes paths, ensures semantic regex compliance, verifies system binaries (such as `git`), and resolves cross-platform paths.
63
+
64
+ ---
65
+
66
+ ## 📥 Installation
67
+
68
+ Install the latest release from PyPI:
69
+
70
+ ```bash
71
+ pip install repopy
72
+ ```
73
+ Alternatively, you can install the latest development version directly from the source:
74
+
75
+ ```bash
76
+ git clone https://github.com/manatunga/repopy.git
77
+ cd repopy
78
+ pip install -e .
79
+ ```
80
+
81
+ ---
82
+
83
+ ## 🚀 Usage Guide
84
+
85
+ ### 1. Initialize a Project (`repopy init`)
86
+ Generate a new workspace interactively or via CLI flags:
87
+
88
+ ```bash
89
+ # Interactive setup
90
+ repopy init my-app
91
+
92
+ # Non-interactive generation with a specific theme
93
+ repopy init my-api -t web_api -s
94
+
95
+ # Initialize and immediately connect to a remote repository
96
+ repopy init my-cli -t cli_package --link <git-url>
97
+ ```
98
+
99
+ #### Available Themes:
100
+ - `minimal`: Bare directory setup with `requirements.txt`.
101
+ - `web_api`: Layered service layout prepared for modern frameworks.
102
+ - `cli_package`: Modular structure configured with PEP 621 compliant `pyproject.toml`.
103
+ - `data_science`: Notebooks, data folders, and pipeline layouts.
104
+ <br>
105
+ <br>
106
+
107
+ ### 2. Clone a Remote Project (`repopy clone`)
108
+ Fetch a remote repository and immediately auto-provision an isolated `.venv`:
109
+
110
+ ```bash
111
+ repopy clone <git-url> -n [custom-project-name]
112
+ ```
113
+
114
+ <br>
115
+
116
+ ### 3. Link an Existing Workspace (`repopy link`)
117
+ Run inside an existing workspace to push tracking history to an upstream origin:
118
+
119
+ ```bash
120
+ repopy link <git-url> -m ["custom-initial-commit-message"]
121
+ ```
122
+
123
+ ---
124
+
125
+ ## 🧪 Testing & Continuous Integration
126
+
127
+ Run the test suite using `pytest`:
128
+
129
+ ```bash
130
+ pytest -v
131
+ ```
132
+
133
+ All contributions and pull requests are validated through our GitHub Actions workflow matrix (`.github/workflows/tests.yml`), running integration and validation tests across supported Python versions.
134
+
135
+ ---
136
+
137
+ ## 🗂️ Project Structure
138
+
139
+ ```
140
+ repopy/
141
+ ├── .github/
142
+ │ └── workflows/
143
+ │ └── tests.yml # CI test runner pipeline
144
+ ├── src/
145
+ │ └── repopy/
146
+ │ ├── __init__.py # Package initialization
147
+ │ ├── __main__.py # Application execution entry
148
+ │ ├── cli.py # CLI subparser configuration
149
+ │ ├── dependencies.py # Binary prerequisite verification
150
+ │ ├── file_system.py # Atomic workspace & venv operations
151
+ │ ├── git_engine.py # Subprocess Git execution engine
152
+ │ ├── orchestrators.py # High-level pipeline management
153
+ │ ├── os_detector.py # Cross-platform environment resolver
154
+ │ ├── prompts.py # Dynamic terminal questionnaires
155
+ │ ├── templates.py # Static asset definitions & manifests
156
+ │ └── validators.py # Input sanitation & regex filters
157
+ ├── tests/
158
+ │ ├── test_prompts.py # Input loop & default manifest tests
159
+ │ └── test_validators.py # Path and schema validation tests
160
+ ├── pyproject.toml # PEP 621 packaging configuration
161
+ ├── LICENSE # MIT License
162
+ └── README.md
163
+ ```
164
+
165
+ ---
166
+
167
+ ## 📄 License
168
+
169
+ Distributed under the MIT License. See `LICENSE` for details.
170
+
171
+ ---
172
+
173
+ ## Key Review Notes
174
+
175
+ * Verify the GitHub Actions workflow file path (`.github/workflows/tests.yml`) matches your actual workflow file name so the build badge renders correctly.
176
+ * In the `repopy init` theme section, verify that the theme descriptions match what you have mapped out in `templates.py`.
repopy-0.2.0/README.md ADDED
@@ -0,0 +1,151 @@
1
+ # repopy
2
+
3
+ A modular, cross-platform Python CLI workspace manager and developer tooling suite designed to automate reproducible local scaffolding, virtual environment creation, and remote repository synchronization.
4
+
5
+ ![PyPI - Version](https://img.shields.io/pypi/v/repopy?color=orange)&nbsp;&nbsp;&nbsp;
6
+ [![CI](https://github.com/manatunga/repopy/actions/workflows/tests.yml/badge.svg)](https://github.com/manatunga/repopy/actions/workflows/tests.yml)&nbsp;&nbsp;&nbsp;
7
+ [![Python Versions](https://img.shields.io/pypi/pyversions/repopy.svg)](https://pypi.org)&nbsp;&nbsp;&nbsp;
8
+ [![License: MIT](https://img.shields.io/pypi/l/repopy.svg)](https://opensource.org/license/mit)
9
+
10
+ ---
11
+
12
+ ## 🌟 Key Features
13
+
14
+ - **Lifecycle Project Scaffolding (`repopy init`)**: Replaces manual setup by provisioning clean directory structures, virtual environments, automated `.gitignore` presets, and standardized metadata configurations (`pyproject.toml` or `requirements.txt`).
15
+
16
+ - **Remote Cloning (`repopy clone`)**: Clones remote Git repositories into structured local footprints and auto-provisions dedicated virtual environments and dependencies.
17
+
18
+ - **Upstream Linking (`repopy link`)**: Instantly connects an unlinked local workspace to a remote Git upstream, staging files, executing initial commits, and pushing to the default branch in one step.
19
+
20
+ - **Architectural Themes**: Supports presets (`minimal`, `web_api`, `cli_package`, `data_science`) tailored to the specific packaging needs of the application.
21
+
22
+ - **Transactional Cleanups**: Employs defensive rollback mechanisms (`shutil.rmtree`) to purge incomplete workspaces if initialization fails midway.
23
+
24
+ - **Automated Test Suite & CI**: Fully covered by local `pytest` test suites and verified via continuous integration on GitHub Actions.
25
+
26
+ ---
27
+
28
+ ## 🛠️ Architecture & Separation of Concerns
29
+
30
+ `repopy` is organized into single-responsibility layers:
31
+ - **Presentation & Routing (`cli.py`, `prompts.py`, `__main__.py`)**: Evaluates native terminal arguments via `argparse`, orchestrates interactive prompt flows, and handles OS interrupts gracefully.
32
+
33
+ - **Supervision (`orchestrators.py`)**: Broker layer executing lifecycle validation checks, branch sequencing, and command handoffs.
34
+
35
+ - **Low-Level Engines (`file_system.py`, `git_engine.py`)**: Decoupled engines handling transactional directory allocations, venv isolation, and direct subprocess execution.
36
+
37
+ - **Validation & Translation (`validators.py`, `dependencies.py`, `os_detector.py`)**: Sanitizes paths, ensures semantic regex compliance, verifies system binaries (such as `git`), and resolves cross-platform paths.
38
+
39
+ ---
40
+
41
+ ## 📥 Installation
42
+
43
+ Install the latest release from PyPI:
44
+
45
+ ```bash
46
+ pip install repopy
47
+ ```
48
+ Alternatively, you can install the latest development version directly from the source:
49
+
50
+ ```bash
51
+ git clone https://github.com/manatunga/repopy.git
52
+ cd repopy
53
+ pip install -e .
54
+ ```
55
+
56
+ ---
57
+
58
+ ## 🚀 Usage Guide
59
+
60
+ ### 1. Initialize a Project (`repopy init`)
61
+ Generate a new workspace interactively or via CLI flags:
62
+
63
+ ```bash
64
+ # Interactive setup
65
+ repopy init my-app
66
+
67
+ # Non-interactive generation with a specific theme
68
+ repopy init my-api -t web_api -s
69
+
70
+ # Initialize and immediately connect to a remote repository
71
+ repopy init my-cli -t cli_package --link <git-url>
72
+ ```
73
+
74
+ #### Available Themes:
75
+ - `minimal`: Bare directory setup with `requirements.txt`.
76
+ - `web_api`: Layered service layout prepared for modern frameworks.
77
+ - `cli_package`: Modular structure configured with PEP 621 compliant `pyproject.toml`.
78
+ - `data_science`: Notebooks, data folders, and pipeline layouts.
79
+ <br>
80
+ <br>
81
+
82
+ ### 2. Clone a Remote Project (`repopy clone`)
83
+ Fetch a remote repository and immediately auto-provision an isolated `.venv`:
84
+
85
+ ```bash
86
+ repopy clone <git-url> -n [custom-project-name]
87
+ ```
88
+
89
+ <br>
90
+
91
+ ### 3. Link an Existing Workspace (`repopy link`)
92
+ Run inside an existing workspace to push tracking history to an upstream origin:
93
+
94
+ ```bash
95
+ repopy link <git-url> -m ["custom-initial-commit-message"]
96
+ ```
97
+
98
+ ---
99
+
100
+ ## 🧪 Testing & Continuous Integration
101
+
102
+ Run the test suite using `pytest`:
103
+
104
+ ```bash
105
+ pytest -v
106
+ ```
107
+
108
+ All contributions and pull requests are validated through our GitHub Actions workflow matrix (`.github/workflows/tests.yml`), running integration and validation tests across supported Python versions.
109
+
110
+ ---
111
+
112
+ ## 🗂️ Project Structure
113
+
114
+ ```
115
+ repopy/
116
+ ├── .github/
117
+ │ └── workflows/
118
+ │ └── tests.yml # CI test runner pipeline
119
+ ├── src/
120
+ │ └── repopy/
121
+ │ ├── __init__.py # Package initialization
122
+ │ ├── __main__.py # Application execution entry
123
+ │ ├── cli.py # CLI subparser configuration
124
+ │ ├── dependencies.py # Binary prerequisite verification
125
+ │ ├── file_system.py # Atomic workspace & venv operations
126
+ │ ├── git_engine.py # Subprocess Git execution engine
127
+ │ ├── orchestrators.py # High-level pipeline management
128
+ │ ├── os_detector.py # Cross-platform environment resolver
129
+ │ ├── prompts.py # Dynamic terminal questionnaires
130
+ │ ├── templates.py # Static asset definitions & manifests
131
+ │ └── validators.py # Input sanitation & regex filters
132
+ ├── tests/
133
+ │ ├── test_prompts.py # Input loop & default manifest tests
134
+ │ └── test_validators.py # Path and schema validation tests
135
+ ├── pyproject.toml # PEP 621 packaging configuration
136
+ ├── LICENSE # MIT License
137
+ └── README.md
138
+ ```
139
+
140
+ ---
141
+
142
+ ## 📄 License
143
+
144
+ Distributed under the MIT License. See `LICENSE` for details.
145
+
146
+ ---
147
+
148
+ ## Key Review Notes
149
+
150
+ * Verify the GitHub Actions workflow file path (`.github/workflows/tests.yml`) matches your actual workflow file name so the build badge renders correctly.
151
+ * In the `repopy init` theme section, verify that the theme descriptions match what you have mapped out in `templates.py`.
@@ -0,0 +1,37 @@
1
+ [build-system]
2
+ requires = ["setuptools>=61.0.0"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "repopy"
7
+ version = "0.2.0"
8
+ description = "A modular CLI workspace initializer and cloning automation tool."
9
+ readme = "README.md"
10
+ requires-python = ">=3.8"
11
+ license = {text = "MIT"}
12
+
13
+ authors = [
14
+ {name = "Janitha Manatunga", email = "janithamanatunga@gmail.com"}
15
+ ]
16
+
17
+ classifiers = [
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: Python :: 3 :: Only",
20
+ "Programming Language :: Python :: 3.8",
21
+ "Programming Language :: Python :: 3.9",
22
+ "Programming Language :: Python :: 3.10",
23
+ "Programming Language :: Python :: 3.11",
24
+ "Programming Language :: Python :: 3.12",
25
+ "Programming Language :: Python :: 3.13",
26
+ "Programming Language :: Python :: 3.14",
27
+ "Operating System :: OS Independent",
28
+ "License :: OSI Approved :: MIT License",
29
+ ]
30
+
31
+ [project.urls]
32
+ Homepage = "https://github.com/manatunga/repopy"
33
+ Repository = "https://github.com/manatunga/repopy"
34
+ "Bug Tracker" = "https://github.com/manatunga/repopy/issues"
35
+
36
+ [project.scripts]
37
+ repopy = "repopy.__main__:main"
@@ -0,0 +1,45 @@
1
+ '''
2
+ Main entrypoint of repopy. Brings together the argument parser and
3
+ the orchestrators together under a main function.
4
+ '''
5
+ import sys
6
+ from repopy.cli import parse_arguments
7
+ from repopy.prompts import capture_project_manifests
8
+ from repopy.orchestrators import LocalInitializer, CloneInitializer, LinkInitializer
9
+
10
+ def main() -> None:
11
+ try:
12
+ args = parse_arguments()
13
+
14
+ if args.command == 'init':
15
+ print('Working on it...\n')
16
+ manifest = capture_project_manifests(args)
17
+ initializer = LocalInitializer(manifest)
18
+ success = initializer.run()
19
+
20
+ if success and args.link:
21
+ print('Initiating automated repository link shortcut...')
22
+ link_initializer = LinkInitializer(args.link, args.message)
23
+ link_initializer.run()
24
+
25
+ elif args.command == 'clone':
26
+ print('Working on it...\n')
27
+ initializer = CloneInitializer(args.repo_url, args.name)
28
+ initializer.run()
29
+
30
+ elif args.command == 'link':
31
+ print('Working on it...\n')
32
+ initializer = LinkInitializer(args.repo_url, args.message)
33
+ initializer.run()
34
+
35
+ else:
36
+ print('Usage: repopy [local | clone] --help')
37
+ print('Error: Please specify a subcommand')
38
+
39
+ except KeyboardInterrupt:
40
+ print('\n Workspace operation cancelled by user.')
41
+ sys.exit(1)
42
+
43
+
44
+ if __name__ == '__main__':
45
+ main()
@@ -0,0 +1,99 @@
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
+ description='repopy: A modular project scaffolder and workflow manager for Python.'
11
+ )
12
+
13
+ subparsers = parser.add_subparsers(dest='command', required=True)
14
+
15
+ #---------------------------------------------------------------------------------
16
+ # `repopy init` subcommand
17
+ #---------------------------------------------------------------------------------
18
+
19
+ init_parser = subparsers.add_parser(
20
+ 'init',
21
+ help='Initializes a standardized Python development workspace in a new directory'
22
+ )
23
+
24
+ # Optional argument to add a project_name
25
+ init_parser.add_argument(
26
+ 'project_name',
27
+ nargs='?',
28
+ help='Name of the target project folder to create'
29
+ )
30
+
31
+ # Project theme shortcut flag (-t / --theme)
32
+ init_parser.add_argument(
33
+ '-t', '--theme',
34
+ choices=['minimal', 'web_api', 'cli_package', 'data_science'],
35
+ help='Pre-select an architectural theme layout'
36
+ )
37
+
38
+ # Skip flag (-s / --skip) to bypass input prompts completely
39
+ init_parser.add_argument(
40
+ '-s', '--skip',
41
+ action='store_true',
42
+ help='Skip interactive loops and generate workspace using default values'
43
+ )
44
+
45
+ # Link flag (-l / --link) to pass an existing remote URL during creation
46
+ init_parser.add_argument(
47
+ '-l', '--link',
48
+ metavar='GIT_URL',
49
+ help='Automatically link and push the new local repo to this remote Git URL'
50
+ )
51
+
52
+ # Custom commit message shortcut allowed directly during init orchestration
53
+ init_parser.add_argument(
54
+ '-m', '--message',
55
+ help='Custom commit message to use for the initial repository push'
56
+ )
57
+
58
+ #---------------------------------------------------------------------------------
59
+ # `repopy clone` subcommand
60
+ #---------------------------------------------------------------------------------
61
+
62
+ clone_parser = subparsers.add_parser(
63
+ 'clone',
64
+ help='Clones a remote Git repository to the local machine'
65
+ )
66
+
67
+ # Positional argument to add remote Git URL
68
+ clone_parser.add_argument(
69
+ 'repo_url',
70
+ help='Repository URL from Github to clone locally'
71
+ )
72
+
73
+ # Name flag (-n / --name) to pass an optional name for the to-be-cloned repository
74
+ clone_parser.add_argument(
75
+ '-n', '--name',
76
+ help='Name of the project folder'
77
+ )
78
+
79
+ #---------------------------------------------------------------------------------
80
+ # `repopy link` subcommand
81
+ #---------------------------------------------------------------------------------
82
+
83
+ link_parser = subparsers.add_parser(
84
+ 'link',
85
+ help='Stage, commit and link current local repository to a remote Git URL'
86
+ )
87
+
88
+ # Positional argument to add a dedicated existing remote Git URL for the local repository
89
+ link_parser.add_argument(
90
+ 'repo_url',
91
+ help='Target remote Git repository URL (e.g., git@github.com:user/repo.git)'
92
+ )
93
+
94
+ link_parser.add_argument(
95
+ '-m', '--message',
96
+ help='Custom commit message to use instead of the default repopy message'
97
+ )
98
+
99
+ return parser.parse_args()
@@ -10,30 +10,12 @@ import logging
10
10
  import subprocess
11
11
  from pathlib import Path
12
12
 
13
+ from repopy.templates import GITIGNORE_TEMPLATE, generate_pyproject_toml
14
+
13
15
  logger = logging.getLogger(__name__)
14
16
 
15
17
  class FileSystemEngine:
16
18
 
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
19
  def __init__(self, project_path: Path):
38
20
  self.project_path = project_path
39
21
 
@@ -49,17 +31,54 @@ Thumbs_db'''
49
31
  return False
50
32
 
51
33
 
52
- def create_gitignore(self) -> bool:
53
- '''Generates a .gitignore file with a basic python gitignore template'''
54
- gitignore_file = self.project_path / '.gitignore'
34
+ def create_theme_directories(self, theme: str, project_name: str):
35
+ '''Maps and structures the child directory tree based on the project theme'''
36
+ if theme == 'web_api':
37
+ sub_dirs = ['src/app', 'src/app/routes', 'src/app/models']
38
+
39
+ elif theme == 'cli_package':
40
+ sub_dirs = [f'src/{project_name}', 'tests']
41
+
42
+ elif theme == 'data_science':
43
+ sub_dirs = ['data/raw', 'data/processed', 'notebooks', 'src/pipeline']
44
+
45
+ else:
46
+ return True
55
47
 
56
48
  try:
57
- with open(gitignore_file, 'w') as f:
58
- f.write(self.GITIGNORE_TEMPLATE)
59
- return True
60
-
49
+ for folder in sub_dirs:
50
+ target_folder_path = (self.project_path / folder).resolve()
51
+ target_folder_path.mkdir(parents=True, exist_ok=True)
52
+
53
+ return True
54
+
55
+ except OSError as e:
56
+ logger.error(f'Failed to build nested structures for theme {theme}: {e}')
57
+ return False
58
+
59
+
60
+ def write_theme_configurations(self, theme: str, manifest: dict) -> bool:
61
+ '''Deploys standard configuration templates (gitignore, requirements.txt or toml)'''
62
+ try:
63
+ gitignore_path = self.project_path / '.gitignore'
64
+ with open(gitignore_path, 'w') as f:
65
+ f.write(GITIGNORE_TEMPLATE)
66
+
67
+ if theme == 'minimal':
68
+ req_path = self.project_path / 'requirements.txt'
69
+ with open(req_path, 'w') as f:
70
+ f.write('')
71
+
72
+ else:
73
+ toml_content = generate_pyproject_toml(manifest)
74
+ toml_path = self.project_path / 'pyproject.toml'
75
+ with open(toml_path, 'w') as f:
76
+ f.write(toml_content)
77
+
78
+ return True
79
+
61
80
  except OSError as e:
62
- logger.error(f'Failed to create gitignore file at {self.project_path}: {e}')
81
+ logger.error(f'Failed to deploy structural file sheets: {e}')
63
82
  return False
64
83
 
65
84
 
@@ -96,13 +115,14 @@ Thumbs_db'''
96
115
  logger.error(f'Failed to clean up directory at {self.project_path}: {e}')
97
116
 
98
117
 
99
- def build_workspace(self) -> bool:
118
+ def build_workspace(self, theme: str, manifest: dict) -> bool:
100
119
  '''Orchestrate entire file-system creation sequence'''
101
120
 
102
121
  if self.create_root_directory():
103
122
  if self.initialize_git():
104
- if self.create_gitignore():
105
- if self.create_virtual_environment():
106
- return True
123
+ if self.create_theme_directories(theme, manifest['project_name']):
124
+ if self.write_theme_configurations(theme, manifest):
125
+ if self.create_virtual_environment():
126
+ return True
107
127
 
108
128
  return False
@@ -61,4 +61,42 @@ class GitEngine:
61
61
  logger.info(f'Successfully cleaned up half-baked workspace at {self.project_path}')
62
62
  except OSError as e:
63
63
  logger.error(f'Failed to clean up directory at {self.project_path}: {e}')
64
-
64
+
65
+
66
+ class GitLinkEngine:
67
+
68
+ def __init__(self, repo_url: str, message: str):
69
+ self.repo_url = repo_url
70
+ self.message = message
71
+
72
+
73
+ def link_and_push(self) -> bool:
74
+ '''Runs the sequence of Git terminal execution blocks to link the repo'''
75
+ try:
76
+ stage_result = subprocess.run(['git', 'add', '.'], capture_output=True, text=True)
77
+ if stage_result.returncode != 0:
78
+ return False
79
+
80
+ commit_result = subprocess.run(['git', 'commit', '-m', self.message], capture_output=True, text=True)
81
+ if commit_result.returncode != 0:
82
+ if 'nothing to commit' not in commit_result.stdout:
83
+ return False
84
+
85
+ branch_result = subprocess.run(['git', 'branch', '-M', 'main'], capture_output=True, text=True)
86
+ if branch_result.returncode != 0:
87
+ return False
88
+
89
+ remote_result = subprocess.run(['git', 'remote', 'add', 'origin', self.repo_url], capture_output=True, text=True)
90
+ if remote_result.returncode != 0:
91
+ return False
92
+
93
+ push_result = subprocess.run(['git', 'push', '-u', 'origin', 'main'], text=True)
94
+ if push_result.returncode != 0:
95
+ return False
96
+
97
+ return True
98
+
99
+ except OSError as e:
100
+ logger.error(f'Failed to execute Git linking operationsL {e}')
101
+ return False
102
+