Skip to content

Commit b15d6c9

Browse files
authored
Improve the log output, better path handling for Windows (#217)
1 parent 6e1e566 commit b15d6c9

File tree

3 files changed

+70
-35
lines changed

3 files changed

+70
-35
lines changed

mlc/index.py

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,16 @@ def __init__(self, repos_path, repos):
4040
self._load_existing_index()
4141
self.build_index()
4242

43+
def _get_stored_mtime(self, key):
44+
"""
45+
Helper method to safely extract mtime from stored data.
46+
Handles both old format (direct mtime) and new format (dict with mtime key).
47+
"""
48+
old = self.modified_times.get(key)
49+
if old is None:
50+
return None
51+
return old["mtime"] if isinstance(old, dict) else old
52+
4353
def _load_modified_times(self):
4454
"""
4555
Load stored mtimes to check for changes in scripts.
@@ -49,7 +59,8 @@ def _load_modified_times(self):
4959
# logger.info(f"Loading modified times from {self.modified_times_file}")
5060
with open(self.modified_times_file, "r") as f:
5161
return json.load(f)
52-
except Exception:
62+
except (json.JSONDecodeError, IOError) as e:
63+
logger.warning(f"Failed to load modified times: {e}")
5364
return {}
5465
return {}
5566

@@ -76,7 +87,8 @@ def _load_existing_index(self):
7687
if isinstance(item.get("repo"), dict):
7788
item["repo"] = Repo(**item["repo"])
7889

79-
except Exception:
90+
except (json.JSONDecodeError, IOError, KeyError, TypeError) as e:
91+
logger.warning(f"Failed to load index for {folder_type}: {e}")
8092
pass # fall back to empty index
8193

8294
def add(self, meta, folder_type, path, repo):
@@ -165,25 +177,32 @@ def _index_single_repo(self, repo, repos_changed=False, current_item_keys=None):
165177
elif os.path.isfile(json_path):
166178
config_path = json_path
167179
else:
168-
#logger.debug(f"No config file found in {automation_path}, skipping")
180+
# No config file found, remove from index if exists
169181
delete_flag = False
170-
if automation_dir in self.modified_times:
171-
del self.modified_times[automation_dir]
172-
if any(automation_dir in item["path"] for item in self.indices[folder_type]):
182+
183+
# Check and remove both possible config paths from modified_times
184+
for config_name in ["meta.yaml", "meta.json"]:
185+
config_key = os.path.join(automation_path, config_name)
186+
if config_key in self.modified_times:
187+
del self.modified_times[config_key]
188+
delete_flag = True
189+
190+
# Use exact path matching instead of substring
191+
if any(item["path"] == automation_path for item in self.indices[folder_type]):
173192
logger.debug(f"Removed index entry (if it exists) for {folder_type} : {automation_dir}")
174193
delete_flag = True
175194
self._remove_index_entry(automation_path)
195+
176196
if delete_flag:
177197
self._save_indices()
178198
continue
179199
if current_item_keys is not None:
180200
current_item_keys.add(config_path)
181201
mtime = self.get_item_mtime(config_path)
182-
old = self.modified_times.get(config_path)
183-
old_mtime = old["mtime"] if isinstance(old, dict) else old
202+
old_mtime = self._get_stored_mtime(config_path)
184203

185204
# skip if unchanged
186-
if old_mtime == mtime and repos_changed != 1:
205+
if old_mtime == mtime and not repos_changed:
187206
continue
188207

189208
self.modified_times[config_path] = {
@@ -220,6 +239,7 @@ def build_index(self):
220239
self.modified_times = {}
221240
self.indices = {k: [] for k in self.index_files.keys()}
222241
force_rebuild = True
242+
223243

224244
# index each repo
225245
for repo in self.repos:
@@ -246,10 +266,12 @@ def build_index(self):
246266

247267
def _remove_index_entry(self, key):
248268
logger.debug(f"Removing index entry for {key}")
269+
# Normalize paths for comparison
270+
normalized_key = os.path.normpath(key)
249271
for ft in self.indices:
250272
self.indices[ft] = [
251273
item for item in self.indices[ft]
252-
if key not in item["path"]
274+
if os.path.normpath(item["path"]) != normalized_key
253275
]
254276

255277
def _delete_by_uid(self, folder_type, uid, alias):
@@ -302,17 +324,14 @@ def _process_config_file(self, config_file, folder_type, folder_path, repo):
302324
alias = data.get("alias", None)
303325

304326
# Validate and add to indices
305-
if unique_id:
306-
self._delete_by_uid(folder_type, unique_id, alias)
307-
self.indices[folder_type].append({
308-
"uid": unique_id,
309-
"tags": tags,
310-
"alias": alias,
311-
"path": folder_path,
312-
"repo": repo
313-
})
314-
else:
315-
logger.warning(f"Skipping {config_file}: Missing 'uid' field.")
327+
self._delete_by_uid(folder_type, unique_id, alias)
328+
self.indices[folder_type].append({
329+
"uid": unique_id,
330+
"tags": tags,
331+
"alias": alias,
332+
"path": folder_path,
333+
"repo": repo
334+
})
316335

317336
except Exception as e:
318337
logger.error(f"Error processing {config_file}: {e}")

mlc/logger.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,27 @@ class ColoredFormatter(logging.Formatter):
1515
}
1616

1717
def format(self, record):
18-
# Add color to the levelname
18+
# Pad filename and line number for alignment
19+
record.filename = f"{record.filename:<15}" # Left-align filename with 15 char width
20+
record.lineno = f"{record.lineno:>4}" # Right-align line number with 4 char width
21+
22+
# Trim WARNING to WARN
23+
levelname = "WARN" if record.levelname == "WARNING" else record.levelname
24+
25+
# Pad and add color to the levelname
26+
levelname_padded = f"{levelname:<5}" # Left-align levelname with 5 char width
1927
if record.levelname in self.COLORS:
20-
record.levelname = f"{self.COLORS[record.levelname]}{record.levelname}{Style.RESET_ALL}"
28+
record.levelname = f"{self.COLORS[record.levelname]}{levelname_padded}{Style.RESET_ALL}"
29+
else:
30+
record.levelname = levelname_padded
2131
return super().format(record)
2232

2333

2434
# Set up logging configuration
2535
def setup_logging(log_path = os.getcwd(), log_file = '.mlc-log.txt'):
2636

2737
if not logger.hasHandlers():
28-
logFormatter = ColoredFormatter('[%(asctime)s %(filename)s:%(lineno)d %(levelname)s] - %(message)s')
38+
logFormatter = ColoredFormatter('[%(asctime)s %(filename)s:%(lineno)s %(levelname)s] - %(message)s')
2939
# by default logging level is set to INFO is being set
3040
logger.setLevel(logging.INFO)
3141

mlc/utils.py

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -694,24 +694,30 @@ def extract_file(options):
694694
with zipfile.ZipFile(filename, 'r') as archive:
695695
members = archive.namelist()
696696
for member in members:
697-
# Strip folder levels
698-
stripped_path = os.path.join(
699-
extract_to, *member.split(os.sep)[strip_folders:]
700-
)
701-
if member.endswith('/'): # Directory
702-
os.makedirs(stripped_path, exist_ok=True)
703-
else: # File
704-
os.makedirs(os.path.dirname(stripped_path), exist_ok=True)
705-
with archive.open(member) as source, open(stripped_path, 'wb') as target:
706-
shutil.copyfileobj(source, target)
697+
# Strip folder levels (zip files always use forward slashes internally)
698+
parts = member.split('/')
699+
if len(parts) > strip_folders:
700+
stripped_parts = parts[strip_folders:]
701+
stripped_path = os.path.join(extract_to, *stripped_parts)
702+
stripped_path = os.path.normpath(stripped_path)
703+
704+
if member.endswith('/'): # Directory
705+
os.makedirs(stripped_path, exist_ok=True)
706+
else: # File
707+
os.makedirs(os.path.dirname(stripped_path), exist_ok=True)
708+
with archive.open(member) as source, open(stripped_path, 'wb') as target:
709+
shutil.copyfileobj(source, target)
707710

708711
elif tarfile.is_tarfile(filename):
709712
with tarfile.open(filename, 'r') as archive:
710713
members = archive.getmembers()
711714
for member in members:
712715
if strip_folders:
716+
# Tar files also use forward slashes internally
713717
parts = member.name.split('/')
714-
member.name = '/'.join(parts[strip_folders:])
718+
if len(parts) > strip_folders:
719+
# Join with OS-specific separator for extraction
720+
member.name = os.path.join(*parts[strip_folders:])
715721
archive.extract(member, path=extract_to)
716722

717723
else:

0 commit comments

Comments
 (0)