Skip to content

Commit

Permalink
Merge branch other/next-release into main
Browse files Browse the repository at this point in the history
  • Loading branch information
anionDev committed Nov 25, 2024
2 parents de9023f + 659f78d commit d4ab370
Show file tree
Hide file tree
Showing 9 changed files with 89 additions and 25 deletions.
6 changes: 6 additions & 0 deletions Other/Resources/Changelog/v3.5.32.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Release notes

## Changes

- Little improvements.
- Added `create_changelog_entry`.
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<coverage version="1.0" date="2024-11-25_14-09-07" tag="v3.5.32">
<assembly name="ScriptCollection">
<class name="Executables.py" coveredlines="0" coverablelines="285" totallines="389" coveredbranches="0" totalbranches="0" coveredcodeelements="0" totalcodeelements="0" />
<class name="GeneralUtilities.py" coveredlines="466" coverablelines="731" totallines="866" coveredbranches="0" totalbranches="0" coveredcodeelements="0" totalcodeelements="0" />
<class name="ProcessesRunner.py" coveredlines="0" coverablelines="31" totallines="41" coveredbranches="0" totalbranches="0" coveredcodeelements="0" totalcodeelements="0" />
<class name="ProgramRunnerBase.py" coveredlines="22" coverablelines="28" totallines="47" coveredbranches="0" totalbranches="0" coveredcodeelements="0" totalcodeelements="0" />
<class name="ProgramRunnerEpew.py" coveredlines="40" coverablelines="103" totallines="122" coveredbranches="0" totalbranches="0" coveredcodeelements="0" totalcodeelements="0" />
<class name="ProgramRunnerPopen.py" coveredlines="23" coverablelines="38" totallines="51" coveredbranches="0" totalbranches="0" coveredcodeelements="0" totalcodeelements="0" />
<class name="RPStream.py" coveredlines="0" coverablelines="32" totallines="42" coveredbranches="0" totalbranches="0" coveredcodeelements="0" totalcodeelements="0" />
<class name="ScriptCollectionCore.py" coveredlines="558" coverablelines="1415" totallines="1893" coveredbranches="0" totalbranches="0" coveredcodeelements="0" totalcodeelements="0" />
<class name="TasksForCommonProjectStructure.py" coveredlines="464" coverablelines="2157" totallines="2796" coveredbranches="0" totalbranches="0" coveredcodeelements="0" totalcodeelements="0" />
<class name="UpdateCertificates.py" coveredlines="0" coverablelines="105" totallines="126" coveredbranches="0" totalbranches="0" coveredcodeelements="0" totalcodeelements="0" />
</assembly>
</coverage>
2 changes: 1 addition & 1 deletion ScriptCollection/ScriptCollection.codeunit.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<cps:codeunit xmlns:cps="https://projects.aniondev.de/PublicProjects/Common/ProjectTemplates/-/tree/main/Conventions/RepositoryStructure/CommonProjectStructure" codeunitspecificationversion="2.9.4"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://projects.aniondev.de/PublicProjects/Common/ProjectTemplates/-/raw/v2.9.4/Conventions/RepositoryStructure/CommonProjectStructure/codeunit.xsd" enabled="true">
<cps:name>ScriptCollection</cps:name>
<cps:version>3.5.31</cps:version>
<cps:version>3.5.32</cps:version>
<cps:codeunitownername>Marius Göcke</cps:codeunitownername>
<cps:codeunitowneremailaddress>[email protected]</cps:codeunitowneremailaddress>
<cps:properties codeunithastestablesourcecode="true" codeunithasupdatabledependencies="true" throwexceptionifcodeunitfilecannotbevalidated="true" developmentstate="Active development" description="ScriptCollection is the place for reusable scripts.">
Expand Down
16 changes: 16 additions & 0 deletions ScriptCollection/ScriptCollection/Executables.py
Original file line number Diff line number Diff line change
Expand Up @@ -371,3 +371,19 @@ def GenerateARC42ReferenceTemplate() -> int:
folder = os.getcwd()
ScriptCollectionCore().generate_arc42_reference_template(folder, args.productname, args.subfolder)
return 0


def CreateChangelogEntry() -> int:
parser = argparse.ArgumentParser()
parser.add_argument('-f', '--repositoryfolder', required=False, default=".")
parser.add_argument('-p', '--message', required=True)
parser.add_argument('-s', '--commit', action='store_true', required=False, default=False)
args = parser.parse_args()

folder: str = None
if os.path.isabs(args.repositoryfolder):
folder = args.repositoryfolder
else:
folder = GeneralUtilities.resolve_relative_path(args.repositoryfolder, os.getcwd())
TasksForCommonProjectStructure().create_changelog_entry(folder, args.message, args.commit)
return 0
3 changes: 1 addition & 2 deletions ScriptCollection/ScriptCollection/GeneralUtilities.py
Original file line number Diff line number Diff line change
Expand Up @@ -732,8 +732,7 @@ def contains_line(lines, regex: str) -> bool:

