Skip to content

Commit 7d04d73

Browse files
committed
update git_fleximod
1 parent d422310 commit 7d04d73

20 files changed

+1450
-638
lines changed

.lib/git-fleximod/.github/workflows/pytest.yaml

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,7 @@ jobs:
7373
- run: |
7474
git config --global user.name "${GITHUB_ACTOR}"
7575
git config --global user.email "${GITHUB_ACTOR_ID}+${GITHUB_ACTOR}@users.noreply.github.com"
76-
poetry run pytest
77-
- name: Setup tmate session
78-
if: ${{ failure() }}
79-
uses: mxschmitt/action-tmate@v3
80-
76+
poetry run pytest --doctest-modules
77+
# - name: Setup tmate session
78+
# if: ${{ failure() }}
79+
# uses: mxschmitt/action-tmate@v3

.lib/git-fleximod/.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ exclude: ^utils/.*$
22

33
repos:
44
- repo: https://github.com/pre-commit/pre-commit-hooks
5-
rev: v4.0.1
5+
rev: v6.0.0
66
hooks:
77
- id: end-of-file-fixer
88
- id: trailing-whitespace

.lib/git-fleximod/CODE_OF_CONDUCT.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Examples of behaviors that contribute to a positive environment include:
1717
* Communicate openly with respect for others, critiquing ideas rather than individuals and gracefully accepting criticism
1818
* Acknowledging the contributions of others
1919
* Avoid personal attacks directed toward other participants
20-
* Be mindful of your surroundings and of your fellow participants
20+
* Be mindful of your surroundings and of your fellow participants
2121
* Alert UCAR staff and suppliers/vendors if you notice a dangerous situation or someone in distress
2222
* Respect the rules and policies of the project and venue
2323

@@ -29,7 +29,7 @@ Examples of unacceptable behavior include, but are not limited to:
2929
* Personal attacks directed at other guests, members, participants, etc.
3030
* Publishing others' private information, such as a physical or electronic address, without explicit permission
3131
* Alarming, intimidating, threatening, or hostile comments or conduct
32-
* Inappropriate use of nudity and/or sexual images
32+
* Inappropriate use of nudity and/or sexual images
3333
* Threatening or stalking anyone, including a participant
3434
* Other conduct which could reasonably be considered inappropriate in a professional setting
3535

