UEPyScripts 1.4.3__tar.gz → 1.4.5__tar.gz
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.
- {uepyscripts-1.4.3 → uepyscripts-1.4.5}/PKG-INFO +1 -1
- {uepyscripts-1.4.3 → uepyscripts-1.4.5}/src/uepyscripts/tools/ugs/pull.py +18 -12
- {uepyscripts-1.4.3 → uepyscripts-1.4.5}/src/uepyscripts/tools/ugs/push.py +34 -25
- uepyscripts-1.4.5/src/uepyscripts/tools/ugs/s3_settings.py +81 -0
- {uepyscripts-1.4.3 → uepyscripts-1.4.5}/.gitignore +0 -0
- {uepyscripts-1.4.3 → uepyscripts-1.4.5}/LICENSE +0 -0
- {uepyscripts-1.4.3 → uepyscripts-1.4.5}/README.md +0 -0
- {uepyscripts-1.4.3 → uepyscripts-1.4.5}/pyproject.toml +0 -0
- {uepyscripts-1.4.3 → uepyscripts-1.4.5}/src/uepyscripts/__init__.py +0 -0
- {uepyscripts-1.4.3 → uepyscripts-1.4.5}/src/uepyscripts/context/__init__.py +0 -0
- {uepyscripts-1.4.3 → uepyscripts-1.4.5}/src/uepyscripts/internal/__init__.py +0 -0
- {uepyscripts-1.4.3 → uepyscripts-1.4.5}/src/uepyscripts/internal/config.py +0 -0
- {uepyscripts-1.4.3 → uepyscripts-1.4.5}/src/uepyscripts/internal/engine.py +0 -0
- {uepyscripts-1.4.3 → uepyscripts-1.4.5}/src/uepyscripts/internal/engine_resolver.py +0 -0
- {uepyscripts-1.4.3 → uepyscripts-1.4.5}/src/uepyscripts/internal/project.py +0 -0
- {uepyscripts-1.4.3 → uepyscripts-1.4.5}/src/uepyscripts/py.typed +0 -0
- {uepyscripts-1.4.3 → uepyscripts-1.4.5}/src/uepyscripts/run/__init__.py +0 -0
- {uepyscripts-1.4.3 → uepyscripts-1.4.5}/src/uepyscripts/run/buildgraph.py +0 -0
- {uepyscripts-1.4.3 → uepyscripts-1.4.5}/src/uepyscripts/run/uat.py +0 -0
- {uepyscripts-1.4.3 → uepyscripts-1.4.5}/src/uepyscripts/run/ubt.py +0 -0
- {uepyscripts-1.4.3 → uepyscripts-1.4.5}/src/uepyscripts/tools/__init__.py +0 -0
- {uepyscripts-1.4.3 → uepyscripts-1.4.5}/src/uepyscripts/tools/ci/buildgraph.py +0 -0
- {uepyscripts-1.4.3 → uepyscripts-1.4.5}/src/uepyscripts/tools/ci/cleanup.py +0 -0
- {uepyscripts-1.4.3 → uepyscripts-1.4.5}/src/uepyscripts/tools/helpers.py +0 -0
- {uepyscripts-1.4.3 → uepyscripts-1.4.5}/src/uepyscripts/tools/subprocess.py +0 -0
- {uepyscripts-1.4.3 → uepyscripts-1.4.5}/src/uepyscripts/tools/ue/__init__.py +0 -0
- {uepyscripts-1.4.3 → uepyscripts-1.4.5}/src/uepyscripts/tools/ue/check_engine_installation.py +0 -0
- {uepyscripts-1.4.3 → uepyscripts-1.4.5}/src/uepyscripts/tools/ue/close_editor.py +0 -0
- {uepyscripts-1.4.3 → uepyscripts-1.4.5}/src/uepyscripts/tools/ue/compile_editor.py +0 -0
- {uepyscripts-1.4.3 → uepyscripts-1.4.5}/src/uepyscripts/tools/ue/engine_installation/engine_destination.py +0 -0
- {uepyscripts-1.4.3 → uepyscripts-1.4.5}/src/uepyscripts/tools/ue/engine_installation/engine_installer.py +0 -0
- {uepyscripts-1.4.3 → uepyscripts-1.4.5}/src/uepyscripts/tools/ue/engine_installation/engine_source.py +0 -0
- {uepyscripts-1.4.3 → uepyscripts-1.4.5}/src/uepyscripts/tools/ue/generate_solution.py +0 -0
- {uepyscripts-1.4.3 → uepyscripts-1.4.5}/src/uepyscripts/tools/ue/run_editor.py +0 -0
- {uepyscripts-1.4.3 → uepyscripts-1.4.5}/src/uepyscripts/tools/ugs/cleanup.py +0 -0
- {uepyscripts-1.4.3 → uepyscripts-1.4.5}/src/uepyscripts/tools/ugs/git_utils.py +0 -0
- {uepyscripts-1.4.3 → uepyscripts-1.4.5}/src/uepyscripts/tools/ugs/ugs_types.py +0 -0
- {uepyscripts-1.4.3 → uepyscripts-1.4.5}/src/uepyscripts/tools/winreg.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: UEPyScripts
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.5
|
|
4
4
|
Summary: Collection of Python tools and helpers designed to automate common Unreal Engine project tasks (builds, packaging, editor control, CI tasks, etc.).
|
|
5
5
|
Project-URL: Changelog, https://github.com/TheEmidee/UEPyScripts/releases
|
|
6
6
|
Project-URL: Homepage, https://github.com/TheEmidee/UEPyScripts
|
|
@@ -12,6 +12,7 @@ from uepyscripts import logger
|
|
|
12
12
|
from uepyscripts.internal.engine import resolve_engine
|
|
13
13
|
from uepyscripts.internal.project import resolve_project
|
|
14
14
|
from uepyscripts.tools.ugs.git_utils import get_local_ancestry, resolve_nearest_published_ancestor
|
|
15
|
+
from uepyscripts.tools.ugs.s3_settings import S3_CONFIG_SECTION, S3Settings, add_s3_arguments, resolve_s3_settings
|
|
15
16
|
from uepyscripts.tools.ugs.ugs_types import Manifest, VersionManifest
|
|
16
17
|
|
|
17
18
|
"""
|
|
@@ -44,14 +45,14 @@ class LocalState(TypedDict):
|
|
|
44
45
|
|
|
45
46
|
|
|
46
47
|
class Context:
|
|
47
|
-
def __init__(self, root_folder: Path,
|
|
48
|
+
def __init__(self, root_folder: Path, s3_settings: S3Settings) -> None:
|
|
48
49
|
self.root_folder: Path = root_folder
|
|
49
|
-
self.s3_bucket_name: str =
|
|
50
|
-
self.s3_bucket_region: str =
|
|
50
|
+
self.s3_bucket_name: str = s3_settings.bucket_name
|
|
51
|
+
self.s3_bucket_region: str = s3_settings.bucket_region
|
|
51
52
|
self.s3_client: S3Client = S3Client(
|
|
52
|
-
access_key=
|
|
53
|
-
secret_key=
|
|
54
|
-
region=
|
|
53
|
+
access_key=s3_settings.access_key,
|
|
54
|
+
secret_key=s3_settings.secret_key,
|
|
55
|
+
region=s3_settings.bucket_region,
|
|
55
56
|
)
|
|
56
57
|
logger.info("Download index.json")
|
|
57
58
|
self.commit_index = cast(list[str], self.s3_client.download_json(self.s3_bucket_name, "index.json", default=[]))
|
|
@@ -207,12 +208,15 @@ def sync(context: Context, target_version: str, state: LocalState) -> LocalState
|
|
|
207
208
|
|
|
208
209
|
def parse_arguments() -> argparse.Namespace:
|
|
209
210
|
"""Parse command line arguments."""
|
|
210
|
-
parser = argparse.ArgumentParser(
|
|
211
|
+
parser = argparse.ArgumentParser(
|
|
212
|
+
description=(
|
|
213
|
+
"Sync local engine + game binaries to match the current git HEAD. "
|
|
214
|
+
f"The S3 info is read from the [{S3_CONFIG_SECTION}] section of Config/PyScripts/config.ini, "
|
|
215
|
+
"and each value can be overridden by its command line argument."
|
|
216
|
+
)
|
|
217
|
+
)
|
|
211
218
|
parser.add_argument("--uproject-path", type=Path, help=("Path to a native uproject file"))
|
|
212
|
-
parser
|
|
213
|
-
parser.add_argument("--s3-bucket-region", type=str, help=("AWS S3 Bucket Region"))
|
|
214
|
-
parser.add_argument("--s3-access-key", type=str, help=("AWS S3 Access Key"))
|
|
215
|
-
parser.add_argument("--s3-secret-key", type=str, help=("AWS S3 Secret Key"))
|
|
219
|
+
add_s3_arguments(parser)
|
|
216
220
|
|
|
217
221
|
return parser.parse_args()
|
|
218
222
|
|
|
@@ -234,9 +238,11 @@ def main() -> None:
|
|
|
234
238
|
|
|
235
239
|
engine = resolve_engine(project)
|
|
236
240
|
|
|
241
|
+
s3_settings = resolve_s3_settings(project, args)
|
|
242
|
+
|
|
237
243
|
local_state = LocalStateManager()
|
|
238
244
|
|
|
239
|
-
context = Context(engine.root_path,
|
|
245
|
+
context = Context(engine.root_path, s3_settings)
|
|
240
246
|
|
|
241
247
|
warn_if_source_dirty()
|
|
242
248
|
|
|
@@ -35,6 +35,7 @@ from uepyscripts.tools.ugs.git_utils import (
|
|
|
35
35
|
get_local_ancestry,
|
|
36
36
|
resolve_nearest_published_ancestor,
|
|
37
37
|
)
|
|
38
|
+
from uepyscripts.tools.ugs.s3_settings import S3_CONFIG_SECTION, S3Settings, add_s3_arguments, resolve_s3_settings
|
|
38
39
|
from uepyscripts.tools.ugs.ugs_types import HashCacheEntry, HashCacheManifest, Manifest, VersionManifest
|
|
39
40
|
|
|
40
41
|
# ---- CONFIG ----------------------------------------------------------
|
|
@@ -92,12 +93,14 @@ class HashCache:
|
|
|
92
93
|
|
|
93
94
|
|
|
94
95
|
class Context:
|
|
95
|
-
def __init__(self, args: argparse.Namespace, root_path: Path) -> None:
|
|
96
|
+
def __init__(self, args: argparse.Namespace, root_path: Path, s3_settings: S3Settings) -> None:
|
|
96
97
|
self.args = args
|
|
98
|
+
self.s3_bucket_name: str = s3_settings.bucket_name
|
|
99
|
+
self.s3_bucket_region: str = s3_settings.bucket_region
|
|
97
100
|
self.s3_client: S3Client = S3Client(
|
|
98
|
-
access_key=
|
|
99
|
-
secret_key=
|
|
100
|
-
region=
|
|
101
|
+
access_key=s3_settings.access_key,
|
|
102
|
+
secret_key=s3_settings.secret_key,
|
|
103
|
+
region=s3_settings.bucket_region,
|
|
101
104
|
)
|
|
102
105
|
self.symbol_store_path: str = args.symbol_store_path
|
|
103
106
|
self.tmp_root: Path = Path(tempfile.mkdtemp(prefix="publish-"))
|
|
@@ -113,7 +116,7 @@ class Context:
|
|
|
113
116
|
an inexact match is fine here: a fingerprint mismatch just falls back to
|
|
114
117
|
a full hash for that file, no worse than a cold-cache case, so
|
|
115
118
|
there's no correctness risk in seeding from a non-ancestor."""
|
|
116
|
-
bucket_name = self.
|
|
119
|
+
bucket_name = self.s3_bucket_name
|
|
117
120
|
hash_cache_index = cast(list[str], self.s3_client.download_json(bucket_name, "hash_caches/index.json", default=[]))
|
|
118
121
|
baseline_sha, _ = resolve_nearest_published_ancestor(hash_cache_index, self.ancestry)
|
|
119
122
|
|
|
@@ -346,7 +349,7 @@ def prune_old_versions(context: Context, cfg: FilesConfiguration, index: list[st
|
|
|
346
349
|
keys_to_delete.append(f"checkpoints/{v}.7z")
|
|
347
350
|
|
|
348
351
|
logger.info(f"Pruning {len(versions_to_delete)} version(s), {len(checkpoints_to_delete)} checkpoint(s)")
|
|
349
|
-
context.s3_client.delete_keys(context.
|
|
352
|
+
context.s3_client.delete_keys(context.s3_bucket_name, keys_to_delete)
|
|
350
353
|
|
|
351
354
|
return index[cutoff_idx:], checkpoints_to_keep
|
|
352
355
|
|
|
@@ -364,7 +367,7 @@ def prune_old_hash_caches(context: Context, hash_cache_index: list[str], keep: i
|
|
|
364
367
|
to_keep = hash_cache_index[-keep:]
|
|
365
368
|
|
|
366
369
|
logger.info(f"Pruning {len(to_delete)} old hash cache(s)")
|
|
367
|
-
context.s3_client.delete_keys(context.
|
|
370
|
+
context.s3_client.delete_keys(context.s3_bucket_name, [f"hash_caches/{sha}.json" for sha in to_delete])
|
|
368
371
|
|
|
369
372
|
return to_keep
|
|
370
373
|
|
|
@@ -413,7 +416,13 @@ def publish_to_symbol_store(context: Context, paths: list[str], cfg: FilesConfig
|
|
|
413
416
|
|
|
414
417
|
def parse_arguments() -> argparse.Namespace:
|
|
415
418
|
"""Parse command line arguments."""
|
|
416
|
-
parser = argparse.ArgumentParser(
|
|
419
|
+
parser = argparse.ArgumentParser(
|
|
420
|
+
description=(
|
|
421
|
+
"Publish the engine + game binaries for the current git HEAD. "
|
|
422
|
+
f"The S3 info is read from the [{S3_CONFIG_SECTION}] section of Config/PyScripts/config.ini, "
|
|
423
|
+
"and each value can be overridden by its command line argument."
|
|
424
|
+
)
|
|
425
|
+
)
|
|
417
426
|
parser.add_argument("--uproject-path", type=Path, help=("Path to a native uproject file"))
|
|
418
427
|
parser.add_argument("--skip-upload", action=argparse.BooleanOptionalAction, help=("Set this to not upload anything on S3"))
|
|
419
428
|
parser.add_argument(
|
|
@@ -421,10 +430,7 @@ def parse_arguments() -> argparse.Namespace:
|
|
|
421
430
|
action=argparse.BooleanOptionalAction,
|
|
422
431
|
help=("Set this to not delete the temporary directory when the script finishes"),
|
|
423
432
|
)
|
|
424
|
-
parser
|
|
425
|
-
parser.add_argument("--s3-bucket-region", type=str, help=("AWS S3 Bucket Region"))
|
|
426
|
-
parser.add_argument("--s3-access-key", type=str, help=("AWS S3 Access Key"))
|
|
427
|
-
parser.add_argument("--s3-secret-key", type=str, help=("AWS S3 Secret Key"))
|
|
433
|
+
add_s3_arguments(parser)
|
|
428
434
|
parser.add_argument("--disable-symbol-store-upload", action=argparse.BooleanOptionalAction)
|
|
429
435
|
parser.add_argument("--symbol-store-path", type=str, help=("Path of the shared symbol store folder"))
|
|
430
436
|
parser.add_argument(
|
|
@@ -472,11 +478,14 @@ def main() -> None:
|
|
|
472
478
|
|
|
473
479
|
engine = resolve_engine(project)
|
|
474
480
|
|
|
481
|
+
s3_settings = resolve_s3_settings(project, args)
|
|
482
|
+
|
|
475
483
|
cfg = FilesConfiguration(
|
|
476
484
|
root_folder=engine.root_path,
|
|
477
485
|
directories=[
|
|
478
486
|
"Engine/Binaries/Win64",
|
|
479
487
|
"Engine/Plugins",
|
|
488
|
+
"Engine/Platforms",
|
|
480
489
|
"Engine/Intermediate/Build/BuildRules",
|
|
481
490
|
"Engine/Intermediate/Build/Win64/**/",
|
|
482
491
|
"Engine/Plugins/**/Intermediate/**/",
|
|
@@ -487,14 +496,14 @@ def main() -> None:
|
|
|
487
496
|
symstore_product=project.project_name,
|
|
488
497
|
)
|
|
489
498
|
|
|
490
|
-
context = Context(args, engine.root_path)
|
|
499
|
+
context = Context(args, engine.root_path, s3_settings)
|
|
491
500
|
|
|
492
501
|
try:
|
|
493
502
|
logger.info("=== Publish binary files ===")
|
|
494
503
|
logger.info(f"Current branch: {context.current_branch}")
|
|
495
504
|
|
|
496
505
|
logger.info("Download index.json")
|
|
497
|
-
index = cast(list[str], context.s3_client.download_json(context.
|
|
506
|
+
index = cast(list[str], context.s3_client.download_json(context.s3_bucket_name, "index.json", default=[]))
|
|
498
507
|
|
|
499
508
|
if len(index) == 0:
|
|
500
509
|
logger.info("Empty index.json. Fresh sync")
|
|
@@ -523,7 +532,7 @@ def main() -> None:
|
|
|
523
532
|
old_state = {}
|
|
524
533
|
else:
|
|
525
534
|
logger.info(f"Using {baseline_sha} as diff baseline for branch '{context.current_branch}'")
|
|
526
|
-
old_manifest = cast(VersionManifest, context.s3_client.download_json(context.
|
|
535
|
+
old_manifest = cast(VersionManifest, context.s3_client.download_json(context.s3_bucket_name, f"manifests/{baseline_sha}.json"))
|
|
527
536
|
old_state = old_manifest["files"]
|
|
528
537
|
|
|
529
538
|
changed, removed = compute_diff(old_state, new_state)
|
|
@@ -544,7 +553,7 @@ def main() -> None:
|
|
|
544
553
|
return
|
|
545
554
|
|
|
546
555
|
logger.info("Upload zip")
|
|
547
|
-
context.s3_client.upload_file(context.
|
|
556
|
+
context.s3_client.upload_file(context.s3_bucket_name, f"deltas/{version}.7z", zip_file_path)
|
|
548
557
|
zip_file_path.unlink()
|
|
549
558
|
|
|
550
559
|
manifest_payload: VersionManifest = {
|
|
@@ -553,7 +562,7 @@ def main() -> None:
|
|
|
553
562
|
"removed": removed,
|
|
554
563
|
}
|
|
555
564
|
context.s3_client.upload_bytes(
|
|
556
|
-
context.
|
|
565
|
+
context.s3_bucket_name,
|
|
557
566
|
f"manifests/{version}.json",
|
|
558
567
|
json.dumps(manifest_payload).encode(),
|
|
559
568
|
content_type="application/json",
|
|
@@ -562,7 +571,7 @@ def main() -> None:
|
|
|
562
571
|
index.append(version)
|
|
563
572
|
|
|
564
573
|
logger.info("Download JSON with checkpoints")
|
|
565
|
-
checkpoints = cast(list[str], context.s3_client.download_json(context.
|
|
574
|
+
checkpoints = cast(list[str], context.s3_client.download_json(context.s3_bucket_name, "checkpoints.json", default=[]))
|
|
566
575
|
|
|
567
576
|
logger.info(f"Checkpoint interval: {cfg.checkpoint_interval} - Number of deltas : {len(index)}")
|
|
568
577
|
|
|
@@ -576,7 +585,7 @@ def main() -> None:
|
|
|
576
585
|
zip_file_path = build_zip(cfg.root_folder, list(new_state.keys()), context.tmp_root)
|
|
577
586
|
|
|
578
587
|
logger.info("Upload zip")
|
|
579
|
-
context.s3_client.upload_file(context.
|
|
588
|
+
context.s3_client.upload_file(context.s3_bucket_name, f"checkpoints/{version}.7z", zip_file_path)
|
|
580
589
|
zip_file_path.unlink()
|
|
581
590
|
checkpoints.append(version)
|
|
582
591
|
else:
|
|
@@ -585,11 +594,11 @@ def main() -> None:
|
|
|
585
594
|
index, checkpoints = prune_old_versions(context, cfg, index, checkpoints)
|
|
586
595
|
|
|
587
596
|
logger.info("Upload index.json")
|
|
588
|
-
context.s3_client.upload_bytes(context.
|
|
597
|
+
context.s3_client.upload_bytes(context.s3_bucket_name, "index.json", json.dumps(index).encode(), content_type="application/json")
|
|
589
598
|
|
|
590
599
|
logger.info("Upload checkpoints.json")
|
|
591
600
|
context.s3_client.upload_bytes(
|
|
592
|
-
context.
|
|
601
|
+
context.s3_bucket_name, "checkpoints.json", json.dumps(checkpoints).encode(), content_type="application/json"
|
|
593
602
|
)
|
|
594
603
|
else:
|
|
595
604
|
logger.info("No changes in synced binaries.")
|
|
@@ -603,7 +612,7 @@ def main() -> None:
|
|
|
603
612
|
logger.info(f"Finished scan. Found {len(symstore_state)} files.")
|
|
604
613
|
|
|
605
614
|
logger.info("Download symstore-manifest.json")
|
|
606
|
-
prev_symstore_state = cast(Manifest, context.s3_client.download_json(context.
|
|
615
|
+
prev_symstore_state = cast(Manifest, context.s3_client.download_json(context.s3_bucket_name, "symstore-manifest.json", default={}))
|
|
607
616
|
symstore_changed, _ = compute_diff(prev_symstore_state, symstore_state)
|
|
608
617
|
|
|
609
618
|
if symstore_changed:
|
|
@@ -611,7 +620,7 @@ def main() -> None:
|
|
|
611
620
|
|
|
612
621
|
logger.info("Upload symstore-manifest.json")
|
|
613
622
|
context.s3_client.upload_bytes(
|
|
614
|
-
context.
|
|
623
|
+
context.s3_bucket_name, "symstore-manifest.json", json.dumps(symstore_state).encode(), content_type="application/json"
|
|
615
624
|
)
|
|
616
625
|
else:
|
|
617
626
|
logger.info("No changes for symbol store")
|
|
@@ -623,7 +632,7 @@ def main() -> None:
|
|
|
623
632
|
if not context.args.skip_upload:
|
|
624
633
|
logger.info("Upload hash cache")
|
|
625
634
|
context.s3_client.upload_bytes(
|
|
626
|
-
context.
|
|
635
|
+
context.s3_bucket_name,
|
|
627
636
|
f"hash_caches/{context.current_sha}.json",
|
|
628
637
|
json.dumps(context.hash_cache.to_manifest()).encode(),
|
|
629
638
|
content_type="application/json",
|
|
@@ -636,7 +645,7 @@ def main() -> None:
|
|
|
636
645
|
|
|
637
646
|
logger.info("Upload hash_caches/index.json")
|
|
638
647
|
context.s3_client.upload_bytes(
|
|
639
|
-
context.
|
|
648
|
+
context.s3_bucket_name,
|
|
640
649
|
"hash_caches/index.json",
|
|
641
650
|
json.dumps(context.hash_cache_index).encode(),
|
|
642
651
|
content_type="application/json",
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"""
|
|
2
|
+
S3 connection info for the binary publish/sync tools.
|
|
3
|
+
|
|
4
|
+
Values are read from the project's Config/PyScripts/config.ini (section
|
|
5
|
+
[UGS.AWS]), and each one can be overridden by its command line argument.
|
|
6
|
+
Having no config file at all is fine — the command line can provide
|
|
7
|
+
everything — but a value that is missing from both sources is reported
|
|
8
|
+
before any S3 call is attempted.
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
import argparse
|
|
12
|
+
from dataclasses import dataclass
|
|
13
|
+
|
|
14
|
+
from uepyscripts import logger
|
|
15
|
+
from uepyscripts.internal.config import Config, resolve_config
|
|
16
|
+
from uepyscripts.internal.project import Project
|
|
17
|
+
|
|
18
|
+
S3_CONFIG_SECTION = "UGS.AWS"
|
|
19
|
+
|
|
20
|
+
# (attribute, command line argument, config.ini key)
|
|
21
|
+
S3_SETTINGS_FIELDS = [
|
|
22
|
+
("bucket_name", "--s3-bucket-name", "AWS_BucketName"),
|
|
23
|
+
("bucket_region", "--s3-bucket-region", "AWS_Region"),
|
|
24
|
+
("access_key", "--s3-access-key", "AWS_AccessKey"),
|
|
25
|
+
("secret_key", "--s3-secret-key", "AWS_SecretKey"),
|
|
26
|
+
]
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@dataclass
|
|
30
|
+
class S3Settings:
|
|
31
|
+
bucket_name: str
|
|
32
|
+
bucket_region: str
|
|
33
|
+
access_key: str
|
|
34
|
+
secret_key: str
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def add_s3_arguments(parser: argparse.ArgumentParser) -> None:
|
|
38
|
+
"""Registers the S3 command line arguments, which override the config file."""
|
|
39
|
+
group = parser.add_argument_group(
|
|
40
|
+
"AWS S3",
|
|
41
|
+
f"Defaults to the [{S3_CONFIG_SECTION}] section of Config/PyScripts/config.ini",
|
|
42
|
+
)
|
|
43
|
+
group.add_argument("--s3-bucket-name", type=str, help="AWS S3 Bucket Name (config: AWS_BucketName)")
|
|
44
|
+
group.add_argument("--s3-bucket-region", type=str, help="AWS S3 Bucket Region (config: AWS_Region)")
|
|
45
|
+
group.add_argument("--s3-access-key", type=str, help="AWS S3 Access Key (config: AWS_AccessKey)")
|
|
46
|
+
group.add_argument("--s3-secret-key", type=str, help="AWS S3 Secret Key (config: AWS_SecretKey)")
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def read_config_value(config: Config, key: str) -> str | None:
|
|
50
|
+
"""A missing config file, section or key are all treated the same way — no value."""
|
|
51
|
+
if not config.valid or not config.config.has_section(S3_CONFIG_SECTION):
|
|
52
|
+
return None
|
|
53
|
+
|
|
54
|
+
value = config[S3_CONFIG_SECTION].get(key)
|
|
55
|
+
|
|
56
|
+
return value if value else None
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def resolve_s3_settings(project: Project, args: argparse.Namespace) -> S3Settings:
|
|
60
|
+
"""Takes the S3 info from the config file, then lets the matching command
|
|
61
|
+
line arguments override each value. Exits with an explicit report of what
|
|
62
|
+
is missing rather than letting the first S3 call fail."""
|
|
63
|
+
config = resolve_config(project)
|
|
64
|
+
|
|
65
|
+
values: dict[str, str] = {}
|
|
66
|
+
missing: list[str] = []
|
|
67
|
+
|
|
68
|
+
for attribute, argument, config_key in S3_SETTINGS_FIELDS:
|
|
69
|
+
argument_value = getattr(args, argument.lstrip("-").replace("-", "_"), None)
|
|
70
|
+
value = argument_value or read_config_value(config, config_key)
|
|
71
|
+
|
|
72
|
+
if value:
|
|
73
|
+
values[attribute] = value
|
|
74
|
+
else:
|
|
75
|
+
missing.append(f" - {argument} (or [{S3_CONFIG_SECTION}] {config_key} in Config/PyScripts/config.ini)")
|
|
76
|
+
|
|
77
|
+
if missing:
|
|
78
|
+
logger.fatal("Missing S3 information:\n" + "\n".join(missing))
|
|
79
|
+
exit(1)
|
|
80
|
+
|
|
81
|
+
return S3Settings(**values)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{uepyscripts-1.4.3 → uepyscripts-1.4.5}/src/uepyscripts/tools/ue/check_engine_installation.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|