1+ from __future__ import annotations
2+
13import logging
24import sys
3- from pathlib import Path
45
56from .utils import (
67 extract_keywords ,
1112)
1213
1314logging .basicConfig (level = logging .INFO , format = "%(levelname)s: %(message)s" )
15+ logger = logging .getLogger (__name__ )
1416
1517# Map CFF types to BibTeX entry types
1618CFF_TO_BIBTEX_TYPES = {
7072}
7173
7274
73- def create_bibtex_from_cff ():
75+ def create_bibtex_from_cff () -> bool | None :
7476 """
75- Creates a CITATION.bib file from CITATION.cff.
77+ Create a CITATION.bib file from CITATION.cff.
7678
77- It reads citation data, prioritizing the 'preferred-citation' block if available,
79+ Reads citation data, prioritizing the 'preferred-citation' block if available,
7880 formats authors, generates a citation key, and constructs a BibTeX entry.
7981
80- Returns:
82+ Returns
83+ -------
8184 bool: True if successful, False otherwise.
8285 """
8386 try :
@@ -86,28 +89,31 @@ def create_bibtex_from_cff():
8689 repo_root = get_file_path ("" ) # Get repo root
8790 citation_cff_path = get_file_path ("CITATION.cff" , repo_root )
8891 citation_bib_path = get_file_path ("CITATION.bib" , repo_root )
89- except Exception as e :
90- logging . error ( f "Failed to resolve file paths: { str ( e ) } " )
92+ except Exception :
93+ logger . exception ( "Failed to resolve file paths" )
9194 return False
9295
9396 # Check if citation_cff_path exists
94- if not Path ( citation_cff_path ) .exists ():
95- logging .error (f "CITATION.cff file not found at { citation_cff_path } " )
97+ if not citation_cff_path .exists ():
98+ logger .error ("CITATION.cff file not found at %s" , citation_cff_path )
9699 return False
97100
98101 # Read CITATION.cff using utility function
99102 citation_data = load_yaml_file (citation_cff_path )
100103
101- if not citation_data :
102- logging .error (f "Could not load { citation_cff_path } . Exiting." )
104+ if not citation_data or not isinstance ( citation_data , dict ) :
105+ logger .error ("Could not load CITATION.cff or invalid format . Exiting." )
103106 return False
104107
105108 # Extract data from preferred-citation or root
106109 if "preferred-citation" in citation_data :
107- logging .info ("Using 'preferred-citation' section from CITATION.cff" )
110+ logger .info ("Using 'preferred-citation' section from CITATION.cff" )
108111 pref = citation_data .get ("preferred-citation" )
112+ if not isinstance (pref , dict ):
113+ logger .error ("preferred-citation is not a dictionary" )
114+ return False
109115 else :
110- logging .info ("No 'preferred-citation' section found, using root data" )
116+ logger .info ("No 'preferred-citation' section found, using root data" )
111117 pref = citation_data
112118
113119 # Validate required fields
@@ -116,19 +122,19 @@ def create_bibtex_from_cff():
116122 year = str (pref .get ("year" , "" )) # Ensure year is a string for generate_citation_key
117123
118124 if not authors :
119- logging .warning ("No authors found in CITATION.cff" )
125+ logger .warning ("No authors found in CITATION.cff" )
120126
121127 if title == "Untitled" :
122- logging .warning ("No title found in CITATION.cff, using 'Untitled'" )
128+ logger .warning ("No title found in CITATION.cff, using 'Untitled'" )
123129
124130 if not year :
125- logging .warning ("No year found in CITATION.cff" )
131+ logger .warning ("No year found in CITATION.cff" )
126132
127133 # Use utility function to format authors
128134 try :
129135 author_str = format_authors_for_bibtex (authors )
130- except Exception as e :
131- logging . error ( f "Error formatting authors: { str ( e ) } " )
136+ except Exception :
137+ logger . exception ( "Error formatting authors" )
132138 author_str = ""
133139
134140 # Choose entry type based on type field
@@ -141,19 +147,19 @@ def create_bibtex_from_cff():
141147 if entry_type == "thesis" :
142148 # Check for thesis type information
143149 thesis_type = pref .get ("thesis-type" , "" ).lower ()
144- if thesis_type == "master" or thesis_type == "masters" or thesis_type == "master's" :
150+ if thesis_type in { "master" , "masters" , "master's" } :
145151 entry_type = "mastersthesis"
146152 else :
147153 # Default to phdthesis if type is not specified or is something else
148154 entry_type = "phdthesis"
149155
150- logging .info (f "Converting CFF type '{ cff_type } ' to BibTeX entry type: { entry_type } " )
156+ logger .info ("Converting CFF type '%s ' to BibTeX entry type: %s" , cff_type , entry_type )
151157
152158 # Use utility function to generate citation key
153159 try :
154160 citation_key = generate_citation_key (authors , title , year )
155- except Exception as e :
156- logging . error ( f "Error generating citation key: { str ( e ) } " )
161+ except Exception :
162+ logger . exception ( "Error generating citation key" )
157163 citation_key = "Unknown_Citation_Key"
158164
159165 # Compile BibTeX entry
@@ -254,8 +260,8 @@ def create_bibtex_from_cff():
254260 try :
255261 editor_str = format_authors_for_bibtex (pref ["collection-editors" ])
256262 bibtex_lines .append (f" editor = {{{ editor_str } }}," )
257- except Exception as e :
258- logging .warning (f "Error formatting collection editors: { str ( e ) } " )
263+ except ( KeyError , TypeError , AttributeError ) as e :
264+ logger .warning ("Error formatting collection editors: %s" , e )
259265
260266 # Special handling for software, code, data entries
261267 if cff_type .lower ().startswith ("software" ) or cff_type .lower () in [
@@ -299,39 +305,40 @@ def create_bibtex_from_cff():
299305 bibtex_lines .append (f" { field :<9} = {{{ field_value } }}," )
300306
301307 # Handle list fields like languages
302- if "languages" in pref and pref [ "languages" ] :
308+ if pref . get ( "languages" ) :
303309 try :
304310 languages_str = ", " .join (pref ["languages" ])
305311 bibtex_lines .append (f" language = {{{ languages_str } }}," )
306- except Exception as e :
307- logging .warning (f "Error processing languages field: { str ( e ) } " )
312+ except ( TypeError , AttributeError ) as e :
313+ logger .warning ("Error processing languages field: %s" , e )
308314
309315 # Handle keywords field
310- if "keywords" in pref and pref [ "keywords" ] :
316+ if pref . get ( "keywords" ) :
311317 try :
312318 keywords_list = extract_keywords (pref ["keywords" ])
313319 if keywords_list :
314320 keywords_str = ", " .join (keywords_list )
315321 bibtex_lines .append (f" keywords = {{{ keywords_str } }}," )
316- except Exception as e :
317- logging .warning (f "Error processing keywords field: { str ( e ) } " )
322+ except ( TypeError , AttributeError ) as e :
323+ logger .warning ("Error processing keywords field: %s" , e )
318324
319325 # Close the entry
320326 bibtex_lines .append ("}" )
321327 bibtex = "\n " .join (bibtex_lines )
322328
323329 # Write to CITATION.bib
324330 try :
325- with open (citation_bib_path , "w" , encoding = "utf-8" ) as f :
331+ with citation_bib_path . open ("w" , encoding = "utf-8" ) as f :
326332 f .write (bibtex )
327- logging .info (f"BibTeX citation successfully created at { citation_bib_path } " )
328- return True
329- except IOError as e :
330- logging .error (f"Error writing to { citation_bib_path } : { e } " )
333+ except OSError :
334+ logger .exception ("Error writing to {citation_bib_path}" )
331335 return False
336+ else :
337+ logger .info ("BibTeX citation successfully created at %s" , citation_bib_path )
338+ return True
332339
333- except Exception as e :
334- logging .exception (f "Unexpected error in create_bibtex_from_cff: { str ( e ) } " )
340+ except Exception :
341+ logger .exception ("Unexpected error in create_bibtex_from_cff" )
335342 return False
336343
337344
0 commit comments