1010pyproject.toml), and a template setup for documentation (e.g., using mkdocs),
1111setup of the build pipeline"""
1212
13+ import subprocess
14+ from pathlib import Path
15+ import logging
1316
17+ import requests
18+
19+ from deep_code .utils .helper import read_git_access_file
20+
21+ logging .basicConfig (level = logging .INFO )
22+ logger = logging .getLogger (__name__ )
23+
24+
25+ class RepositoryInitializer :
26+ """
27+ A utility class to initialize a GitHub repository with configuration files,
28+ a workflow notebook template, and a Python package template for DeepESDL experiment
29+ """
30+
31+ def __init__ (self , repo_name : str ):
32+ """
33+ Initialize the RepositoryInitializer.
34+ """
35+ self .repo_name = repo_name
36+ self .repo_dir = Path (repo_name ).absolute ()
37+ self .templates_dir = Path (__file__ ).parent / "templates"
38+ git_config = read_git_access_file ()
39+ self .github_username = git_config .get ("github-username" )
40+ self .github_token = git_config .get ("github-token" )
41+ if not self .github_username or not self .github_token :
42+ raise ValueError ("GitHub credentials are missing in the `.gitaccess` file." )
43+
44+ def create_local_repo (self ) -> None :
45+ """Create a local directory for the repository and initialize it as a Git repository."""
46+ logger .info (f"Creating local repository: { self .repo_dir } " )
47+ self .repo_dir .mkdir (parents = True , exist_ok = True )
48+ subprocess .run (["git" , "init" ], cwd = self .repo_dir , check = True )
49+
50+ def _load_template (self , template_name : str ) -> str :
51+ """Load a template file from the templates directory."""
52+ template_path = self .templates_dir / template_name
53+ if not template_path .exists ():
54+ raise FileNotFoundError (f"Template not found: { template_path } " )
55+ with open (template_path , "r" ) as file :
56+ return file .read ()
57+
58+ def create_config_files (self ) -> None :
59+ """Create configuration files in the repository."""
60+ logger .info ("Creating configuration files..." )
61+
62+ # Create README.md
63+ readme_content = (f"# { self .repo_name } \n \n This repository contains workflows "
64+ f"and Python code for a DeepESDL Experiment." )
65+ (self .repo_dir / "README.md" ).write_text (readme_content )
66+
67+ # Create .gitignore
68+ gitignore_content = self ._load_template (".gitignore" )
69+ (self .repo_dir / ".gitignore" ).write_text (gitignore_content )
70+
71+ def create_jupyter_notebook_template (self ) -> None :
72+ """Create a workflow notebook template (workflow.ipynb)."""
73+ logger .info ("Creating workflow notebook template..." )
74+ workflow_content = self ._load_template ("workflow.ipynb" )
75+ (self .repo_dir / "workflow.ipynb" ).write_text (workflow_content )
76+
77+ def create_python_package (self ) -> None :
78+ """Create a Python package template with a pyproject.toml file."""
79+ logger .info ("Creating Python package template..." )
80+
81+ # Create package directory
82+ package_dir = self .repo_dir / self .repo_name
83+ package_dir .mkdir (exist_ok = True )
84+
85+ # Create __init__.py
86+ (package_dir / "__init__.py" ).write_text ("# Package initialization\n " )
87+
88+ # Create pyproject.toml
89+ pyproject_content = self ._load_template ("pyproject.toml" )
90+ pyproject_content = pyproject_content .replace ("{repo_name}" , self .repo_name )
91+ (self .repo_dir / "pyproject.toml" ).write_text (pyproject_content )
92+
93+ def create_github_repo (self ) -> None :
94+ """Create a remote GitHub repository and push the local repository."""
95+ if not self .github_username or not self .github_token :
96+ logger .warning ("GitHub credentials not provided. Skipping remote repository creation." )
97+ return
98+
99+ logger .info ("Creating remote GitHub repository..." )
100+
101+ repo_url = "https://api.github.com/user/repos"
102+ repo_data = {
103+ "name" : self .repo_name ,
104+ "description" : "Repository for DeepESDL workflows and Python code." ,
105+ "private" : True ,
106+ }
107+ headers = {
108+ "Authorization" : f"token { self .github_token } " ,
109+ "Accept" : "application/vnd.github.v3+json" ,
110+ }
111+ response = requests .post (repo_url , json = repo_data , headers = headers )
112+ response .raise_for_status ()
113+
114+ remote_url = f"https://github.com/{ self .github_username } /{ self .repo_name } .git"
115+ subprocess .run (["git" , "remote" , "add" , "origin" , remote_url ], cwd = self .repo_dir , check = True )
116+ subprocess .run (["git" , "add" , "." ], cwd = self .repo_dir , check = True )
117+ subprocess .run (["git" , "commit" , "-m" , "Initial commit" ], cwd = self .repo_dir , check = True )
118+ subprocess .run (["git" , "push" , "-u" , "origin" , "main" ], cwd = self .repo_dir , check = True )
119+
120+ logger .info (f"Remote repository created: { remote_url } " )
121+
122+ def create_github_actions_workflow (self ) -> None :
123+ """Create a GitHub Actions workflow for running unit tests."""
124+ logger .info ("Creating GitHub Actions workflow..." )
125+
126+ workflows_dir = self .repo_dir / ".github" / "workflows"
127+ workflows_dir .mkdir (parents = True , exist_ok = True )
128+
129+ workflow_content = self ._load_template ("unit-tests.yml" )
130+ (workflows_dir / "unit-tests.yml" ).write_text (workflow_content )
131+
132+ def initialize (self ) -> None :
133+ """Initialize the repository with all templates and configurations."""
134+ self .create_local_repo ()
135+ self .create_config_files ()
136+ self .create_jupyter_notebook_template ()
137+ self .create_python_package ()
138+ self .create_github_repo ()
139+ logger .info (f"Repository '{ self .repo_name } ' initialized successfully!" )
140+
141+
142+ if __name__ == '__main__' :
143+ r = RepositoryInitializer ("deepesdl-test-experiment" )
144+ r .initialize ()
0 commit comments