ScriptCollection 3.5.93__py3-none-any.whl → 3.5.95__py3-none-any.whl
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.
- ScriptCollection/ScriptCollectionCore.py +10 -3
- ScriptCollection/TasksForCommonProjectStructure.py +150 -73
- {scriptcollection-3.5.93.dist-info → scriptcollection-3.5.95.dist-info}/METADATA +1 -1
- {scriptcollection-3.5.93.dist-info → scriptcollection-3.5.95.dist-info}/RECORD +7 -7
- {scriptcollection-3.5.93.dist-info → scriptcollection-3.5.95.dist-info}/WHEEL +1 -1
- {scriptcollection-3.5.93.dist-info → scriptcollection-3.5.95.dist-info}/entry_points.txt +0 -0
- {scriptcollection-3.5.93.dist-info → scriptcollection-3.5.95.dist-info}/top_level.txt +0 -0
@@ -12,6 +12,7 @@ import math
|
|
12
12
|
import os
|
13
13
|
from queue import Queue, Empty
|
14
14
|
from concurrent.futures import ThreadPoolExecutor
|
15
|
+
import xml.etree.ElementTree as ET
|
15
16
|
from pathlib import Path
|
16
17
|
from subprocess import Popen
|
17
18
|
import re
|
@@ -32,7 +33,7 @@ from .ProgramRunnerBase import ProgramRunnerBase
|
|
32
33
|
from .ProgramRunnerPopen import ProgramRunnerPopen
|
33
34
|
from .ProgramRunnerEpew import ProgramRunnerEpew, CustomEpewArgument
|
34
35
|
|
35
|
-
version = "3.5.
|
36
|
+
version = "3.5.95"
|
36
37
|
__version__ = version
|
37
38
|
|
38
39
|
|
@@ -2052,7 +2053,7 @@ chmod {permission} {link_file}
|
|
2052
2053
|
if productname is None:
|
2053
2054
|
productname = os.path.basename(repository)
|
2054
2055
|
if subfolder is None:
|
2055
|
-
subfolder = "Other/
|
2056
|
+
subfolder = "Other/Reference"
|
2056
2057
|
reference_root_folder = f"{repository}/{subfolder}"
|
2057
2058
|
reference_content_folder = reference_root_folder + "/Technical"
|
2058
2059
|
if os.path.isdir(reference_root_folder):
|
@@ -2152,7 +2153,6 @@ TXDX
|
|
2152
2153
|
- [Repository](TXDX)
|
2153
2154
|
- [Productive-System](TXDX)
|
2154
2155
|
- [QualityCheck-system](TXDX)
|
2155
|
-
|
2156
2156
|
""".replace("XDX", "ODO"))
|
2157
2157
|
|
2158
2158
|
@GeneralUtilities.check_arguments
|
@@ -2242,3 +2242,10 @@ TXDX
|
|
2242
2242
|
raise ValueError(f"Folder '{folder}' does not exist.")
|
2243
2243
|
|
2244
2244
|
GeneralUtilities.ensure_directory_exists(path)
|
2245
|
+
|
2246
|
+
@GeneralUtilities.check_arguments
|
2247
|
+
def format_xml_file(self, file: str) -> None:
|
2248
|
+
encoding = "utf-8"
|
2249
|
+
element = ET.XML(GeneralUtilities.read_text_from_file(file, encoding))
|
2250
|
+
ET.indent(element)
|
2251
|
+
GeneralUtilities.write_text_to_file(file, ET.tostring(element, encoding="unicode"), encoding)
|
@@ -307,6 +307,7 @@ class TasksForCommonProjectStructure:
|
|
307
307
|
@GeneralUtilities.check_arguments
|
308
308
|
def generate_bom_for_python_project(self, verbosity: int, codeunit_folder: str, codeunitname: str, commandline_arguments: list[str]) -> None:
|
309
309
|
self.assert_is_codeunit_folder(codeunit_folder)
|
310
|
+
repository_folder = os.path.dirname(codeunit_folder)
|
310
311
|
verbosity = TasksForCommonProjectStructure.get_verbosity_from_commandline_arguments(commandline_arguments, verbosity)
|
311
312
|
codeunitversion = self.get_version_of_codeunit_folder(codeunit_folder)
|
312
313
|
bom_folder = "Other/Artifacts/BOM"
|
@@ -316,9 +317,20 @@ class TasksForCommonProjectStructure:
|
|
316
317
|
raise ValueError(f"Codeunit {codeunitname} does not have a 'requirements.txt'-file.")
|
317
318
|
# TODO check that all values from setup.cfg are contained in requirements.txt
|
318
319
|
result = self.__sc.run_program("cyclonedx-py", "requirements", codeunit_folder, verbosity=verbosity)
|
319
|
-
|
320
|
-
|
321
|
-
|
320
|
+
bom_file_relative_json = f"{bom_folder}/{codeunitname}.{codeunitversion}.bom.json"
|
321
|
+
bom_file_relative_xml = f"{bom_folder}/{codeunitname}.{codeunitversion}.bom.xml"
|
322
|
+
bom_file_json = os.path.join(codeunit_folder, bom_file_relative_json)
|
323
|
+
bom_file_xml = os.path.join(codeunit_folder, bom_file_relative_xml)
|
324
|
+
|
325
|
+
GeneralUtilities.ensure_file_exists(bom_file_json)
|
326
|
+
GeneralUtilities.write_text_to_file(bom_file_json, result[1])
|
327
|
+
self.ensure_cyclonedxcli_is_available(repository_folder)
|
328
|
+
cyclonedx_exe = os.path.join(repository_folder, "Other/Resources/CycloneDXCLI/cyclonedx-cli")
|
329
|
+
if GeneralUtilities.current_system_is_windows():
|
330
|
+
cyclonedx_exe = cyclonedx_exe+".exe"
|
331
|
+
self.__sc.run_program(cyclonedx_exe, f"convert --input-file ./{codeunitname}/{bom_file_relative_json} --input-format json --output-file ./{codeunitname}/{bom_file_relative_xml} --output-format xml", repository_folder)
|
332
|
+
self.__sc.format_xml_file(bom_file_xml)
|
333
|
+
GeneralUtilities.ensure_file_does_not_exist(bom_file_json)
|
322
334
|
|
323
335
|
@GeneralUtilities.check_arguments
|
324
336
|
def standardized_tasks_push_wheel_file_to_registry(self, wheel_file: str, api_key: str, repository: str, gpg_identity: str, verbosity: int) -> None:
|
@@ -759,7 +771,7 @@ class TasksForCommonProjectStructure:
|
|
759
771
|
target = f"{codeunit_folder}\\{bomfile_folder}\\{codeunit_name}.{codeunitversion}.sbom.xml"
|
760
772
|
GeneralUtilities.ensure_file_does_not_exist(target)
|
761
773
|
os.rename(f"{codeunit_folder}\\{bomfile_folder}\\bom.xml", target)
|
762
|
-
|
774
|
+
self.__sc.format_xml_file(target)
|
763
775
|
|
764
776
|
@GeneralUtilities.check_arguments
|
765
777
|
def standardized_tasks_run_linting_for_flutter_project_in_common_project_structure(self, script_file: str, default_verbosity: int, args: list[str]):
|
@@ -1348,25 +1360,29 @@ class TasksForCommonProjectStructure:
|
|
1348
1360
|
repository_folder = GeneralUtilities.resolve_relative_path("..", codeunit_folder)
|
1349
1361
|
dependent_codeunit_folder = os.path.join(repository_folder, dependent_codeunit_name).replace("\\", "/")
|
1350
1362
|
t = TasksForCommonProjectStructure()
|
1351
|
-
sbom_file = f"{codeunitname}/Other/Artifacts/BOM/{codeunitname}.{t.get_version_of_codeunit_folder(codeunit_folder)}.sbom.xml"
|
1352
|
-
dependent_sbom_file = f"{dependent_codeunit_name}/Other/Artifacts/BOM/{dependent_codeunit_name}.{t.get_version_of_codeunit_folder(dependent_codeunit_folder)}.sbom.xml"
|
1363
|
+
sbom_file = f"{repository_folder}/{codeunitname}/Other/Artifacts/BOM/{codeunitname}.{t.get_version_of_codeunit_folder(codeunit_folder)}.sbom.xml"
|
1364
|
+
dependent_sbom_file = f"{repository_folder}/{dependent_codeunit_name}/Other/Artifacts/BOM/{dependent_codeunit_name}.{t.get_version_of_codeunit_folder(dependent_codeunit_folder)}.sbom.xml"
|
1353
1365
|
self.merge_sbom_file(repository_folder, dependent_sbom_file, sbom_file)
|
1354
1366
|
|
1355
1367
|
@GeneralUtilities.check_arguments
|
1356
|
-
def merge_sbom_file(self, repository_folder: str,
|
1357
|
-
GeneralUtilities.assert_file_exists(os.path.join(repository_folder,
|
1358
|
-
GeneralUtilities.assert_file_exists(os.path.join(repository_folder,
|
1359
|
-
|
1360
|
-
os.rename(os.path.join(repository_folder,
|
1361
|
-
|
1362
|
-
|
1363
|
-
|
1368
|
+
def merge_sbom_file(self, repository_folder: str, source_sbom_file_relative: str, target_sbom_file_relative: str) -> None:
|
1369
|
+
GeneralUtilities.assert_file_exists(os.path.join(repository_folder, source_sbom_file_relative))
|
1370
|
+
GeneralUtilities.assert_file_exists(os.path.join(repository_folder, target_sbom_file_relative))
|
1371
|
+
target_original_sbom_file_relative = os.path.dirname(target_sbom_file_relative)+"/"+os.path.basename(target_sbom_file_relative)+".original.xml"
|
1372
|
+
os.rename(os.path.join(repository_folder, target_sbom_file_relative), os.path.join(repository_folder, target_original_sbom_file_relative))
|
1373
|
+
|
1374
|
+
self.ensure_cyclonedxcli_is_available(repository_folder)
|
1375
|
+
cyclonedx_exe = os.path.join(repository_folder, "Other/Resources/CycloneDXCLI/cyclonedx-cli")
|
1376
|
+
if GeneralUtilities.current_system_is_windows():
|
1377
|
+
cyclonedx_exe = cyclonedx_exe+".exe"
|
1378
|
+
self.__sc.run_program(cyclonedx_exe, f"merge --input-files {source_sbom_file_relative} {target_original_sbom_file_relative} --output-file {target_sbom_file_relative}", repository_folder)
|
1379
|
+
GeneralUtilities.ensure_file_does_not_exist(os.path.join(repository_folder, target_original_sbom_file_relative))
|
1380
|
+
self.__sc.format_xml_file(os.path.join(repository_folder, target_sbom_file_relative))
|
1364
1381
|
|
1365
1382
|
@GeneralUtilities.check_arguments
|
1366
1383
|
def standardized_tasks_build_for_docker_project_with_additional_build_arguments(self, build_script_file: str, target_environment_type: str, verbosity: int, commandline_arguments: list[str], custom_arguments: dict[str, str]) -> None:
|
1367
1384
|
use_cache: bool = False
|
1368
1385
|
verbosity = TasksForCommonProjectStructure.get_verbosity_from_commandline_arguments(commandline_arguments, verbosity)
|
1369
|
-
sc: ScriptCollectionCore = ScriptCollectionCore()
|
1370
1386
|
codeunitname: str = Path(os.path.dirname(build_script_file)).parent.parent.name
|
1371
1387
|
codeunit_folder = GeneralUtilities.resolve_relative_path("../..", str(os.path.dirname(build_script_file)))
|
1372
1388
|
codeunitname_lower = codeunitname.lower()
|
@@ -1381,7 +1397,7 @@ class TasksForCommonProjectStructure:
|
|
1381
1397
|
args.append("--no-cache")
|
1382
1398
|
args.append(".")
|
1383
1399
|
codeunit_content_folder = os.path.join(codeunit_folder)
|
1384
|
-
|
1400
|
+
self.__sc.run_program_argsasarray("docker", args, codeunit_content_folder, verbosity=verbosity, print_errors_as_information=True)
|
1385
1401
|
artifacts_folder = GeneralUtilities.resolve_relative_path("Other/Artifacts", codeunit_folder)
|
1386
1402
|
app_artifacts_folder = os.path.join(artifacts_folder, "BuildResult_OCIImage")
|
1387
1403
|
GeneralUtilities.ensure_directory_does_not_exist(app_artifacts_folder)
|
@@ -1400,7 +1416,7 @@ class TasksForCommonProjectStructure:
|
|
1400
1416
|
codeunitversion = self.get_version_of_codeunit(os.path.join(codeunit_folder, f"{codeunitname}.codeunit.xml"))
|
1401
1417
|
GeneralUtilities.ensure_directory_exists(sbom_folder)
|
1402
1418
|
self.__sc.run_program_argsasarray("docker", ["sbom", "--format", "cyclonedx", f"{codeunitname_lower}:{codeunitversion}", "--output", f"{codeunitname}.{codeunitversion}.sbom.xml"], sbom_folder, verbosity=verbosity, print_errors_as_information=True)
|
1403
|
-
|
1419
|
+
self.__sc.format_xml_file(sbom_folder+f"/{codeunitname}.{codeunitversion}.sbom.xml")
|
1404
1420
|
|
1405
1421
|
@GeneralUtilities.check_arguments
|
1406
1422
|
def push_docker_build_artifact(self, push_artifacts_file: str, registry: str, verbosity: int, push_readme: bool, commandline_arguments: list[str], repository_folder_name: str) -> None:
|
@@ -1470,8 +1486,8 @@ class TasksForCommonProjectStructure:
|
|
1470
1486
|
@GeneralUtilities.check_arguments
|
1471
1487
|
def standardized_tasks_do_common_tasks(self, common_tasks_scripts_file: str, codeunit_version: str, verbosity: int, targetenvironmenttype: str, clear_artifacts_folder: bool, additional_arguments_file: str, assume_dependent_codeunits_are_already_built: bool, commandline_arguments: list[str]) -> None:
|
1472
1488
|
additional_arguments_file = self.get_additionalargumentsfile_from_commandline_arguments(commandline_arguments, additional_arguments_file)
|
1473
|
-
target_environmenttype = self.get_targetenvironmenttype_from_commandline_arguments(commandline_arguments, targetenvironmenttype)
|
1474
|
-
assume_dependent_codeunits_are_already_built = self.get_assume_dependent_codeunits_are_already_built_from_commandline_arguments(commandline_arguments, assume_dependent_codeunits_are_already_built)
|
1489
|
+
target_environmenttype = self.get_targetenvironmenttype_from_commandline_arguments(commandline_arguments, targetenvironmenttype)#pylint: disable=unused-variable
|
1490
|
+
# assume_dependent_codeunits_are_already_built = self.get_assume_dependent_codeunits_are_already_built_from_commandline_arguments(commandline_arguments, assume_dependent_codeunits_are_already_built)
|
1475
1491
|
if commandline_arguments is None:
|
1476
1492
|
raise ValueError('The "commandline_arguments"-parameter is not defined.')
|
1477
1493
|
if len(commandline_arguments) == 0:
|
@@ -1571,8 +1587,8 @@ class TasksForCommonProjectStructure:
|
|
1571
1587
|
GeneralUtilities.ensure_directory_does_not_exist(artifacts_folder)
|
1572
1588
|
|
1573
1589
|
# Get artifacts from dependent codeunits
|
1574
|
-
if assume_dependent_codeunits_are_already_built:
|
1575
|
-
|
1590
|
+
# if assume_dependent_codeunits_are_already_built:
|
1591
|
+
# self.build_dependent_code_units(repository_folder, codeunit_name, verbosity, target_environmenttype, additional_arguments_file, commandline_arguments)
|
1576
1592
|
self.copy_artifacts_from_dependent_code_units(repository_folder, codeunit_name)
|
1577
1593
|
|
1578
1594
|
# Update codeunit-version
|
@@ -1730,8 +1746,9 @@ class TasksForCommonProjectStructure:
|
|
1730
1746
|
def standardized_tasks_build_bom_for_node_project(self, codeunit_folder: str, verbosity: int, commandline_arguments: list[str]) -> None:
|
1731
1747
|
self.assert_is_codeunit_folder(codeunit_folder)
|
1732
1748
|
verbosity = TasksForCommonProjectStructure.get_verbosity_from_commandline_arguments(commandline_arguments, verbosity)
|
1733
|
-
|
1734
|
-
|
1749
|
+
relative_path_to_bom_file = f"Other/Artifacts/BOM/{os.path.basename(codeunit_folder)}.{self.get_version_of_codeunit_folder(codeunit_folder)}.sbom.xml"
|
1750
|
+
self.run_with_epew("cyclonedx-npm", f"--output-format xml --output-file {relative_path_to_bom_file}", codeunit_folder, verbosity=verbosity)
|
1751
|
+
self.__sc.format_xml_file(codeunit_folder+"/"+relative_path_to_bom_file)
|
1735
1752
|
|
1736
1753
|
@GeneralUtilities.check_arguments
|
1737
1754
|
def standardized_tasks_linting_for_angular_codeunit(self, linting_script_file: str, verbosity: int, build_environment_target_type: str, commandline_arguments: list[str]) -> None:
|
@@ -2333,6 +2350,7 @@ class TasksForCommonProjectStructure:
|
|
2333
2350
|
command_with_args = f"{command_with_args} {{{{.CLI_ARGS}}}}"
|
2334
2351
|
lines.append(f" {name}:")
|
2335
2352
|
lines.append(f' desc: "{description}"')
|
2353
|
+
lines.append(' silent: true')
|
2336
2354
|
lines.append(f' dir: "{cwd}"')
|
2337
2355
|
lines.append(" cmds:")
|
2338
2356
|
lines.append(f" - {command_with_args}")
|
@@ -2432,7 +2450,19 @@ class TasksForCommonProjectStructure:
|
|
2432
2450
|
GeneralUtilities.copy_content_of_folder(ca_source_folder, ca_target_folder)
|
2433
2451
|
|
2434
2452
|
@GeneralUtilities.check_arguments
|
2435
|
-
def get_sorted_codeunits(self,
|
2453
|
+
def get_sorted_codeunits(self, repository_folder: str) -> list[str]:
|
2454
|
+
codeunits_with_dependent_codeunits: dict[str, set[str]] = dict[str, set[str]]()
|
2455
|
+
subfolders = GeneralUtilities.get_direct_folders_of_folder(repository_folder)
|
2456
|
+
for subfolder in subfolders:
|
2457
|
+
codeunit_name: str = os.path.basename(subfolder)
|
2458
|
+
codeunit_file = os.path.join(subfolder, f"{codeunit_name}.codeunit.xml")
|
2459
|
+
if os.path.exists(codeunit_file):
|
2460
|
+
codeunits_with_dependent_codeunits[codeunit_name] = self.get_dependent_code_units(codeunit_file)
|
2461
|
+
sorted_codeunits = self._internal_get_sorted_codeunits_by_dict(codeunits_with_dependent_codeunits)
|
2462
|
+
return sorted_codeunits
|
2463
|
+
|
2464
|
+
@GeneralUtilities.check_arguments
|
2465
|
+
def _internal_get_sorted_codeunits_by_dict(self, codeunits=dict[str, set[str]]) -> list[str]:
|
2436
2466
|
result_typed = list(TopologicalSorter(codeunits).static_order())
|
2437
2467
|
result = list()
|
2438
2468
|
for item in result_typed:
|
@@ -2475,16 +2505,36 @@ class TasksForCommonProjectStructure:
|
|
2475
2505
|
self.__sc.assert_is_git_repository(repository_folder)
|
2476
2506
|
repository_folder = GeneralUtilities.resolve_relative_path_from_current_working_directory(repository_folder)
|
2477
2507
|
codeunits = self.get_codeunits(repository_folder, False)
|
2508
|
+
project_version = self.get_version_of_project(repository_folder)
|
2509
|
+
|
2510
|
+
now = datetime.now()
|
2511
|
+
if not self.__suport_information_exists(repository_folder, project_version):
|
2512
|
+
support_time = timedelta(days=365*2+30*3+1) # TODO make this configurable
|
2513
|
+
until = now + support_time
|
2514
|
+
until_day = datetime(until.year, until.month, until.day, 0, 0, 0)
|
2515
|
+
self.mark_current_version_as_supported(repository_folder, project_version, now, until_day)
|
2516
|
+
|
2517
|
+
project_resources_folder = os.path.join(repository_folder, "Other", "Scripts")
|
2518
|
+
PrepareBuildCodeunits_script_name = "PrepareBuildCodeunits.py"
|
2519
|
+
prepare_build_codeunits_scripts = os.path.join(project_resources_folder, PrepareBuildCodeunits_script_name)
|
2520
|
+
if os.path.isfile(prepare_build_codeunits_scripts):
|
2521
|
+
GeneralUtilities.write_message_to_stdout(f'Run "{PrepareBuildCodeunits_script_name}"')
|
2522
|
+
result = self.__sc.run_program("python", f"{PrepareBuildCodeunits_script_name}", project_resources_folder, throw_exception_if_exitcode_is_not_zero=False, print_live_output=True)
|
2523
|
+
if result[0] != 0:
|
2524
|
+
raise ValueError(f"PrepareBuildCodeunits.py resulted in exitcode {result[0]}.")
|
2525
|
+
|
2526
|
+
self.__do_repository_checks(repository_folder, project_version)
|
2478
2527
|
self.build_specific_codeunits(repository_folder, codeunits, verbosity, target_environmenttype, additional_arguments_file, is_pre_merge, export_target_directory, False, commandline_arguments, do_git_clean_when_no_changes, note)
|
2479
2528
|
|
2480
2529
|
@GeneralUtilities.check_arguments
|
2481
|
-
def build_specific_codeunits(self, repository_folder: str, codeunits: list[str], verbosity: int = 1, target_environmenttype: str = "QualityCheck", additional_arguments_file: str = None, is_pre_merge: bool = False, export_target_directory: str = None, assume_dependent_codeunits_are_already_built: bool = True, commandline_arguments: list[str] = [], do_git_clean_when_no_changes: bool = False, note: str = None) -> None:
|
2530
|
+
def build_specific_codeunits(self, repository_folder: str, codeunits: list[str], verbosity: int = 1, target_environmenttype: str = "QualityCheck", additional_arguments_file: str = None, is_pre_merge: bool = False, export_target_directory: str = None, assume_dependent_codeunits_are_already_built: bool = True, commandline_arguments: list[str] = [], do_git_clean_when_no_changes: bool = False, note: str = None, check_for_new_files: bool = True) -> None:
|
2531
|
+
codeunits_list = {", ".join(codeunits)}
|
2482
2532
|
if verbosity > 2:
|
2483
|
-
GeneralUtilities.write_message_to_stdout(f"Start building codeunits
|
2533
|
+
GeneralUtilities.write_message_to_stdout(f"Start building codeunits ({codeunits_list}) in repository '{repository_folder}'...")
|
2484
2534
|
self.__sc.assert_is_git_repository(repository_folder)
|
2485
2535
|
self.__check_target_environmenttype(target_environmenttype)
|
2486
2536
|
repository_folder = GeneralUtilities.resolve_relative_path_from_current_working_directory(repository_folder)
|
2487
|
-
repository_name = os.path.
|
2537
|
+
repository_name = os.path.basename(repository_folder)
|
2488
2538
|
contains_uncommitted_changes_at_begin = self.__sc.git_repository_has_uncommitted_changes(repository_folder)
|
2489
2539
|
if contains_uncommitted_changes_at_begin:
|
2490
2540
|
if is_pre_merge:
|
@@ -2492,57 +2542,38 @@ class TasksForCommonProjectStructure:
|
|
2492
2542
|
else:
|
2493
2543
|
if do_git_clean_when_no_changes:
|
2494
2544
|
self.__sc.run_program("git", "clean -dfx", repository_folder)
|
2495
|
-
|
2545
|
+
codeunit_subfolders = [os.path.join(repository_folder, codeunit) for codeunit in codeunits]
|
2496
2546
|
codeunits_with_dependent_codeunits: dict[str, set[str]] = dict[str, set[str]]()
|
2497
2547
|
|
2498
|
-
|
2499
|
-
PrepareBuildCodeunits_script_name = "PrepareBuildCodeunits.py"
|
2500
|
-
prepare_build_codeunits_scripts = os.path.join(project_resources_folder, PrepareBuildCodeunits_script_name)
|
2501
|
-
if os.path.isfile(prepare_build_codeunits_scripts):
|
2502
|
-
GeneralUtilities.write_message_to_stdout(f'Run "{PrepareBuildCodeunits_script_name}"')
|
2503
|
-
result = self.__sc.run_program("python", f"{PrepareBuildCodeunits_script_name}", project_resources_folder, throw_exception_if_exitcode_is_not_zero=False, print_live_output=True)
|
2504
|
-
if result[0] != 0:
|
2505
|
-
raise ValueError(f"PrepareBuildCodeunits.py resulted in exitcode {result[0]}.")
|
2506
|
-
|
2507
|
-
for subfolder in subfolders:
|
2548
|
+
for subfolder in codeunit_subfolders:
|
2508
2549
|
codeunit_name: str = os.path.basename(subfolder)
|
2509
2550
|
codeunit_file = os.path.join(subfolder, f"{codeunit_name}.codeunit.xml")
|
2510
|
-
|
2511
|
-
|
2512
|
-
|
2513
|
-
|
2514
|
-
sorted_codeunits = self.get_sorted_codeunits(codeunits_with_dependent_codeunits)
|
2551
|
+
GeneralUtilities.assert_condition(os.path.exists(codeunit_file), f"Codeunit-file '{codeunit_file}' does nost exist.")
|
2552
|
+
codeunits_with_dependent_codeunits[codeunit_name] = self.get_dependent_code_units(codeunit_file)
|
2553
|
+
sorted_codeunits = self.get_sorted_codeunits(repository_folder)
|
2554
|
+
sorted_codeunits = [codeunit for codeunit in sorted_codeunits if codeunit in codeunits]
|
2515
2555
|
project_version = self.get_version_of_project(repository_folder)
|
2516
2556
|
|
2517
|
-
now = datetime.now()
|
2518
2557
|
message = f"Build codeunits in product {repository_name}..."
|
2519
2558
|
if note is not None:
|
2520
2559
|
message = f"{message} ({note})"
|
2521
2560
|
GeneralUtilities.write_message_to_stdout(message)
|
2522
2561
|
|
2523
|
-
if not self.__suport_information_exists(repository_folder, project_version):
|
2524
|
-
support_time = timedelta(days=365*2+30*3+1) # TODO make this configurable
|
2525
|
-
until = now + support_time
|
2526
|
-
until_day = datetime(until.year, until.month, until.day, 0, 0, 0)
|
2527
|
-
self.mark_current_version_as_supported(repository_folder, project_version, now, until_day)
|
2528
|
-
|
2529
2562
|
if len(sorted_codeunits) == 0:
|
2530
2563
|
raise ValueError(f'No codeunit found in subfolders of "{repository_folder}".')
|
2531
2564
|
else:
|
2532
2565
|
if verbosity > 1:
|
2533
|
-
GeneralUtilities.write_message_to_stdout(f"Attempt to build codeunits for version {project_version} in the following order:")
|
2566
|
+
GeneralUtilities.write_message_to_stdout(f"Attempt to build codeunits ({codeunits_list}) for project version {project_version} in the following order:")
|
2534
2567
|
i = 0
|
2535
2568
|
for codeunit in sorted_codeunits:
|
2536
2569
|
i = i+1
|
2537
2570
|
GeneralUtilities.write_message_to_stdout(f"{i}.: {codeunit}")
|
2538
|
-
self.__do_repository_checks(repository_folder, project_version)
|
2539
|
-
line = "----------"
|
2540
2571
|
for codeunit in sorted_codeunits:
|
2541
|
-
GeneralUtilities.write_message_to_stdout(
|
2572
|
+
GeneralUtilities.write_message_to_stdout(GeneralUtilities.get_line())
|
2542
2573
|
self.__build_codeunit(os.path.join(repository_folder, codeunit), verbosity, target_environmenttype, additional_arguments_file, is_pre_merge, assume_dependent_codeunits_are_already_built, commandline_arguments)
|
2543
|
-
GeneralUtilities.write_message_to_stdout(
|
2574
|
+
GeneralUtilities.write_message_to_stdout(GeneralUtilities.get_line())
|
2544
2575
|
contains_uncommitted_changes_at_end = self.__sc.git_repository_has_uncommitted_changes(repository_folder)
|
2545
|
-
if contains_uncommitted_changes_at_end and not is_pre_merge:
|
2576
|
+
if contains_uncommitted_changes_at_end and (not is_pre_merge) and check_for_new_files:
|
2546
2577
|
if contains_uncommitted_changes_at_begin:
|
2547
2578
|
GeneralUtilities.write_message_to_stdout(f'There are still uncommitted changes in the repository "{repository_folder}".')
|
2548
2579
|
else:
|
@@ -2551,6 +2582,7 @@ class TasksForCommonProjectStructure:
|
|
2551
2582
|
GeneralUtilities.write_message_to_stderr(f"Warning: {message}")
|
2552
2583
|
else:
|
2553
2584
|
raise ValueError(message)
|
2585
|
+
|
2554
2586
|
if export_target_directory is not None:
|
2555
2587
|
project_name = self.get_project_name(repository_folder)
|
2556
2588
|
for codeunit in sorted_codeunits:
|
@@ -2574,9 +2606,14 @@ class TasksForCommonProjectStructure:
|
|
2574
2606
|
self.__sc.assert_is_git_repository(repository_folder)
|
2575
2607
|
self.__check_if_changelog_exists(repository_folder, project_version)
|
2576
2608
|
self.__check_whether_security_txt_exists(repository_folder)
|
2609
|
+
self.__check_whether_general_reference_exists(repository_folder)
|
2577
2610
|
self.__check_whether_workspace_file_exists(repository_folder)
|
2578
2611
|
self.__check_for_staged_or_committed_ignored_files(repository_folder)
|
2579
2612
|
|
2613
|
+
@GeneralUtilities.check_arguments
|
2614
|
+
def __check_whether_general_reference_exists(self, repository_folder: str) -> None:
|
2615
|
+
GeneralUtilities.assert_file_exists(os.path.join(repository_folder, "Other", "Reference", "Reference.md"))
|
2616
|
+
|
2580
2617
|
@GeneralUtilities.check_arguments
|
2581
2618
|
def __check_if_changelog_exists(self, repository_folder: str, project_version: str) -> None:
|
2582
2619
|
self.__sc.assert_is_git_repository(repository_folder)
|
@@ -2693,6 +2730,17 @@ class TasksForCommonProjectStructure:
|
|
2693
2730
|
def ensure_androidappbundletool_is_available(self, target_folder: str) -> None:
|
2694
2731
|
self.ensure_file_from_github_assets_is_available(target_folder, "google", "bundletool", "AndroidAppBundleTool", "bundletool.jar", lambda latest_version: f"bundletool-all-{latest_version}.jar")
|
2695
2732
|
|
2733
|
+
@GeneralUtilities.check_arguments
|
2734
|
+
def ensure_cyclonedxcli_is_available(self, target_folder: str) -> None:
|
2735
|
+
local_filename = "cyclonedx-cli"
|
2736
|
+
filename_on_github: str
|
2737
|
+
if GeneralUtilities.current_system_is_windows():
|
2738
|
+
filename_on_github = "cyclonedx-win-x64.exe"
|
2739
|
+
local_filename = local_filename+".exe"
|
2740
|
+
else:
|
2741
|
+
filename_on_github = "cyclonedx-linux-x64"
|
2742
|
+
self.ensure_file_from_github_assets_is_available(target_folder, "CycloneDX", "cyclonedx-cli", "CycloneDXCLI", local_filename, lambda latest_version: filename_on_github)
|
2743
|
+
|
2696
2744
|
@GeneralUtilities.check_arguments
|
2697
2745
|
def ensure_file_from_github_assets_is_available(self, target_folder: str, githubuser: str, githubprojectname: str, resource_name: str, local_filename: str, get_filename_on_github) -> None:
|
2698
2746
|
resource_folder = os.path.join(target_folder, "Other", "Resources", resource_name)
|
@@ -2703,11 +2751,11 @@ class TasksForCommonProjectStructure:
|
|
2703
2751
|
GeneralUtilities.ensure_directory_does_not_exist(resource_folder)
|
2704
2752
|
GeneralUtilities.ensure_directory_exists(resource_folder)
|
2705
2753
|
headers = {'Cache-Control': 'no-cache'}
|
2706
|
-
response = requests.get(f"https://api.github.com/repos/{githubuser}/{githubprojectname}/releases/latest", timeout=
|
2707
|
-
latest_version = response.json()["
|
2754
|
+
response = requests.get(f"https://api.github.com/repos/{githubuser}/{githubprojectname}/releases/latest", timeout=10, headers=headers)
|
2755
|
+
latest_version = response.json()["tag_name"]
|
2708
2756
|
filename_on_github = get_filename_on_github(latest_version)
|
2709
|
-
|
2710
|
-
urllib.request.urlretrieve(
|
2757
|
+
link = f"https://github.com/{githubuser}/{githubprojectname}/releases/download/{latest_version}/{filename_on_github}"
|
2758
|
+
urllib.request.urlretrieve(link, file)
|
2711
2759
|
else:
|
2712
2760
|
if file_exists:
|
2713
2761
|
GeneralUtilities.write_message_to_stdout(f"Warning: Can not check for updates of {resource_name} due to missing internet-connection.")
|
@@ -2715,22 +2763,49 @@ class TasksForCommonProjectStructure:
|
|
2715
2763
|
raise ValueError(f"Can not download {resource_name}.")
|
2716
2764
|
|
2717
2765
|
@GeneralUtilities.check_arguments
|
2718
|
-
def
|
2719
|
-
self.
|
2720
|
-
|
2721
|
-
|
2766
|
+
def generate_svg_files_from_plantuml_files_for_repository(self, repository_folder: str) -> None:
|
2767
|
+
self.__sc.assert_is_git_repository(repository_folder)
|
2768
|
+
self.ensure_plantuml_is_available(repository_folder)
|
2769
|
+
plant_uml_folder = os.path.join(repository_folder, "Other", "Resources", "PlantUML")
|
2770
|
+
target_folder = os.path.join(repository_folder, "Other", "Reference")
|
2771
|
+
self.__generate_svg_files_from_plantuml(target_folder, plant_uml_folder)
|
2772
|
+
|
2773
|
+
@GeneralUtilities.check_arguments
|
2774
|
+
def generate_svg_files_from_plantuml_files_for_codeunit(self, codeunit_folder: str) -> None:
|
2775
|
+
self.assert_is_codeunit_folder(codeunit_folder)
|
2776
|
+
repository_folder = os.path.dirname(codeunit_folder)
|
2777
|
+
self.ensure_plantuml_is_available(repository_folder)
|
2778
|
+
plant_uml_folder = os.path.join(repository_folder, "Other", "Resources", "PlantUML")
|
2779
|
+
target_folder = os.path.join(codeunit_folder, "Other", "Reference")
|
2780
|
+
self.__generate_svg_files_from_plantuml(target_folder, plant_uml_folder)
|
2781
|
+
|
2782
|
+
@GeneralUtilities.check_arguments
|
2783
|
+
def __generate_svg_files_from_plantuml(self, diagrams_files_folder: str, plant_uml_folder: str) -> None:
|
2722
2784
|
sc = ScriptCollectionCore()
|
2723
|
-
for file in GeneralUtilities.get_all_files_of_folder(
|
2785
|
+
for file in GeneralUtilities.get_all_files_of_folder(diagrams_files_folder):
|
2724
2786
|
if file.endswith(".plantuml"):
|
2725
|
-
|
2726
|
-
|
2727
|
-
|
2787
|
+
output_filename = self.get_output_filename_for_plantuml_filename(file)
|
2788
|
+
argument = ['-jar', f'{plant_uml_folder}/plantuml.jar', '-tsvg', os.path.basename(file)]
|
2789
|
+
folder = os.path.dirname(file)
|
2790
|
+
sc.run_program_argsasarray("java", argument, folder, verbosity=0)
|
2791
|
+
result_file = folder+"/" + output_filename
|
2792
|
+
GeneralUtilities.assert_file_exists(result_file)
|
2793
|
+
self.__sc.format_xml_file(result_file)
|
2794
|
+
|
2795
|
+
@GeneralUtilities.check_arguments
|
2796
|
+
def get_output_filename_for_plantuml_filename(self, plantuml_file: str) -> str:
|
2797
|
+
for line in GeneralUtilities.read_lines_from_file(plantuml_file):
|
2798
|
+
prefix = "@startuml "
|
2799
|
+
if line.startswith(prefix):
|
2800
|
+
title = line[len(prefix):]
|
2801
|
+
return title+".svg"
|
2802
|
+
return Path(plantuml_file).stem+".svg"
|
2728
2803
|
|
2729
2804
|
@GeneralUtilities.check_arguments
|
2730
2805
|
def generate_codeunits_overview_diagram(self, repository_folder: str) -> None:
|
2731
2806
|
self.__sc.assert_is_git_repository(repository_folder)
|
2732
2807
|
project_name: str = os.path.basename(repository_folder)
|
2733
|
-
target_folder = os.path.join(repository_folder, "Other", "
|
2808
|
+
target_folder = os.path.join(repository_folder, "Other", "Reference", "Technical", "Diagrams")
|
2734
2809
|
GeneralUtilities.ensure_directory_exists(target_folder)
|
2735
2810
|
target_file = os.path.join(target_folder, "CodeUnits-Overview.plantuml")
|
2736
2811
|
lines = ["@startuml CodeUnits-Overview"]
|
@@ -2856,10 +2931,9 @@ class TasksForCommonProjectStructure:
|
|
2856
2931
|
GeneralUtilities.write_message_to_stdout(f"Warning: Codeunit {codeunit_name} is disabled.")
|
2857
2932
|
return
|
2858
2933
|
|
2859
|
-
artifacts_folder = os.path.join(codeunit_folder, "Other", "Artifacts")
|
2860
2934
|
GeneralUtilities.write_message_to_stdout(f"Start building codeunit {codeunit_name}.")
|
2861
2935
|
GeneralUtilities.write_message_to_stdout(f"Build-environmenttype: {target_environmenttype}")
|
2862
|
-
|
2936
|
+
self.__sc.run_program("git", "clean -dfx", codeunit_folder)
|
2863
2937
|
|
2864
2938
|
verbosity_for_executed_programs = self.get_verbosity_from_commandline_arguments(commandline_arguments, verbosity)
|
2865
2939
|
|
@@ -2935,6 +3009,7 @@ class TasksForCommonProjectStructure:
|
|
2935
3009
|
GeneralUtilities.write_message_to_stdout('Run "OnBuildingFinished.py"...')
|
2936
3010
|
self.__sc.run_program("python", f"OnBuildingFinished.py{additional_arguments_f}{general_argument}", other_folder, verbosity=verbosity_for_executed_programs, throw_exception_if_exitcode_is_not_zero=True, print_live_output=2 < verbosity)
|
2937
3011
|
|
3012
|
+
artifacts_folder = os.path.join(codeunit_folder, "Other", "Artifacts")
|
2938
3013
|
artifactsinformation_file = os.path.join(artifacts_folder, f"{codeunit_name}.artifactsinformation.xml")
|
2939
3014
|
codeunit_version = self.get_version_of_codeunit(codeunit_file)
|
2940
3015
|
GeneralUtilities.ensure_file_exists(artifactsinformation_file)
|
@@ -2964,9 +3039,10 @@ class TasksForCommonProjectStructure:
|
|
2964
3039
|
# Prepare
|
2965
3040
|
GeneralUtilities.write_message_to_stdout("Update dependencies...")
|
2966
3041
|
self.__sc.assert_is_git_repository(repository_folder)
|
2967
|
-
codeunits = self.
|
3042
|
+
codeunits = self.get_sorted_codeunits(repository_folder)
|
2968
3043
|
update_dependencies_script_filename = "UpdateDependencies.py"
|
2969
|
-
|
3044
|
+
target_environmenttype = "QualityCheck"
|
3045
|
+
self.build_codeunits(repository_folder, target_environmenttype=target_environmenttype, do_git_clean_when_no_changes=True, note="Prepare dependency-update") # Required because update dependencies is not always possible for not-buildet codeunits (depends on the programming language or package manager)
|
2970
3046
|
|
2971
3047
|
# update dependencies of resources
|
2972
3048
|
global_scripts_folder = os.path.join(repository_folder, "Other", "Scripts")
|
@@ -2982,6 +3058,7 @@ class TasksForCommonProjectStructure:
|
|
2982
3058
|
update_dependencies_script_folder = os.path.join(codeunit_folder, "Other")
|
2983
3059
|
GeneralUtilities.ensure_directory_exists(os.path.join(update_dependencies_script_folder, "Resources", "CodeAnalysisResult"))
|
2984
3060
|
self.__sc.run_program("python", update_dependencies_script_filename, update_dependencies_script_folder, verbosity, print_live_output=True)
|
3061
|
+
self.build_specific_codeunits(repository_folder, [codeunit], 0, target_environmenttype, None, False, None, True, [], False, "Build due to updated dependencies", False)
|
2985
3062
|
if self.__sc.git_repository_has_uncommitted_changes(repository_folder):
|
2986
3063
|
version_of_project = self.get_version_of_project(repository_folder)
|
2987
3064
|
changelog_file = os.path.join(repository_folder, "Other", "Resources", "Changelog", f"v{version_of_project}.md")
|
@@ -6,12 +6,12 @@ ScriptCollection/ProgramRunnerEpew.py,sha256=4pjEd0r9Fcz3TTDv0MdTSd5KkigYXcWUVI1
|
|
6
6
|
ScriptCollection/ProgramRunnerPopen.py,sha256=BPY7-ZMIlqT7JOKz8qlB5c0laF2Js-ijzqk09GxZC48,3821
|
7
7
|
ScriptCollection/RPStream.py,sha256=NRRHL3YSP3D9MuAV2jB_--0KUKCsvJGxeKnxgrRZ9kY,1545
|
8
8
|
ScriptCollection/SCLog.py,sha256=l4aekBiGoNkKGtvO_Er3NY_K7ts4ZWtIGlhq07I-4LY,30
|
9
|
-
ScriptCollection/ScriptCollectionCore.py,sha256=
|
10
|
-
ScriptCollection/TasksForCommonProjectStructure.py,sha256=
|
9
|
+
ScriptCollection/ScriptCollectionCore.py,sha256=BNaVHYzgDngTNPvdu1RmI5CcoBYXa5eER6MbOG9ECZA,123973
|
10
|
+
ScriptCollection/TasksForCommonProjectStructure.py,sha256=WLpk9nRa6p_fFCHTJ3YO8mOxyrs1D8V2CuXem38qi84,226908
|
11
11
|
ScriptCollection/UpdateCertificates.py,sha256=Eynbgu7k9jLxApP2D_8Il77B6BFjJap6K7oTeEAZYbk,7790
|
12
12
|
ScriptCollection/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
13
|
-
scriptcollection-3.5.
|
14
|
-
scriptcollection-3.5.
|
15
|
-
scriptcollection-3.5.
|
16
|
-
scriptcollection-3.5.
|
17
|
-
scriptcollection-3.5.
|
13
|
+
scriptcollection-3.5.95.dist-info/METADATA,sha256=vVDkmhbE3EFINXPutGygcmV-cNd_sEKd0AFPwvsSF8g,7664
|
14
|
+
scriptcollection-3.5.95.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
|
15
|
+
scriptcollection-3.5.95.dist-info/entry_points.txt,sha256=fYCGWGNGijBQHhFe6UAO-BEpfEOxLyNJemukt5ElSzs,3644
|
16
|
+
scriptcollection-3.5.95.dist-info/top_level.txt,sha256=hY2hOVH0V0Ce51WB76zKkIWTUNwMUdHo4XDkR2vYVwg,17
|
17
|
+
scriptcollection-3.5.95.dist-info/RECORD,,
|
File without changes
|
File without changes
|