5757 (?P<nanos>\d{1,9}) # nanoseconds, maybe truncated
5858 Z # Zulu
5959""" , re .VERBOSE )
60- DEFAULT_CONFIGURATION_PATH = '~/.config/gcloud/configurations/config_default'
60+ # NOTE: Catching this ImportError is a workaround for GAE not supporting the
61+ # "pwd" module which is imported lazily when "expanduser" is called.
62+ try :
63+ _USER_ROOT = os .path .expanduser ('~' )
64+ except ImportError : # pragma: NO COVER
65+ _USER_ROOT = None
66+ _GCLOUD_CONFIG_FILE = os .path .join (
67+ 'gcloud' , 'configurations' , 'config_default' )
68+ _GCLOUD_CONFIG_SECTION = 'core'
69+ _GCLOUD_CONFIG_KEY = 'project'
6170
6271
6372class _LocalStack (Local ):
@@ -171,10 +180,10 @@ def _app_engine_id():
171180
172181
173182def _file_project_id ():
174- """Gets the project id from the credentials file if one is available.
183+ """Gets the project ID from the credentials file if one is available.
175184
176185 :rtype: str or ``NoneType``
177- :returns: Project- ID from JSON credentials file if value exists,
186+ :returns: Project ID from JSON credentials file if value exists,
178187 else ``None``.
179188 """
180189 credentials_file_path = os .getenv (CREDENTIALS )
@@ -185,9 +194,37 @@ def _file_project_id():
185194 return credentials .get ('project_id' )
186195
187196
197+ def _get_nix_config_path ():
198+ """Get the ``gcloud`` CLI config path on *nix systems.
199+
200+ :rtype: str
201+ :returns: The filename on a *nix system containing the CLI
202+ config file.
203+ """
204+ return os .path .join (_USER_ROOT , '.config' , _GCLOUD_CONFIG_FILE )
205+
206+
207+ def _get_windows_config_path ():
208+ """Get the ``gcloud`` CLI config path on Windows systems.
209+
210+ :rtype: str
211+ :returns: The filename on a Windows system containing the CLI
212+ config file.
213+ """
214+ appdata_dir = os .getenv ('APPDATA' , '' )
215+ return os .path .join (appdata_dir , _GCLOUD_CONFIG_FILE )
216+
217+
188218def _default_service_project_id ():
189219 """Retrieves the project ID from the gcloud command line tool.
190220
221+ This assumes the ``.config`` directory is stored
222+ - in ~/.config on *nix systems
223+ - in the %APPDATA% directory on Windows systems
224+
225+ Additionally, the ${HOME} / "~" directory may not be present on Google
226+ App Engine, so this may be conditionally ignored.
227+
191228 Files that cannot be opened with configparser are silently ignored; this is
192229 designed so that you can specify a list of potential configuration file
193230 locations.
@@ -196,21 +233,17 @@ def _default_service_project_id():
196233 :returns: Project-ID from default configuration file else ``None``
197234 """
198235 search_paths = []
199- # Workaround for GAE not supporting pwd which is used by expanduser.
200- try :
201- search_paths . append ( os . path . expanduser ( DEFAULT_CONFIGURATION_PATH ))
202- except ImportError :
203- pass
236+ if _USER_ROOT is not None :
237+ search_paths . append ( _get_nix_config_path ())
238+
239+ if os . name == 'nt' :
240+ search_paths . append ( _get_windows_config_path ())
204241
205- windows_config_path = os .path .join (os .getenv ('APPDATA' , '' ),
206- 'gcloud' , 'configurations' ,
207- 'config_default' )
208- search_paths .append (windows_config_path )
209242 config = configparser .RawConfigParser ()
210243 config .read (search_paths )
211244
212- if config .has_section ('core' ):
213- return config .get ('core' , 'project' )
245+ if config .has_section (_GCLOUD_CONFIG_SECTION ):
246+ return config .get (_GCLOUD_CONFIG_SECTION , _GCLOUD_CONFIG_KEY )
214247
215248
216249def _compute_engine_id ():
0 commit comments