Coverage for src / eclipse / care / __init__.py: 31%

72 statements  

« prev     ^ index     » next       coverage.py v7.13.5, created at 2026-03-24 09:38 +0100

1# Copyright (c) 2025 The Eclipse Foundation 

2# 

3# This program and the accompanying materials are made available under the 

4# terms of the Eclipse Public License 2.0 which is available at 

5# http://www.eclipse.org/legal/epl-2.0. 

6# 

7# SPDX-License-Identifier: EPL-2.0 

8# 

9# Contributors: 

10# asgomes - Initial implementation 

11 

12"""Main functions for the utility.  

13  

14Eclipse CARE is a tool to assess and provide recommendations for open source  

15best practices in Eclipse projects. 

16""" 

17 

18__version__ = "0.0.2" 

19 

20import argparse 

21import configparser 

22import json 

23import sys 

24import os 

25import importlib 

26 

27from colorama import init 

28 

29from .utils import print_error 

30 

31# Initialize colorama 

32init(autoreset=True) 

33 

34# Define the default modules to run if the user doesn't specify any with -m 

35DEFAULT_MODULES = [ 

36 ".legal.recommended_files", 

37 ".copyright.copyright_headers" 

38] 

39 

40 

41def main(): 

42 """ 

43 Main entry point for Eclipse CARE. 

44 

45 Initializes and runs the primary application logic. This function is 

46 responsible for setting up the execution environment, parsing user 

47 input, and managing configuration before delegating control to other 

48 application modules. 

49 """ 

50 

51 # Handle parameters and defaults 

52 parser = argparse.ArgumentParser( 

53 description="Eclipse CARE -- Eclipse best practices assessment and recommendations." 

54 ) 

55 

56 parser.add_argument('project_id', action='store', 

57 help='The Eclipse project ID to assess.') 

58 parser.add_argument('-c', '--conf', action='store', 

59 help='Ini file containing authentication data.') 

60 parser.add_argument('-m', '--modules', action='append', 

61 help='Run the specified module. Can be specified multiple times.') 

62 parser.add_argument('-v', '--verbose', action='store_true', 

63 help='Display more verbose information.') 

64 parser.add_argument('-V', '--version', action='version', version=f'Eclipse CARE {__version__}', 

65 help='Show the version and exit') 

66 

67 try: 

68 args = parser.parse_args() 

69 except argparse.ArgumentError as e: 

70 print_error(str(e)) 

71 sys.exit(1) 

72 

73 if args.project_id: 

74 print(f"Analysing project {args.project_id}.") 

75 

76 if args.verbose: 

77 print("- Enabling verbose.") 

78 

79 # Manage credentials 

80 credentials = {} 

81 auth_src = None 

82 

83 if args.conf: 

84 # Form provided configuration file 

85 auth_src = f"using configuration from file {args.conf}" 

86 

87 # Read .ini config file 

88 config = configparser.ConfigParser(interpolation=None) 

89 try: 

90 with open(args.conf, "r") as f: 

91 data = f.read() 

92 config.read_string(data) 

93 except Exception as e: 

94 print("Error reading " + args.conf + " file:" + str(e) + ".") 

95 sys.exit(1) 

96 

97 # Get the GH/GL tokens from the config file and store them in the credentials dict 

98 if config.has_section("GitHub") and config.has_option("GitHub", "gh_token"): 

99 credentials['GH_TOKEN'] = config.get("GitHub", "gh_token") 

100 

101 if config.has_section("GitLab") and config.has_option("GitLab", "gl_token"): 

102 credentials['GL_TOKEN'] = config.get("GitLab", "gl_token") 

103 

104 # Read authentication data from env vars (overriding file config, if present): 

105 if 'GH_AUTH_TOKEN' in os.environ: 

106 auth_src = "using GH token from env var GH_AUTH_TOKEN" 

107 credentials['GH_TOKEN'] = os.environ['GH_AUTH_TOKEN'] 

108 

109 if 'GL_AUTH_TOKEN' in os.environ: 

110 auth_src = "using GL token from env var GL_AUTH_TOKEN" 

111 credentials['GL_TOKEN'] = os.environ['GL_AUTH_TOKEN'] 

112 

113 if args.verbose and auth_src: 

114 print('- Connecting ' + auth_src) 

115 

116 results = {} 

117 

118 # Determine which list of modules to run 

119 modules_to_run = args.modules if args.modules else DEFAULT_MODULES 

120 

121 # Execute the selected modules dynamically 

122 for m in modules_to_run: 

123 try: 

124 # Import the module dynamically 

125 module = importlib.import_module(m, __package__) 

126 if args.verbose: 

127 print(f"Successfully imported module {m}.") 

128 

129 # Create a clean dictionary key (e.g., '.legal.recommended_files' -> 'recommended_files') 

130 module_key = m.split('.')[-1] 

131 

132 # Execute the module's analyse_project function 

133 results[module_key] = module.analyse_project( 

134 project_id=args.project_id, 

135 credentials=credentials, 

136 verbose=args.verbose 

137 ) 

138 except AttributeError: 

139 print_error(f"Module '{m}' is missing the required 'analyse_project' function.") 

140 sys.exit(1) 

141 except ModuleNotFoundError: 

142 print_error(f"Module '{m}' could not be found. Check the module path.") 

143 sys.exit(1) 

144 except Exception as e: 

145 print_error(f"Failed to run module '{m}': {e}") 

146 sys.exit(1) 

147 

148 # Print the final JSON output 

149 print(json.dumps(results, indent=2)) 

150 

151 

152if __name__ == '__main__': 

153 main()