Skip to content

Commit 52b1b81

Browse files
authored
Merge pull request #9 from samsrabin/verbosity
Rework verbosity
2 parents 27a83c4 + ddde636 commit 52b1b81

2 files changed

Lines changed: 373 additions & 28 deletions

File tree

relink.py

Lines changed: 55 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,17 @@
55
"""
66

77
import os
8+
import sys
89
import pwd
910
import argparse
11+
import logging
1012

1113
DEFAULT_SOURCE_ROOT = '/glade/campaign/cesm/cesmdata/cseg/inputdata/'
1214
DEFAULT_TARGET_ROOT = '/glade/campaign/collections/gdex/data/d651077/cesmdata/inputdata/'
1315

16+
# Set up logger
17+
logger = logging.getLogger(__name__)
18+
1419
def find_and_replace_owned_files(source_dir, target_dir, username):
1520
"""
1621
Finds files owned by a specific user in a source directory tree,
@@ -29,10 +34,15 @@ def find_and_replace_owned_files(source_dir, target_dir, username):
2934
try:
3035
user_uid = pwd.getpwnam(username).pw_uid
3136
except KeyError:
32-
print(f"Error: User '{username}' not found. Exiting.")
37+
logger.error("Error: User '%s' not found. Exiting.", username)
3338
return
3439

35-
print(f"Searching for files owned by '{username}' (UID: {user_uid}) in '{source_dir}'...")
40+
logger.info(
41+
"Searching for files owned by '%s' (UID: %s) in '%s'...",
42+
username,
43+
user_uid,
44+
source_dir
45+
)
3646

3747
for dirpath, _, filenames in os.walk(source_dir):
3848
for filename in filenames:
@@ -41,23 +51,28 @@ def find_and_replace_owned_files(source_dir, target_dir, username):
4151
# Use os.stat().st_uid to get the file's owner UID
4252
try:
4353
if os.path.islink(file_path):
44-
print(f"Skipping symlink: {file_path}")
54+
logger.info("Skipping symlink: %s", file_path)
4555
continue
4656

4757
file_uid = os.stat(file_path).st_uid
4858
except FileNotFoundError:
4959
continue # Skip if file was deleted during traversal
5060

5161
if file_uid == user_uid:
52-
print(f"Found owned file: {file_path}")
62+
logger.info("Found owned file: %s", file_path)
5363

5464
# Determine the relative path and the new link's destination
5565
relative_path = os.path.relpath(file_path, source_dir)
5666
link_target = os.path.join(target_dir, relative_path)
5767

5868
# Check if the target file actually exists
5969
if not os.path.exists(link_target):
60-
print(f"Warning: Corresponding file not found in '{target_dir}' for '{file_path}'. Skipping.")
70+
logger.warning(
71+
"Warning: Corresponding file not found in '%s' "
72+
"for '%s'. Skipping.",
73+
target_dir,
74+
file_path
75+
)
6176
continue
6277

6378
# Get the link name
@@ -66,9 +81,9 @@ def find_and_replace_owned_files(source_dir, target_dir, username):
6681
# Remove the original file
6782
try:
6883
os.rename(link_name, link_name+".tmp")
69-
print(f"Deleted original file: {link_name}")
84+
logger.info("Deleted original file: %s", link_name)
7085
except OSError as e:
71-
print(f"Error deleting file {link_name}: {e}. Skipping.")
86+
logger.error("Error deleting file %s: %s. Skipping.", link_name, e)
7287
continue
7388

7489
# Create the symbolic link, handling necessary parent directories
@@ -77,18 +92,18 @@ def find_and_replace_owned_files(source_dir, target_dir, username):
7792
os.makedirs(os.path.dirname(link_name), exist_ok=True)
7893
os.symlink(link_target, link_name)
7994
os.remove(link_name+".tmp")
80-
print(f"Created symbolic link: {link_name} -> {link_target}")
95+
logger.info("Created symbolic link: %s -> %s", link_name, link_target)
8196
except OSError as e:
8297
os.rename(link_name+".tmp", link_name)
83-
print(f"Error creating symlink for {link_name}: {e}. Skipping.")
98+
logger.error("Error creating symlink for %s: %s. Skipping.", link_name, e)
8499

85100
def parse_arguments():
86101
"""
87102
Parse command-line arguments.
88103
89104
Returns:
90-
argparse.Namespace: Parsed arguments containing source_root
91-
and target_root.
105+
argparse.Namespace: Parsed arguments containing source_root,
106+
target_root, and verbosity settings.
92107
"""
93108
parser = argparse.ArgumentParser(
94109
description=(
@@ -111,11 +126,39 @@ def parse_arguments():
111126
)
112127
)
113128

129+
# Verbosity options (mutually exclusive)
130+
verbosity_group = parser.add_mutually_exclusive_group()
131+
verbosity_group.add_argument(
132+
'-v', '--verbose',
133+
action='store_true',
134+
help='Enable verbose output'
135+
)
136+
verbosity_group.add_argument(
137+
'-q', '--quiet',
138+
action='store_true',
139+
help='Quiet mode (show only warnings and errors)'
140+
)
141+
114142
return parser.parse_args()
115143

116144
if __name__ == '__main__':
117-
# --- Configuration ---
145+
118146
args = parse_arguments()
147+
148+
# Configure logging based on verbosity flags
149+
if args.quiet:
150+
LOG_LEVEL = logging.WARNING
151+
elif args.verbose:
152+
LOG_LEVEL = logging.DEBUG
153+
else:
154+
LOG_LEVEL = logging.INFO
155+
156+
logging.basicConfig(
157+
level=LOG_LEVEL,
158+
format='%(message)s',
159+
stream=sys.stdout
160+
)
161+
119162
my_username = os.environ['USER']
120163

121164
# --- Execution ---

0 commit comments

Comments
 (0)