Skip to content

Commit bb9ebf7

Browse files
authored
Updated Library to Pull From Two Repos Separately (#56)
* Incremented minor version * Renamed repo variable * Slowly working through website repo code * Correctly generated dir * Reworked init to generate the separate repos * Reworked some of the pathing * Ready to run some tests * Updated requirements.txt * Managed to get the code working * Updated changelog
1 parent b5caa63 commit bb9ebf7

File tree

5 files changed

+53
-55
lines changed

5 files changed

+53
-55
lines changed

docs/changelog.rst

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,18 @@ Changelog
44
Below you'll find all the changes that have been made to the code with
55
newest changes first.
66

7+
0.13.x
8+
------
9+
10+
* v0.13.0
11+
* Updated subete to pull from archive and docs separately, rather than relying on submodules which might be out of date
12+
713
0.12.x
814
------
915

16+
* v0.12.1
17+
* Fixed an issue where older versions of Git could not handle use of blame
18+
1019
* v0.12.0
1120
* Reworked the way project names are parsed to support new naming conventions
1221
* Cleaned up error logs for readability

requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ PyYAML==5.4.1
22
pytest==6.2.4
33
pytest-cov==2.12.1
44
GitPython==3.1.18
5+
sphinx_rtd_theme

setup.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@
1212
long_description = fh.read()
1313

1414
MAJOR = 0
15-
MINOR = 12
16-
PATCH = 1
15+
MINOR = 13
16+
PATCH = 0
1717

1818
name = "subete"
1919
version = f"{MAJOR}.{MINOR}"

subete/__init__.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from .repo import *
22

33

4-
def load(source_dir: str = None) -> Repo:
4+
def load(sample_programs_repo_dir: Optional[str] = None, sample_programs_website_repo_dir: Optional[str] = None) -> Repo:
55
"""
66
Loads the Sample Programs repo as a Repo object. This is
77
a convenience function which can be used to quickly generate
@@ -14,8 +14,11 @@ def load(source_dir: str = None) -> Repo:
1414
Optionally, you can also provide a source directory which
1515
bypasses the need for git on your system::
1616
17-
repo = subete.load(source_dir="path/to/sample-programs/archive")
17+
repo = subete.load(sample_programs_repo_dir="path/to/sample-programs/archive")
1818
1919
:return: the Sample Programs repo as a Repo object
2020
"""
21-
return Repo(source_dir=source_dir)
21+
return Repo(
22+
sample_programs_repo_dir=sample_programs_repo_dir,
23+
sample_programs_website_repo_dir=sample_programs_website_repo_dir
24+
)

subete/repo.py

Lines changed: 35 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -22,18 +22,41 @@ class Repo:
2222
:param str source_dir: the location of the repo archive (e.g., C://.../sample-programs/archive)
2323
"""
2424

25-
def __init__(self, source_dir: Optional[str] = None) -> None:
26-
self._temp_dir = tempfile.TemporaryDirectory()
27-
self._source_dir: str = self._generate_source_dir(source_dir)
28-
self._git_repo: git.Repo = self._generate_git_repo()
29-
self._docs_dir: str = self._generate_docs_dir(source_dir)
25+
def __init__(self, sample_programs_repo_dir: Optional[str] = None, sample_programs_website_repo_dir: Optional[str] = None) -> None:
26+
27+
# Sets up the sample programs repo variables
28+
self._sample_programs_temp_dir = tempfile.TemporaryDirectory()
29+
self._sample_programs_repo_dir = self._sample_programs_temp_dir.name
30+
if sample_programs_repo_dir:
31+
self._sample_programs_repo_dir = sample_programs_repo_dir
32+
self._sample_programs_repo: git.Repo = git.Repo(self._sample_programs_repo_dir, search_parent_directories=True)
33+
else:
34+
self._sample_programs_repo: git.Repo = git.Repo.clone_from("https://github.com/TheRenegadeCoder/sample-programs.git", self._sample_programs_repo_dir)
35+
36+
# Sets up the sample programs website repo variables
37+
self._sample_programs_website_temp_dir = tempfile.TemporaryDirectory()
38+
self._sample_programs_website_repo_dir = self._sample_programs_website_temp_dir.name
39+
if sample_programs_website_repo_dir:
40+
self._sample_programs_website_repo_dir = sample_programs_website_repo_dir
41+
self._sample_programs_website_repo: git.Repo = git.Repo(self._sample_programs_website_repo_dir, search_parent_directories=True)
42+
else:
43+
self._sample_programs_website_repo: git.Repo = git.Repo.clone_from("https://github.com/TheRenegadeCoder/sample-programs-website.git", self._sample_programs_website_repo_dir)
44+
45+
# Sets up paths to relevant directories
46+
self._docs_dir: str = os.path.join(self._sample_programs_website_repo_dir, "docs")
47+
self._archive_dir: str = os.path.join(self._sample_programs_repo_dir, "archive")
48+
49+
# Performs data collection from the repos
3050
self._tested_projects: Dict = self._collect_tested_projects()
3151
self._projects: List[Project] = self._collect_projects()
3252
self._languages: Dict[str: LanguageCollection] = self._collect_languages()
3353
self._total_snippets: int = sum(x.total_programs() for _, x in self._languages.items())
3454
self._total_tests: int = sum(1 for _, x in self._languages.items() if x.has_testinfo())
3555
self._load_git_data()
36-
self._git_repo.close() # Closes the repo before cleaning up the temp dir
56+
57+
# Closes repositories
58+
self._sample_programs_repo.close()
59+
self._sample_programs_website_repo.close()
3760

3861
def __getitem__(self, language: str) -> LanguageCollection:
3962
"""
@@ -172,7 +195,7 @@ def sorted_language_letters(self) -> List[str]:
172195
173196
:return: a sorted list of letters
174197
"""
175-
unsorted_letters = os.listdir(self._source_dir)
198+
unsorted_letters = os.listdir(self._archive_dir)
176199
return sorted(unsorted_letters, key=lambda s: s.casefold())
177200

178201
def _collect_languages(self) -> Dict[str, LanguageCollection]:
@@ -182,7 +205,7 @@ def _collect_languages(self) -> Dict[str, LanguageCollection]:
182205
:return: the list of language collections
183206
"""
184207
languages = {}
185-
for root, directories, files in os.walk(self._source_dir):
208+
for root, directories, files in os.walk(self._archive_dir):
186209
if not directories:
187210
language = LanguageCollection(os.path.basename(root), root, files, self._projects)
188211
languages[str(language)] = language
@@ -206,50 +229,12 @@ def _collect_projects(self) -> List[Project]:
206229
projects.append(Project(project_dir.name, project_test))
207230
return projects
208231

209-
def _generate_source_dir(self, source_dir: Optional[str]) -> str:
210-
"""
211-
A helper method which generates the Sample Programs repo
212-
from Git if it's not provided on the source directory.
213-
214-
:return: a path to the source directory of the archive directory
215-
"""
216-
if not source_dir:
217-
logger.info(f"Source directory is not provided. Using temp directory {self._temp_dir.name}.")
218-
return os.path.join(self._temp_dir.name, "archive")
219-
logger.info(f"Source directory provided: {source_dir}")
220-
return source_dir
221-
222-
def _generate_git_repo(self) -> git.Repo:
223-
"""
224-
Generates the Git repository from the Sample Programs repo.
225-
226-
:return: a Git repository object
227-
"""
228-
if self._temp_dir.name in self._source_dir:
229-
return git.Repo.clone_from("https://github.com/TheRenegadeCoder/sample-programs.git", self._temp_dir.name, multi_options=["--recursive"])
230-
else:
231-
return git.Repo(self._source_dir, search_parent_directories=True)
232-
233-
def _generate_docs_dir(self, source_dir: Optional[str]) -> str:
234-
"""
235-
A helper methods which generates the path to the documentation.
236-
This method is needed because the provided source directory is meant
237-
to point at archive (for historical purposes). This is normally
238-
a non-issue if the directory is generated using Git, but can be more
239-
annoying if the user provides a source.
240-
241-
:return: a path to the documentation directory
242-
"""
243-
if not source_dir:
244-
return os.path.join(self._temp_dir.name, "docs", "sources")
245-
return os.path.join(source_dir, os.pardir, "docs", "sources")
246-
247232
def _collect_tested_projects(self) -> str:
248233
"""
249234
Generates the dictionary of tested projects from the
250235
Glotter YAML file.
251236
"""
252-
p = Path(self._source_dir).parents[0] / ".glotter.yml"
237+
p = Path(self._sample_programs_repo_dir) / ".glotter.yml"
253238
if p.exists():
254239
with open(p, "r") as f:
255240
data = yaml.safe_load(f)["projects"]
@@ -260,22 +245,22 @@ def _collect_tested_projects(self) -> str:
260245

261246
def _load_git_data(self) -> None:
262247
"""
263-
One the repo is loaded, this method will load the git data from the repo
248+
Once the repo is loaded, this method will load the git data from the repo
264249
and inject that data into the repo object. This was done for simplicity.
265250
It seems like way more of a pain to try to pass the git data around.
266251
"""
267252

268253
# Make sure .git-blame-ignore-revs exists for older versions of git and
269254
# keep track of whether it existed before
270-
blame_path = Path(f"{self._temp_dir.name}/.git-blame-ignore-revs")
255+
blame_path = Path(f"{self._sample_programs_temp_dir.name}/.git-blame-ignore-revs")
271256
blame_path_exists = blame_path.exists()
272257
blame_path.touch()
273258

274259
for language in self:
275260
language: LanguageCollection
276261
for program in language:
277262
program: SampleProgram
278-
blame = self._git_repo.blame('HEAD', f"{program._path}/{program._file_name}")
263+
blame = self._sample_programs_repo.blame('HEAD', f"{program._path}/{program._file_name}")
279264
times = []
280265
for commit, _ in blame:
281266
commit: git.Commit

0 commit comments

Comments
 (0)