11import logging
22import os
3+ from enum import Enum
34from pathlib import Path
4- from typing import Any , Optional
5+ from typing import Any , Optional , Set , Tuple
56
67import click
78
1718)
1819
1920
21+ class ConfigSource (Enum ):
22+ """
23+ Enum of the different sources of configuration
24+ where an API key or instance URL can come from
25+ """
26+
27+ CMD_OPTION = "command line option"
28+ DOTENV = ".env file"
29+ ENV_VAR = "environment variable"
30+ USER_CONFIG = "user config"
31+ DEFAULT = "default"
32+
33+
2034logger = logging .getLogger (__name__ )
2135
2236
@@ -26,7 +40,13 @@ class Config:
2640 AuthConfig.
2741 """
2842
29- __slots__ = ["user_config" , "auth_config" , "_cmdline_instance_name" , "_config_path" ]
43+ __slots__ = [
44+ "user_config" ,
45+ "auth_config" ,
46+ "_cmdline_instance_name" ,
47+ "_config_path" ,
48+ "_dotenv_vars" ,
49+ ]
3050
3151 user_config : UserConfig
3252 auth_config : AuthConfig
@@ -36,10 +56,16 @@ class Config:
3656
3757 _config_path : Path
3858
59+ # This environment variable helps us knowing whether environment variables
60+ # were set by the dotenv file or not
61+ # It is used in the `api-status` command to return the API key and instance sources
62+ _dotenv_vars : Set [str ]
63+
3964 def __init__ (self , config_path : Optional [Path ] = None ):
4065 self .user_config , self ._config_path = UserConfig .load (config_path = config_path )
4166 self .auth_config = AuthConfig .load ()
4267 self ._cmdline_instance_name = None
68+ self ._dotenv_vars = set ()
4369
4470 def save (self ) -> None :
4571 self .user_config .save (self ._config_path )
@@ -51,17 +77,23 @@ def config_path(self) -> Path:
5177
5278 @property
5379 def instance_name (self ) -> str :
80+ return self .get_instance_name_and_source ()[0 ]
81+
82+ def get_instance_name_and_source (self ) -> Tuple [str , ConfigSource ]:
5483 """
84+ Return the instance name and source of the selected instance.
85+
5586 The instance name (defaulting to URL) of the selected instance
5687 priority order is:
5788 - set from the command line (by setting cmdline_instance_name)
58- - env var (in auth_config.current_instance)
89+ - GITGUARDIAN_INSTANCE env var
90+ - GITGUARDIAN_API_URL env var
5991 - in local user config (in user_config.dashboard_url)
6092 - in global user config (in user_config.dashboard_url)
6193 - the default instance
6294 """
6395 if self ._cmdline_instance_name :
64- return self ._cmdline_instance_name
96+ return self ._cmdline_instance_name , ConfigSource . CMD_OPTION
6597
6698 try :
6799 url = os .environ ["GITGUARDIAN_INSTANCE" ]
@@ -70,20 +102,30 @@ def instance_name(self) -> str:
70102 pass
71103 else :
72104 validate_instance_url (url )
73- return remove_url_trailing_slash (url )
105+ source = (
106+ ConfigSource .DOTENV
107+ if "GITGUARDIAN_INSTANCE" in self ._dotenv_vars
108+ else ConfigSource .ENV_VAR
109+ )
110+ return remove_url_trailing_slash (url ), source
74111
75112 try :
76113 name = os .environ ["GITGUARDIAN_API_URL" ]
77114 logger .debug ("Using API URL from $GITGUARDIAN_API_URL" )
78115 except KeyError :
79116 pass
80117 else :
81- return api_to_dashboard_url (name , warn = True )
118+ source = (
119+ ConfigSource .DOTENV
120+ if "GITGUARDIAN_API_URL" in self ._dotenv_vars
121+ else ConfigSource .ENV_VAR
122+ )
123+ return api_to_dashboard_url (name , warn = True ), source
82124
83125 if self .user_config .instance :
84- return self .user_config .instance
126+ return self .user_config .instance , ConfigSource . USER_CONFIG
85127
86- return DEFAULT_INSTANCE_URL
128+ return DEFAULT_INSTANCE_URL , ConfigSource . DEFAULT
87129
88130 @property
89131 def cmdline_instance_name (self ) -> Optional [str ]:
@@ -123,7 +165,12 @@ def dashboard_url(self) -> str:
123165
124166 @property
125167 def api_key (self ) -> str :
168+ return self .get_api_key_and_source ()[0 ]
169+
170+ def get_api_key_and_source (self ) -> Tuple [str , ConfigSource ]:
126171 """
172+ Return the selected API key and its source
173+
127174 The API key to use
128175 priority order is
129176 - env var
@@ -132,9 +179,15 @@ def api_key(self) -> str:
132179 try :
133180 key = os .environ ["GITGUARDIAN_API_KEY" ]
134181 logger .debug ("Using API key from $GITGUARDIAN_API_KEY" )
182+ source = (
183+ ConfigSource .DOTENV
184+ if "GITGUARDIAN_API_KEY" in self ._dotenv_vars
185+ else ConfigSource .ENV_VAR
186+ )
135187 except KeyError :
136188 key = self .auth_config .get_instance_token (self .instance_name )
137- return key
189+ source = ConfigSource .USER_CONFIG
190+ return key , source
138191
139192 def add_ignored_match (self , * args : Any , ** kwargs : Any ) -> None :
140193 return self .user_config .secret .add_ignored_match (* args , ** kwargs )
0 commit comments