@staticmethod
@check_arguments
def read_csv_file(file: str, ignore_first_line: bool = False, treat_number_sign_at_begin_of_line_as_comment: bool = True, trim_values: bool = True,
encoding="utf-8", ignore_empty_lines: bool = True, separator_character: str = ";", values_are_surrounded_by_quotes: bool = False) -> list[list[str]]:
def read_csv_file(file: str, ignore_first_line: bool = False, treat_number_sign_at_begin_of_line_as_comment: bool = True, trim_values: bool = True, encoding="utf-8", ignore_empty_lines: bool = True, separator_character: str = ";", values_are_surrounded_by_quotes: bool = False) -> list[list[str]]:
lines = GeneralUtilities.read_lines_from_file(file, encoding)

if ignore_first_line:
Expand Down
24 changes: 10 additions & 14 deletions ScriptCollection/ScriptCollection/ScriptCollectionCore.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
from .ProgramRunnerPopen import ProgramRunnerPopen
from .ProgramRunnerEpew import ProgramRunnerEpew, CustomEpewArgument

version = "3.5.31"
version = "3.5.32"
__version__ = version


Expand Down Expand Up @@ -1719,26 +1719,22 @@ def update_year_in_first_line_of_file(self, file: str) -> None:
GeneralUtilities.write_lines_to_file(file, lines)

@GeneralUtilities.check_arguments
def get_external_ip(self, proxy: str) -> str:
information = self.get_externalnetworkinformation_as_json_string(proxy)
def get_external_ip(self) -> str:
information = self.get_externalnetworkinformation_as_json_string()
parsed = json.loads(information)
return parsed.ip
return parsed.IPAddress

@GeneralUtilities.check_arguments
def get_country_of_external_ip(self, proxy: str) -> str:
information = self.get_externalnetworkinformation_as_json_string(proxy)
def get_country_of_external_ip(self) -> str:
information = self.get_externalnetworkinformation_as_json_string()
parsed = json.loads(information)
return parsed.country
return parsed.Country

@GeneralUtilities.check_arguments
def get_externalnetworkinformation_as_json_string(self, proxy: str) -> str:
proxies = None
if GeneralUtilities.string_has_content(proxy):
proxies = {"http": proxy}
def get_externalnetworkinformation_as_json_string(self) -> str:
headers = {'Cache-Control': 'no-cache'}
response = requests.get('https://ipinfo.io', proxies=proxies, timeout=5, headers=headers)
network_information_as_json_string = GeneralUtilities.bytes_to_string(
response.content)
response = requests.get('https://clientinformation.anion327.de/API/v1/ClientInformationBackendController/Information', timeout=5, headers=headers)
network_information_as_json_string = GeneralUtilities.bytes_to_string(response.content)
return network_information_as_json_string

@GeneralUtilities.check_arguments
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1102,9 +1102,7 @@ def assert_no_uncommitted_changes(self, repository_folder: str):
raise ValueError(f"Repository '{repository_folder}' has uncommitted changes.")

