Index: appengine/components/tool_support/gae_sdk_utils.py |
diff --git a/appengine/components/tool_support/gae_sdk_utils.py b/appengine/components/tool_support/gae_sdk_utils.py |
index acb1c229bd9f58fbf1e8a63f9b0c37dafad8f9bd..61b96fdec908f71411374b8fe49ae2f16eca88e3 100644 |
--- a/appengine/components/tool_support/gae_sdk_utils.py |
+++ b/appengine/components/tool_support/gae_sdk_utils.py |
@@ -338,11 +338,12 @@ class Application(object): |
"""Runs appcfg.py <args>, deserializes its output and returns it.""" |
if USE_GCLOUD: |
raise Error('Attempting to run appcfg.py %s' % ' '.join(args)) |
- if not is_gcloud_oauth2_token_cached(): |
- raise LoginRequiredError('Login first using \'gcloud auth login\'.') |
+ if not is_appcfg_oauth_token_cached(): |
+ raise LoginRequiredError('Login first using \'gae.py appcfg_login\'.') |
cmd = [ |
sys.executable, |
os.path.join(self._gae_sdk, 'appcfg.py'), |
+ '--skip_sdk_update_check', |
'--application', self.app_id, |
] |
if self._verbose: |
@@ -353,7 +354,7 @@ class Application(object): |
def run_gcloud(self, args): |
"""Runs 'gcloud <args> --project ... --format ...' and parses the output.""" |
gcloud = find_gcloud() |
- if not is_gcloud_oauth2_token_cached(): |
+ if not is_gcloud_auth_set(): |
raise LoginRequiredError('Login first using \'gcloud auth login\'') |
raw = self.run_cmd( |
[gcloud] + args + ['--project', self.app_id, '--format', 'json']) |
@@ -713,16 +714,49 @@ def confirm(text, app, version, modules=None, default_yes=False): |
return raw_input('Continue? [y/N] ') in ('y', 'Y') |
-def is_gcloud_oauth2_token_cached(): |
+def is_gcloud_auth_set(): |
"""Returns false if 'gcloud auth login' needs to be run.""" |
- p = os.path.join(os.path.expanduser('~'), '.config', 'gcloud', 'credentials') |
try: |
- with open(p) as f: |
- return len(json.load(f)['data']) != 0 |
- except (KeyError, IOError, OSError, ValueError): |
+ # This returns an email address of currently active account or empty string |
+ # if no account is active. |
+ output = subprocess.check_output([ |
+ find_gcloud(), 'auth', 'list', |
+ '--filter=status:ACTIVE', '--format=value(account)', |
+ ]) |
+ return bool(output.strip()) |
+ except subprocess.CalledProcessError as exc: |
+ logging.error('Failed to check active gcloud account: %s', exc) |
return False |
+# TODO(vadimsh): Can be removed if using 'gcloud'. |
+def _appcfg_oauth2_tokens(): |
+ return os.path.join(os.path.expanduser('~'), '.appcfg_oauth2_tokens') |
+ |
+ |
+# TODO(vadimsh): Can be removed if using 'gcloud'. |
+def is_appcfg_oauth_token_cached(): |
+ """Returns true if ~/.appcfg_oauth2_tokens exists.""" |
+ return os.path.exists(_appcfg_oauth2_tokens()) |
+ |
+ |
+# TODO(vadimsh): Can be removed if using 'gcloud'. |
+def appcfg_login(app): |
+ """Starts appcfg.py's login flow.""" |
+ if not _GAE_SDK_PATH: |
+ raise ValueError('Call setup_gae_sdk first') |
+ if os.path.exists(_appcfg_oauth2_tokens()): |
+ os.remove(_appcfg_oauth2_tokens()) |
+ # HACK: Call a command with no side effect to launch the flow. |
+ subprocess.call([ |
+ sys.executable, |
+ os.path.join(_GAE_SDK_PATH, 'appcfg.py'), |
+ '--application', app.app_id, |
+ '--noauth_local_webserver', |
+ 'list_versions', |
+ ], cwd=app.app_dir) |
+ |
+ |
def setup_gae_env(): |
"""Sets up App Engine Python test environment by modifying sys.path.""" |
sdk_path = find_gae_sdk() |