-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1144 from mrapp-ke/merge-bugfix
Merge bugfix into feature branch
- Loading branch information
Showing
136 changed files
with
6,688 additions
and
2,754 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
# Quality-of-Life Improvements | ||
|
||
- The build system now uses a lightweight custom implementation instead of [SCons](https://scons.org/) and is better modularized to avoid unnecessary runs of Continuous Integration jobs when only certain parts of it are modified. | ||
- Releases are now automated via Continuous Integration, including the update of the project's changelog. | ||
- The presentation of algorithmic parameters in the documentation has been improved. | ||
- Outdated GitHub Actions can now be printed via the build target `check_github_actions`. Alternatively, the build target `update_github_actions` may be used to update them automatically. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
""" | ||
Author: Michael Rapp ([email protected]) | ||
Provides classes that provide information about independent units of the build system. | ||
""" | ||
from os import path | ||
from typing import List | ||
|
||
|
||
class BuildUnit: | ||
""" | ||
An independent unit of the build system that may come with its own built-time dependencies. | ||
""" | ||
|
||
BUILD_SYSTEM_DIRECTORY = 'build_system' | ||
|
||
BUILD_DIRECTORY_NAME = 'build' | ||
|
||
def __init__(self, root_directory: str = BUILD_SYSTEM_DIRECTORY): | ||
""" | ||
:param root_directory: The root directory of this unit | ||
""" | ||
self.root_directory = root_directory | ||
|
||
@staticmethod | ||
def for_file(file) -> 'BuildUnit': | ||
""" | ||
Creates and returns a `BuildUnit` for a given file. | ||
:param file: The file for which a `BuildUnit` should be created | ||
:return: The `BuildUnit` that has been created | ||
""" | ||
return BuildUnit(path.relpath(path.dirname(file), path.dirname(BuildUnit.BUILD_SYSTEM_DIRECTORY))) | ||
|
||
@property | ||
def build_directory(self) -> str: | ||
""" | ||
The path to the build directory of this unit. | ||
""" | ||
return path.join(self.root_directory, self.BUILD_DIRECTORY_NAME) | ||
|
||
def find_requirements_files(self) -> List[str]: | ||
""" | ||
The path to the requirements file that specifies the build-time dependencies of this unit. | ||
""" | ||
requirements_files = [] | ||
current_directory = self.root_directory | ||
|
||
while path.basename(current_directory) != self.BUILD_SYSTEM_DIRECTORY: | ||
requirements_file = path.join(current_directory, 'requirements.txt') | ||
|
||
if path.isfile(requirements_file): | ||
requirements_files.append(requirements_file) | ||
|
||
current_directory = path.dirname(current_directory) | ||
|
||
return requirements_files |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
""" | ||
Author: Michael Rapp ([email protected]) | ||
Provides classes for detecting changes in files. | ||
""" | ||
import json | ||
|
||
from functools import cached_property | ||
from os import path | ||
from typing import Dict, List, Set | ||
|
||
from core.modules import Module | ||
from util.io import TextFile, create_directories | ||
|
||
|
||
class JsonFile(TextFile): | ||
""" | ||
Allows to read and write the content of a JSON file. | ||
""" | ||
|
||
@cached_property | ||
def json(self) -> Dict: | ||
""" | ||
The content of the JSON file as a dictionary. | ||
""" | ||
lines = self.lines | ||
|
||
if lines: | ||
return json.loads('\n'.join(lines)) | ||
|
||
return {} | ||
|
||
def write_json(self, dictionary: Dict): | ||
""" | ||
Writes a given dictionary to the JSON file. | ||
:param dictionary: The dictionary to be written | ||
""" | ||
self.write_lines(json.dumps(dictionary, indent=4)) | ||
|
||
def write_lines(self, *lines: str): | ||
super().write_lines(*lines) | ||
|
||
try: | ||
del self.json | ||
except AttributeError: | ||
pass | ||
|
||
|
||
class ChangeDetection: | ||
""" | ||
Allows to detect changes in tracked files. | ||
""" | ||
|
||
class CacheFile(JsonFile): | ||
""" | ||
A JSON file that stores checksums for tracked files. | ||
""" | ||
|
||
@staticmethod | ||
def __checksum(file: str) -> str: | ||
return str(path.getmtime(file)) | ||
|
||
def __init__(self, file: str): | ||
""" | ||
:param file: The path to the JSON file | ||
""" | ||
super().__init__(file, accept_missing=True) | ||
create_directories(path.dirname(file)) | ||
|
||
def update(self, module_name: str, files: Set[str]): | ||
""" | ||
Updates the checksums of given files. | ||
:param module_name: The name of the module, the files belong to | ||
:param files: A set that contains the paths of the files to be updated | ||
""" | ||
cache = self.json | ||
module_cache = cache.setdefault(module_name, {}) | ||
|
||
for invalid_key in [file for file in module_cache.keys() if file not in files]: | ||
del module_cache[invalid_key] | ||
|
||
for file in files: | ||
module_cache[file] = self.__checksum(file) | ||
|
||
if module_cache: | ||
cache[module_name] = module_cache | ||
else: | ||
del cache[module_name] | ||
|
||
if cache: | ||
self.write_json(cache) | ||
else: | ||
self.delete() | ||
|
||
def has_changed(self, module_name: str, file: str) -> bool: | ||
""" | ||
Returns whether a file has changed according to the cache or not. | ||
:param module_name: The name of the module, the file belongs to | ||
:param file: The file to be checked | ||
:return: True, if the file has changed, False otherwise | ||
""" | ||
module_cache = self.json.get(module_name, {}) | ||
return file not in module_cache or module_cache[file] != self.__checksum(file) | ||
|
||
def __init__(self, cache_file: str): | ||
""" | ||
:param cache_file: The path to the file that should be used for tracking files | ||
""" | ||
self.cache_file = ChangeDetection.CacheFile(cache_file) | ||
|
||
def track_files(self, module: Module, *files: str): | ||
""" | ||
Updates the cache to keep track of given files. | ||
:param module: The module, the files belong to | ||
:param files: The files to be tracked | ||
""" | ||
self.cache_file.update(str(module), set(files)) | ||
|
||
def get_changed_files(self, module: Module, *files: str) -> List[str]: | ||
""" | ||
Filters given files and returns only those that have changed. | ||
:param module: The module, the files belong to | ||
:param files: The files to be filtered | ||
:return: A list that contains the files that have changed | ||
""" | ||
module_name = str(module) | ||
return [file for file in files if self.cache_file.has_changed(module_name, file)] |
Oops, something went wrong.