@@ -60,7 +60,7 @@ the [Attribution](#attribution) section.
6060
## Reporting
6161
Instances of unacceptable behavior can be brought to the attention of the project administrator(s) who may take any action as
6262
outlined in the [Consequences](#consequences) section below.
63-
However, making a report to a project administrator is not considered an 'official report' to UCAR.
63+
However, making a report to a project administrator is not considered an 'official report' to UCAR.
6464

6565
Instances of unacceptable behavior may also be reported directly to UCAR pursuant to [UCAR's Harassment Reporting and Complaint
6666
Procedure](https://www2.fin.ucar.edu/procedures/hr/harassment-reporting-and-complaint-procedure), or anonymously through [UCAR's

.lib/git-fleximod/git_fleximod/cli.py

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
from pathlib import Path
22
import argparse, os, sys
3-
from git_fleximod import utils
43

5-
__version__ = "1.1.0"
4+
__version__ = "1.1.1"
5+
66

77
class CustomArgumentParser(argparse.ArgumentParser):
88
def print_help(self, file=None):
@@ -17,13 +17,28 @@ def print_help(self, file=None):
1717
for path in candidate_paths:
1818
if os.path.exists(path):
1919
with open(path) as f:
20-
print( f.read(), file=file)
20+
print(f.read(), file=file)
2121
return
22-
print( "README.md not found.", file=file)
22+
print("README.md not found.", file=file)
23+
2324

2425
def find_root_dir(filename=".gitmodules"):
25-
""" finds the highest directory in tree
26-
which contains a file called filename """
26+
"""
27+
Finds the highest directory in tree which contains a file called filename.
28+
29+
>>> import tempfile, os
30+
>>> cwd = os.getcwd()
31+
>>> with tempfile.TemporaryDirectory() as tmp:
32+
... subdir = Path(tmp) / 'subdir'
33+
... subdir.mkdir()
34+
... f = Path(tmp) / '.gitmodules'
35+
... _ = f.write_text('')
36+
... os.chdir(subdir)
37+
... result = find_root_dir('.gitmodules') == str(tmp)
38+
... os.chdir(cwd)
39+
... result
40+
True
41+
"""
2742
d = Path.cwd()
2843
root = Path(d.root)
2944
dirlist = []
@@ -40,6 +55,7 @@ def find_root_dir(filename=".gitmodules"):
4055
return str(dl)
4156
return None
4257

58+
4359
def get_parser():
4460
description = """
4561
%(prog)s manages checking out groups of gitsubmodules with additional support for Earth System Models
@@ -120,7 +136,7 @@ def get_parser():
120136
"--no-mods-details",
121137
action="store_true",
122138
default=False,
123-
help="Suppress details on local mods in status output."
139+
help="Suppress details on local mods in status output.",
124140
)
125141

126142
parser.add_argument(

.lib/git-fleximod/git_fleximod/git_fleximod.py

Lines changed: 51 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,27 @@
77

88
import os
99
import shutil
10-
import logging
11-
import textwrap
1210
import asyncio
11+
import logging
12+
from configparser import NoOptionError
1313
from git_fleximod import utils
1414
from git_fleximod import cli
1515
from git_fleximod.gitinterface import GitInterface
1616
from git_fleximod.gitmodules import GitModules
1717
from git_fleximod.submodule import Submodule
1818

19-
# logger variable is global
20-
logger = None
19+
logger = logging.getLogger(__name__)
2120

2221

2322
def fxrequired_allowed_values():
24-
return ["ToplevelRequired", "ToplevelOptional", "AlwaysRequired", "AlwaysOptional", "TopLevelRequired", "TopLevelOptional"]
23+
return [
24+
"ToplevelRequired",
25+
"ToplevelOptional",
26+
"AlwaysRequired",
27+
"AlwaysOptional",
28+
"TopLevelRequired",
29+
"TopLevelOptional",
30+
]
2531

2632

2733
def commandline_arguments(args=None):
@@ -152,8 +158,8 @@ def submodule_sparse_checkout(root_dir, name, url, path, sparsefile, tag="master
152158

153159
if os.path.isdir(os.path.join(root_dir, path, ".git")):
154160
with utils.pushd(sprep_repo):
155-
if os.path.isdir(os.path.join(topgit,".git")):
156-
shutil.rmtree(os.path.join(topgit,".git"))
161+
if os.path.isdir(os.path.join(topgit, ".git")):
162+
shutil.rmtree(os.path.join(topgit, ".git"))
157163
shutil.move(".git", topgit)
158164
with open(".git", "w") as f:
159165
f.write("gitdir: " + os.path.relpath(topgit))
@@ -168,7 +174,6 @@ def submodule_sparse_checkout(root_dir, name, url, path, sparsefile, tag="master
168174
with utils.pushd(sprep_repo):
169175
if os.path.isfile(sparsefile):
170176
shutil.copy(sparsefile, gitsparse)
171-
172177

173178
# Finally checkout the repo
174179
sprepo_git.git_operation("fetch", "origin", "--tags")
@@ -178,7 +183,8 @@ def submodule_sparse_checkout(root_dir, name, url, path, sparsefile, tag="master
178183
rgit.config_set_value(f'submodule "{name}"', "active", "true")
179184
rgit.config_set_value(f'submodule "{name}"', "url", url)
180185

181-
def init_submodule_from_gitmodules(gitmodules, name, root_dir, logger):
186+
187+
def init_submodule_from_gitmodules(gitmodules, name, root_dir, llogger):
182188
path = gitmodules.get(name, "path")
183189
url = gitmodules.get(name, "url")
184190
assert path and url, f"Malformed .gitmodules file {path} {url}"
@@ -188,16 +194,29 @@ def init_submodule_from_gitmodules(gitmodules, name, root_dir, logger):
188194
fxurl = gitmodules.get(name, "fxDONOTUSEurl")
189195
fxsparse = gitmodules.get(name, "fxsparse")
190196
fxrequired = gitmodules.get(name, "fxrequired")
191-
return Submodule(root_dir, name, path, url, fxtag=tag, fxurl=fxurl, fxsparse=fxsparse, fxrequired=fxrequired, logger=logger)
197+
return Submodule(
198+
root_dir,
199+
name,
200+
path,
201+
url,
202+
fxtag=tag,
203+
fxurl=fxurl,
204+
fxsparse=fxsparse,
205+
fxrequired=fxrequired,
206+
logger=llogger,
207+
)
208+
192209

193-
def submodules_status(gitmodules, root_dir, toplevel=False, depth=0, no_mods_details=False):
210+
def submodules_status(
211+
gitmodules, root_dir, toplevel=False, depth=0, no_mods_details=False
212+
):
194213
testfails = 0
195214
localmods = 0
196215
needsupdate = 0
197216
for name in gitmodules.sections():
198217
submod = init_submodule_from_gitmodules(gitmodules, name, root_dir, logger)
199218

200-
result,n,l,t = submod.status(depth=depth, no_mods_details=no_mods_details)
219+
result, n, l, t = submod.status(depth=depth, no_mods_details=no_mods_details)
201220
if toplevel or not submod.toplevel():
202221
print(result)
203222
testfails += t
@@ -216,33 +235,32 @@ def submodules_status(gitmodules, root_dir, toplevel=False, depth=0, no_mods_det
216235

217236
return testfails, localmods, needsupdate
218237

219-
def git_toplevelroot(root_dir, logger):
220-
rgit = GitInterface(root_dir, logger)
238+
239+
def git_toplevelroot(root_dir, llogger):
240+
rgit = GitInterface(root_dir, llogger)
221241
_, superroot = rgit.git_operation("rev-parse", "--show-superproject-working-tree")
222242
return superroot
223243

244+
224245
async def submodules_update(gitmodules, root_dir, requiredlist, force):
225246
async def update_submodule(name, requiredlist, force):
226247
submod = init_submodule_from_gitmodules(gitmodules, name, root_dir, logger)
227248

228-
_, needsupdate, localmods, testfails = submod.status()
229249
if not submod.fxrequired:
230250
submod.fxrequired = "AlwaysRequired"
231-
fxrequired = submod.fxrequired
251+
fxrequired = submod.fxrequired
232252
allowedvalues = fxrequired_allowed_values()
233253
assert fxrequired in allowedvalues
234254

235255
superroot = git_toplevelroot(root_dir, logger)
236-
237-
if (
238-
fxrequired
239-
and ((superroot and "Toplevel" in fxrequired)
240-
or fxrequired not in requiredlist)
256+
257+
if fxrequired and (
258+
(superroot and "Toplevel" in fxrequired) or fxrequired not in requiredlist
241259
):
242260
if "Optional" in fxrequired and "Optional" not in requiredlist:
243261
if fxrequired.startswith("Always"):
244262
print(f"Skipping optional component {name:>20}")
245-
return # continue to next submodule
263+
return # continue to next submodule
246264
optional = "AlwaysOptional" in requiredlist
247265

248266
if fxrequired in requiredlist:
@@ -255,11 +273,16 @@ async def update_submodule(name, requiredlist, force):
255273
newrequiredlist = ["AlwaysRequired"]
256274
if optional:
257275
newrequiredlist.append("AlwaysOptional")
258-
await submodules_update(gitsubmodules, repodir, newrequiredlist, force=force)
276+
await submodules_update(
277+
gitsubmodules, repodir, newrequiredlist, force=force
278+
)
259279

260-
tasks = [update_submodule(name, requiredlist, force) for name in gitmodules.sections()]
280+
tasks = [
281+
update_submodule(name, requiredlist, force) for name in gitmodules.sections()
282+
]
261283
await asyncio.gather(*tasks)
262284

285+
263286
def local_mods_output():
264287
text = """\
265288
The submodules labeled with 'M' above are not in a clean state.
@@ -273,6 +296,7 @@ def local_mods_output():
273296
"""
274297
print(text)
275298

299+
276300
def submodules_test(gitmodules, root_dir, no_mods_details=False):
277301
"""
278302
This function tests the git submodules based on the provided parameters.
@@ -327,7 +351,9 @@ def main():
327351
global logger
328352
logger = logging.getLogger(__name__)
329353

330-
logger.info("action is {} root_dir={} file_name={}".format(action, root_dir, file_name))
354+
logger.info(
355+
"action is {} root_dir={} file_name={}".format(action, root_dir, file_name)
356+
)
331357

332358
if not root_dir or not os.path.isfile(os.path.join(root_dir, file_name)):
333359
if root_dir:

0 commit comments

Comments
 (0)