Skip to content

Commit bd64f5e

Browse files
Change to LFRic Macros scripts for git (#117)
* update copyright checker * update copyright checker * update copyright_checker * add GitInfo class * remove unnecessary function * add gitinfo class * add check for detached head * initial commit for suite_report * task tables done * update ' * make executable * update suite_report * run black * revert test_fcm_bdiff deletion * add finally with error to import statement * didn't want finally * revert bdiff changes * add check for writable suite_path * re-copy bdiff branch * add detached head unit test * run black * update for jules primary source * add class docstring * edit dependency table * run black * Update suite_report_git/suite_data.py Co-authored-by: Yaswant Pradhan <2984440+yaswant@users.noreply.github.com> * Update suite_report_git/suite_data.py Co-authored-by: Yaswant Pradhan <2984440+yaswant@users.noreply.github.com> * Update suite_report_git/suite_data.py Co-authored-by: Yaswant Pradhan <2984440+yaswant@users.noreply.github.com> * change to using urls * url for local clones * run black * collapse failed * start changes * add get_git_sources * split get_git_sources * change lfric_macros to git * remove print * update source dirs * code review comments * run black * make source dir first * fix * add umdp3_fixer * add wrapper script * make copy of fcm nightly testing * update read_sources * run black * black * update extract loc * add type hinting * fix checkout * update github extraction * add mkdir * try other apprach * change to tuple * revert to init * move files around * update extract * update extract * update extract * update extract * update suite_report * unsaved * update suite_report * update branch * add option to use tokens * print extraction * syntax * fix * add print * update if * update prints * test * test * test * remove debug prints * update umdp3 error message * use shutil instead * Update lfric_macros/apply_macros.py Co-authored-by: Yaswant Pradhan <2984440+yaswant@users.noreply.github.com> * Update lfric_macros/apply_macros.py Co-authored-by: Yaswant Pradhan <2984440+yaswant@users.noreply.github.com> * Update lfric_macros/apply_macros.py Co-authored-by: Yaswant Pradhan <2984440+yaswant@users.noreply.github.com> * Update lfric_macros/apply_macros.py Co-authored-by: Yaswant Pradhan <2984440+yaswant@users.noreply.github.com> * Update lfric_macros/apply_macros.py Co-authored-by: Yaswant Pradhan <2984440+yaswant@users.noreply.github.com> * change test for git url * cr comments * update * added space to incorrect place --------- Co-authored-by: Yaswant Pradhan <2984440+yaswant@users.noreply.github.com>
1 parent cc4978a commit bd64f5e

File tree

3 files changed

+92
-87
lines changed

3 files changed

+92
-87
lines changed

lfric_macros/apply_macros.py

Lines changed: 50 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@
1414
import ast
1515
import os
1616
import re
17+
import shlex
1718
import shutil
1819
import subprocess
1920
import tempfile
21+
import yaml
2022
import networkx as nx
2123
from collections import defaultdict
2224

@@ -34,7 +36,7 @@ def run_command(command, shell=False):
3436
- result object from subprocess.run
3537
"""
3638
if not shell:
37-
command = command.split()
39+
command = shlex.split(command)
3840
return subprocess.run(
3941
command,
4042
capture_output=True,
@@ -72,31 +74,29 @@ def check_environment():
7274

7375
def get_root_path(wc_path):
7476
"""
75-
Given a path to a working copy, ensure the path and working copy are both
76-
valid and return the path to the working copy root directory
77+
Given a path to a git clone, ensure the path and clone are both
78+
valid and return the path to the clone root directory
7779
Inputs:
78-
- wc_path, command line argument to a working copy
80+
- wc_path, command line argument to a clone
7981
Outputs:
80-
- str, path to the top level of the apps working copy
82+
- str, path to the top level of the apps clone
8183
"""
8284

83-
# Run fcm info on the given path to ensure it is
84-
command = f"fcm info {wc_path}"
85+
command = f"git -C {wc_path} rev-parse --show-toplevel"
8586
result = run_command(command)
8687
if result.returncode:
8788
print(
88-
"[WARN] - Could not find the fcm root path for the apps working copy. "
89-
"Defaulting to assuming the provided path in the root path."
89+
"[WARN] - Unable to locate the git clone root for the apps working copy."
90+
"Assuming the given path is the root directory by default."
9091
)
9192
return wc_path
9293

9394
# If no error, then search through output for the working copy root path
9495
# return the found path
95-
for line in result.stdout.split("\n"):
96-
if line.startswith("Working Copy Root Path"):
97-
return line.split(":", 1)[1].strip()
96+
if result.stdout:
97+
return result.stdout.strip()
9898
raise Exception(
99-
"Couldn't extract the Working Copy Root path from the output of the "
99+
"Couldn't extract the Git Clone Root path from the output of the "
100100
f"command '{command}'"
101101
)
102102

@@ -321,11 +321,10 @@ def parse_application_section(self, meta_dir):
321321

322322
def get_dependency_paths(self, source, repo):
323323
"""
324-
Parse the core or jules command line arguments to get the path to a
325-
working copy.
324+
Parse the core or jules command line arguments to get the path to a git clone.
326325
If the source isn't defined, first populate the source by reading the
327-
dependencies.sh file.
328-
If the source is an fcm url check it out to a temporary location
326+
dependencies.yaml file.
327+
If the source is a remote GitHub source clone it to a temporary location
329328
Inputs:
330329
- source, str, The command line argument for the source. If not set
331330
this will be None
@@ -335,9 +334,9 @@ def get_dependency_paths(self, source, repo):
335334
- str, The path to the source working copy to use
336335
"""
337336

338-
# If source is None then read the dependencies.sh file for the source
337+
# If source is None then read the dependencies.yaml file for the source
339338
if source is None:
340-
source = self.read_dependencies(repo)
339+
source, ref = self.read_dependencies(repo)
341340

342341
# If the source exists as a path then return as is
343342
if os.path.exists(os.path.expanduser(source)):
@@ -347,76 +346,58 @@ def get_dependency_paths(self, source, repo):
347346
if os.path.exists(source_path):
348347
return source_path
349348

350-
# Check that the source looks like an fcm keyword, raise an error if not
351-
if "fcm:" not in source:
349+
# Check that the source looks like a GitHub URL, raise an error if not
350+
if "git@github.com:" not in source and "https://github.com/" not in source:
352351
raise Exception(
353352
f"The {repo} source: {source}, was not found as a working copy "
354-
"and does not look like an fcm url. Please check the source."
355-
"If not set on the command then the dependencies.sh file is "
353+
"and does not look like an GitHub URL. Please check the source."
354+
"If not set on the command then the dependencies.yaml file is "
356355
"being used."
357356
)
358357

359-
# Checkout the fcm source to a temporary location
360-
source = self.fcm_temp_copy(source, repo)
358+
# Checkout the git source to a temporary location
359+
source = self.git_clone_temp(source, ref, repo)
361360
return source
362361

363362
def read_dependencies(self, repo):
364363
"""
365-
Read through the dependencies.sh file for the source of the repo defined
366-
by repo. Uses self.root_path to locate the dependencies.sh file.
364+
Read through the dependencies.yaml file for the source of the repo defined
365+
by repo. Uses self.root_path to locate the dependencies.yaml file.
367366
Inputs:
368367
- repo, str, Either "lfric_core" or "jules" depending on which
369368
source is being found. The function will work with
370369
other repos, but not intended to within this script.
371370
Outputs:
372-
- str, The source as defined by the dependencies.sh file
371+
- str, The source as defined by the dependencies.yaml file
373372
"""
374-
dependencies_path = os.path.join(self.root_path, "dependencies.sh")
375-
source = ""
376-
rev = ""
377-
with open(dependencies_path, "r") as dependencies_file:
378-
# Loop over lines in dependencies.sh for lines relevant to repo
379-
for line in dependencies_file:
380-
line = line.strip()
381-
if line.startswith(f"export {repo}_rev"):
382-
rev = line.split("=")[1]
383-
if line.startswith(f"export {repo}_sources"):
384-
source = line.split("=")[1]
385-
# If source not set then default to trunk
386-
if source == "":
387-
# lfric_core doesn't match the url
388-
if repo == "lfric_core":
389-
source = "fcm:lfric.xm_tr"
390-
else:
391-
source = f"fcm:{repo}.xm_tr"
392-
# If a revision set then append to source
393-
# Defaults to the head of the source
394-
# Only do this if it's an fcm url
395-
if rev != "" and "fcm:" in source:
396-
source = f"{source}@{rev}"
397-
return source
373+
dependencies_path = os.path.join(self.root_path, "dependencies.yaml")
374+
with open(dependencies_path, "r") as f:
375+
dependencies = yaml.safe_load(f)
398376

399-
def fcm_temp_copy(self, url, repo):
377+
return dependencies[repo]["source"], dependencies[repo]["ref"]
378+
379+
def git_clone_temp(self, source, ref, repo):
400380
"""
401-
Given an fcm url as a source, checkout a working copy to a temp location
402-
and return the path. Update self.temp_dirs with temporary directory path
381+
Given a github URL, extract a temporary clone
403382
Inputs:
404-
- url, str, An fcm url of the source
383+
- source, str, A github URL
384+
- ref, str, A git ref to checkout, None will result in default branch
405385
- repo, str, the name of the source being found
406386
Outputs:
407387
- str, The path to the temporary working copy
408388
"""
409389

410-
print(f"Extracting {url} to a temporary directory")
390+
print(f"Extracting {source} to a temporary directory")
411391
tempdir = tempfile.mkdtemp()
412392
self.temp_dirs[repo] = tempdir
413-
command = f"fcm co {url} {tempdir}"
414-
result = run_command(command)
415-
if result.returncode:
416-
raise Exception(
417-
f"Failed to checkout from URL {url} into directory {tempdir} "
418-
f"with error message:\n\n{result.stderr}"
419-
)
393+
commands = (f"git clone {source} {tempdir}", f"git -C {tempdir} checkout {ref}")
394+
for command in commands:
395+
result = run_command(command)
396+
if result.returncode:
397+
raise Exception(
398+
f"Failed to clone from {source} into directory {tempdir} "
399+
f"with error message:\n\n{result.stderr}"
400+
)
420401
return tempdir
421402

422403
############################################################################
@@ -1237,16 +1218,16 @@ def parse_args():
12371218
"--core",
12381219
default=None,
12391220
help="The LFRic Core source being used."
1240-
"Either a path to a working copy or an FCM URL."
1241-
"If not set, will be read from the dependencies.sh",
1221+
"Either a path to a working copy or a git source."
1222+
"If not set, will be read from the dependencies.yaml",
12421223
)
12431224
parser.add_argument(
12441225
"-j",
12451226
"--jules",
12461227
default=None,
12471228
help="The Jules source being used."
1248-
"Either a path to a working copy or an FCM URL."
1249-
"If not set, will be read from the dependencies.sh",
1229+
"Either a path to a working copy or a git source."
1230+
"If not set, will be read from the dependencies.yaml",
12501231
)
12511232
return parser.parse_args()
12521233

@@ -1273,7 +1254,7 @@ def apply_macros_main(tag, cname=None, version=None, apps=".", core=None, jules=
12731254
banner_print("WARNING")
12741255
print(
12751256
"Macros have been applied to apps in LFRic Core. A temporary "
1276-
"copy of the LFRic Core source given by the `dependencies.sh` "
1257+
"copy of the LFRic Core source given by the `dependencies.yaml` "
12771258
f"file is located at:\n{macro_object.core_source}\nEnsure you "
12781259
"have committed those changes back to the core branch."
12791260
)

lfric_macros/check_macro_chains.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,8 @@ def main():
103103
Main function of the program
104104
"""
105105

106-
source_apps = os.path.join(os.environ["SOURCE_ROOT"], "apps")
107-
source_core = os.path.join(os.environ["SOURCE_ROOT"], "core")
106+
source_apps = os.path.join(os.environ["SOURCE_ROOT"], "lfric_apps")
107+
source_core = os.path.join(os.environ["SOURCE_ROOT"], "lfric_core")
108108

109109
macro_object = ApplyMacros(
110110
"vn0.0_t0", None, "vn0.0", source_apps, source_core, None

lfric_macros/release_lfric.py

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
import re
2323
import socket
2424
import subprocess
25+
import shutil
26+
import shlex
2527

2628
from apply_macros import (
2729
ApplyMacros,
@@ -54,7 +56,7 @@ def run_command(command, timelimit=120):
5456
- result object from subprocess.run
5557
"""
5658
result = subprocess.run(
57-
command.split(),
59+
shlex.split(command),
5860
capture_output=True,
5961
text=True,
6062
timeout=timelimit,
@@ -81,20 +83,25 @@ def set_dependency_path(args):
8183
LFRic Core source
8284
"""
8385

84-
print("[INFO] Updating dependencies.sh Core source")
86+
print("[INFO] Updating dependencies.yaml Core source")
8587

8688
hostname = socket.gethostname()
87-
dep_path = os.path.join(args.apps, "dependencies.sh")
89+
dep_path = os.path.join(args.apps, "dependencies.yaml")
8890
with open(dep_path) as f:
8991
lines = f.readlines()
92+
in_core = False
9093
for i, line in enumerate(lines):
91-
if line.strip().startswith("export lfric_core_rev"):
92-
lines[i] = "export lfric_core_rev=\n"
93-
if line.strip().startswith("export lfric_core_sources"):
94-
lines[i] = (
95-
"export lfric_core_sources="
96-
f"{hostname}:{os.path.abspath(args.core)}\n"
97-
)
94+
if line.strip().startswith("lfric_core"):
95+
in_core = True
96+
elif in_core and "source:" in line:
97+
prefix, _, _ = line.partition("source:")
98+
line = f"{prefix}source: {hostname}:{os.path.abspath(args.core)}\n"
99+
elif in_core and "ref:" in line:
100+
prefix, _, _ = line.partition("ref:")
101+
line = f"{prefix}ref:"
102+
elif in_core:
103+
break
104+
lines[i] = line
98105
with open(dep_path, "w") as f:
99106
f.write("".join(x for x in lines))
100107

@@ -216,8 +223,16 @@ def copy_head_meta(meta_dirs, args):
216223
for meta_dir in meta_dirs:
217224
head = os.path.join(meta_dir, "HEAD")
218225
new = os.path.join(meta_dir, args.version)
219-
command = f"fcm cp {head} {new}"
220-
result = run_command(command)
226+
shutil.copytree(head, new)
227+
if args.core in new:
228+
new = new.removeprefix(args.core)
229+
new = new.lstrip("/")
230+
command = f"git -C {args.core} add {new}"
231+
elif args.apps in new:
232+
new = new.removeprefix(args.apps)
233+
new = new.lstrip("/")
234+
command = f"git -C {args.apps} add {new}"
235+
_ = run_command(command)
221236

222237

223238
def update_meta_import_path(meta_dirs, args):
@@ -264,8 +279,18 @@ def copy_versions_files(meta_dirs, args):
264279
for meta_dir in meta_dirs:
265280
versions_file = os.path.join(meta_dir, "versions.py")
266281
upgrade_file = os.path.join(meta_dir, upgrade_name)
267-
command = f"fcm cp {versions_file} {upgrade_file}"
268-
result = run_command(command)
282+
if not os.path.exists(versions_file):
283+
raise FileNotFoundError(f"The file {versions_file} doesn't exist")
284+
shutil.copyfile(versions_file, upgrade_file)
285+
if args.core in upgrade_file:
286+
upgrade_file = upgrade_file.removeprefix(args.core)
287+
upgrade_file = upgrade_file.lstrip("/")
288+
command = f"git -C {args.core} add {upgrade_file}"
289+
elif args.apps in upgrade_file:
290+
upgrade_file = upgrade_file.removeprefix(args.apps)
291+
upgrade_file = upgrade_file.lstrip("/")
292+
command = f"git -C {args.apps} add {upgrade_file}"
293+
_ = run_command(command)
269294

270295
return upgrade_name
271296

@@ -321,8 +346,7 @@ def update_versions_file(meta_dirs, upgrade_name):
321346

322347
for meta_dir in meta_dirs:
323348
versions_file = os.path.join(meta_dir, "versions.py")
324-
command = f"cp {template_path} {versions_file}"
325-
result = run_command(command)
349+
shutil.copyfile(template_path, versions_file)
326350
add_new_import(versions_file, upgrade_name)
327351

328352

0 commit comments

Comments
 (0)