Coverage for core/src/version_finder/common.py: 85%

62 statements  

« prev     ^ index     » next       coverage.py v7.7.0, created at 2025-03-18 10:30 +0000

1""" 

2common.py 

3==================================== 

4Common utilities and constants for version_finder. 

5""" 

6import argparse 

7import os 

8from pathlib import Path 

9from typing import Optional 

10 

11# Default configuration values 

12DEFAULT_GIT_TIMEOUT = 30 # seconds 

13DEFAULT_GIT_MAX_RETRIES = 0 

14DEFAULT_GIT_RETRY_DELAY = 1 # seconds 

15 

16# Environment variable names 

17ENV_GIT_TIMEOUT = "GIT_TIMEOUT" 

18ENV_GIT_MAX_RETRIES = "GIT_MAX_RETRIES" 

19ENV_GIT_RETRY_DELAY = "GIT_RETRY_DELAY" 

20ENV_DEBUG = "VERSION_FINDER_DEBUG" 

21 

22# Git command constants 

23GIT_CMD_FETCH = ["fetch", "--all"] 

24GIT_CMD_CHECKOUT = ["checkout"] 

25GIT_CMD_SUBMODULE_UPDATE = ["submodule", "update", "--init", "--recursive"] 

26GIT_CMD_LIST_BRANCHES = ["branch", "-a"] 

27GIT_CMD_LIST_SUBMODULES = ["submodule", "status"] 

28GIT_CMD_LOG = ["log"] 

29GIT_CMD_SHOW = ["show"] 

30GIT_CMD_REV_PARSE = ["rev-parse"] 

31GIT_CMD_GREP = ["grep"] 

32 

33# Regex patterns 

34BRANCH_PATTERN = r"\s*(?:\*\s)?(.*)" 

35 

36# UI constants 

37MAX_COMMITS_DISPLAY = 1000 # Maximum number of commits to display in UI 

38MAX_LOG_ENTRIES = 500 # Maximum number of log entries to keep in UI 

39 

40# File paths 

41DEFAULT_CONFIG_PATH = os.path.expanduser("~/.version_finder/config.json") 

42 

43 

44def parse_arguments() -> argparse.Namespace: 

45 """ 

46 Parse command-line arguments. 

47 

48 Returns: 

49 argparse.Namespace: Parsed arguments 

50 """ 

51 parser = argparse.ArgumentParser(description="Version Finder - Find and compare versions in Git repositories") 

52 parser.add_argument("--path", "-p", type=str, default="", help="Path to the Git repository") 

53 parser.add_argument("--debug", "-d", action="store_true", help="Enable debug logging") 

54 parser.add_argument("--config", "-c", type=str, default=DEFAULT_CONFIG_PATH, help="Path to configuration file") 

55 parser.add_argument("--version", "-v", action="store_true", help="Show version information") 

56 parser.add_argument("--verbose", action="store_true", help="Enable verbose output") 

57 parser.add_argument( 

58 "--force", 

59 "-f", 

60 action="store_true", 

61 help="Force operation even if repository has uncommitted changes") 

62 parser.add_argument("--restore-state", "-r", action="store_true", 

63 help="Restore repository to original state after operation") 

64 parser.add_argument("--branch", "-b", type=str, help="Branch to use") 

65 parser.add_argument("--commit", type=str, help="Commit SHA to find version for") 

66 parser.add_argument("--submodule", "-s", type=str, help="Submodule to use") 

67 parser.add_argument("--cli", action="store_true", help="Run the CLI version") 

68 parser.add_argument("--gui", action="store_true", help="Run the GUI version") 

69 parser.add_argument("--task", "-t", type=str, help="Task to run") 

70 

71 return parser.parse_args() 

72 

73 

74def get_repository_path(path_arg: str) -> Optional[Path]: 

75 """ 

76 Get the repository path from the command-line argument or current directory. 

77 

78 Args: 

79 path_arg: Path argument from command line 

80 

81 Returns: 

82 Path: Repository path or None if invalid 

83 """ 

84 if path_arg: 

85 path = Path(path_arg) 

86 else: 

87 path = Path.cwd() 

88 

89 # Check if path exists and is a directory 

90 if not path.exists() or not path.is_dir(): 

91 return None 

92 

93 # Check if it's a git repository 

94 git_dir = path / ".git" 

95 if not git_dir.exists() or not git_dir.is_dir(): 

96 return None 

97 

98 return path 

99 

100 

101def args_to_command(args): 

102 """ 

103 Convert argparse.Namespace object to command-line arguments string. 

104 

105 Args: 

106 args: argparse.Namespace object containing command-line arguments 

107 

108 Returns: 

109 str: Command-line arguments as a string 

110 

111 Raises: 

112 AttributeError: If args is not an argparse.Namespace object 

113 """ 

114 if not isinstance(args, argparse.Namespace): 

115 raise AttributeError("args must be an argparse.Namespace object") 

116 

117 command_parts = [] 

118 

119 for key, value in vars(args).items(): 

120 # Replace underscores with hyphens in argument names 

121 arg_name = key.replace('_', '-') 

122 

123 # Include boolean flags that are True 

124 if isinstance(value, bool): 

125 if value: 

126 command_parts.append(f"--{arg_name}") 

127 # Include non-None and non-False values 

128 elif value is not None: 

129 command_parts.append(f"--{arg_name} {value}") 

130 

131 return " ".join(command_parts)