@GeneralUtilities.check_arguments
def ensure_certificate_authority_for_development_purposes_is_generated(self, script_file: str):
folder_of_current_file = os.path.dirname(script_file)
product_folder: str = GeneralUtilities.resolve_relative_path("../..", folder_of_current_file)
def ensure_certificate_authority_for_development_purposes_is_generated(self, product_folder: str):
product_name: str = os.path.basename(product_folder)
now = datetime.now()
ca_name = f"{product_name}CA_{now.year:04}{now.month:02}{now.day:02}{now.hour:02}{now.min:02}{now.second:02}"
Expand All @@ -1119,6 +1117,15 @@ def ensure_certificate_authority_for_development_purposes_is_generated(self, scr
pass
if generate_certificate:
self.__sc.generate_certificate_authority(ca_folder, ca_name, "DE", "SubjST", "SubjL", "SubjO", "SubjOU")
# TODO add switch to auto-install the script if desired
# for windows: powershell Import-Certificate -FilePath ConSurvCA_20241121000236.crt -CertStoreLocation 'Cert:\CurrentUser\Root'
# for linux: (TODO)

@GeneralUtilities.check_arguments
def generate_certificate_for_development_purposes_for_product(self, repository_folder: str):
product_name = os.path.basename(repository_folder)
ca_folder: str = os.path.join(repository_folder, "Other", "Resources", "CA")
self.__generate_certificate_for_development_purposes(product_name, os.path.join(repository_folder, "Other", "Resources"), ca_folder, None)

@GeneralUtilities.check_arguments
def generate_certificate_for_development_purposes_for_external_service(self, service_folder: str, domain: str = None):
Expand Down Expand Up @@ -1160,6 +1167,15 @@ def __generate_certificate_for_development_purposes(self, service_name: str, res
self.__sc.sign_certificate(certificate_folder, ca_folder, ca_name, domain, resource_content_filename)
GeneralUtilities.ensure_file_does_not_exist(unsignedcertificate_file)

@GeneralUtilities.check_arguments
def copy_product_resource_to_codeunit_resource_folder(self, codeunit_folder: str, resourcename: str) -> None:
src_folder = GeneralUtilities.resolve_relative_path(f"../Other/Resources/{resourcename}", codeunit_folder)
GeneralUtilities.assert_condition(os.path.isdir(src_folder), f"Required product-resource {resourcename} does not exist. Expected folder: {src_folder}")
trg_folder = GeneralUtilities.resolve_relative_path(f"Other/Resources/{resourcename}", codeunit_folder)
GeneralUtilities.ensure_directory_does_not_exist(trg_folder)
GeneralUtilities.ensure_directory_exists(trg_folder)
GeneralUtilities.copy_content_of_folder(src_folder, trg_folder)

@GeneralUtilities.check_arguments
def ensure_product_resource_is_imported(self, codeunit_folder: str, product_resource_name: str) -> None:
product_folder = os.path.dirname(codeunit_folder)
Expand Down Expand Up @@ -1803,7 +1819,7 @@ def __get_constant_helper(self, source_codeunit_folder: str, constant_name: str,

@GeneralUtilities.check_arguments
def copy_development_certificate_to_default_development_directory(self, codeunit_folder: str, build_environment: str, domain: str = None, certificate_resource_name: str = "DevelopmentCertificate") -> None:
if build_environment == "Development":
if build_environment != "Productive":
codeunit_name: str = os.path.basename(codeunit_folder)
if domain is None:
domain = f"{codeunit_name}.test.local".lower()
Expand Down Expand Up @@ -2272,7 +2288,7 @@ def __check_if_changelog_exists(self, repository_folder: str, project_version: s
changelog_folder = os.path.join(repository_folder, "Other", "Resources", "Changelog")
changelog_file = os.path.join(changelog_folder, f"v{project_version}.md")
if not os.path.isfile(changelog_file):
raise ValueError(f"Changelog-file '{changelog_file}' does not exist.")
raise ValueError(f"Changelog-file '{changelog_file}' does not exist. Try creating it using 'sccreatechangelogentry' for example.")

@GeneralUtilities.check_arguments
def __check_whether_security_txt_exists(self, repository_folder: str) -> None:
Expand Down Expand Up @@ -2743,6 +2759,21 @@ def __init__(self, current_file: str, product_name: str, common_remote_name: str
self.commandline_arguments = commandline_arguments
self.main_branch_name = "main"

@GeneralUtilities.check_arguments
def create_changelog_entry(self, repositoryfolder: str, message: str, commit: bool):
current_version = self.get_version_of_project(repositoryfolder)
changelog_file = os.path.join(repositoryfolder, "Other", "Resources", "Changelog", f"v{current_version}.md")
if os.path.isdir(changelog_file):
raise ValueError(f"Changelogfile {changelog_file} already exists.")
else:
GeneralUtilities.ensure_file_exists(changelog_file)
GeneralUtilities.write_text_to_file(changelog_file, f"""# Release notes
## Changes
- {message}
""")

@GeneralUtilities.check_arguments
def update_http_documentation(self, update_http_documentation_arguments: UpdateHTTPDocumentationArguments):
GeneralUtilities.write_message_to_stdout(f"Update HTTP-documentation for for {update_http_documentation_arguments.product_name}.")
Expand Down
2 changes: 1 addition & 1 deletion ScriptCollection/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
autopep8>=2.3.1
build>=1.2.2.post1
coverage>=7.6.7
coverage>=7.6.8
cyclonedx-bom>=5.1.1
defusedxml>=0.7.1
keyboard>=0.13.5
Expand Down
5 changes: 3 additions & 2 deletions ScriptCollection/setup.cfg
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[metadata]
name = ScriptCollection
version = 3.5.31
version = 3.5.32
author = Marius Göcke
author_email = [email protected]
description = The ScriptCollection is the place for reusable scripts.
Expand Down Expand Up @@ -32,7 +32,7 @@ include_package_data = False
python_requires = >=3.10
install_requires =
build>=1.2.2.post1
coverage>=7.6.7
coverage>=7.6.8
cyclonedx-bom>=5.1.1
defusedxml>=0.7.1
keyboard>=0.13.5
Expand Down Expand Up @@ -60,6 +60,7 @@ console_scripts =
scbuildcodeunits = ScriptCollection.Executables:BuildCodeUnits
scbuildcodeunitsc = ScriptCollection.Executables:BuildCodeUnitsC
sccalculatebitcoinblockhash = ScriptCollection.Executables:CalculateBitcoinBlockHash
sccreatechangelogentry = ScriptCollection.Executables:CreateChangelogEntry
scchangefileextension = ScriptCollection.Executables:ChangeFileExtensions
scchangehashofprogram = ScriptCollection.Executables:ChangeHashOfProgram
sccreateemptyfilewithspecificsize = ScriptCollection.Executables:CreateEmptyFileWithSpecificSize
Expand Down

0 comments on commit d4ab370

Please sign in to comment.