Skip to content

Commit 0783038

Browse files
author
Matthew Fisher
committed
ref(client): assume app name is current directory
Previously, `deis create` would store session data in a ~/.deis/apps.yml file for applications with no git root to facilitate `deis pull`. This file looked similar to this: {'/tmp/deis-test': 'united-mainsail'} The issue with this means if you move your application's root directory somewhere else, the reference to the instance is lost. With this change, if no git root is present in the application directory, the base name of the current working directory (in the example above, that would be 'deis-test') is synonymous with the app name. With this in mind, `deis create` in a git repo retains the old behaviour (via the auto-generator from the server), but in a non-git directory, it takes the name of the current working directory. As always, --app works just like it used to, or you can still manually specify a name with `deis create <id>`.
1 parent 9b4b6b1 commit 0783038

1 file changed

Lines changed: 35 additions & 79 deletions

File tree

client/deis.py

Lines changed: 35 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -91,17 +91,31 @@ def __init__(self):
9191
self.cookies.load()
9292
self.cookies.clear_expired_cookies()
9393
self.cookies.save()
94-
# local session state
95-
self.state_file = os.path.expanduser('~/.deis/apps.yml')
96-
if not os.path.isfile(self.state_file):
97-
with open(self.state_file, 'w') as f:
98-
f.write(yaml.safe_dump({}))
94+
95+
@property
96+
def app(self):
97+
"""Retrieve the application's name."""
98+
try:
99+
return self._get_name_from_git_remote(self.git_root())
100+
except EnvironmentError:
101+
return os.path.basename(os.getcwd())
102+
103+
def is_git_app(self):
104+
"""Determines if this app is a git repository. This is important in special cases
105+
where we need to know whether or not we should use Deis' automatic app name
106+
generator, for example.
107+
"""
108+
try:
109+
self.git_root()
110+
return True
111+
except EnvironmentError:
112+
return False
99113

100114
def git_root(self):
101115
"""
102-
Return the absolute path from the git repository root
116+
Returns the absolute path from the git repository root.
103117
104-
If no git repository exists, raise an EnvironmentError
118+
If no git repository exists, raises an EnvironmentError.
105119
"""
106120
try:
107121
git_root = subprocess.check_output(
@@ -111,12 +125,12 @@ def git_root(self):
111125
raise EnvironmentError('Current directory is not a git repository')
112126
return git_root
113127

114-
def _get_app_from_git_remote(self, git_root):
128+
def _get_name_from_git_remote(self, git_root):
115129
"""
116-
Return the application name from a git repository root
130+
Retrieves the application name from a git repository root.
117131
118132
The application is determined by parsing `git remote -v` output.
119-
If no application is found, raise an EnvironmentError.
133+
If no application is found, raises an EnvironmentError.
120134
"""
121135
remotes = subprocess.check_output(['git', 'remote', '-v'],
122136
cwd=git_root)
@@ -130,55 +144,6 @@ def _get_app_from_git_remote(self, git_root):
130144
raise EnvironmentError("Could not parse: {url}".format(**locals()))
131145
return m.groupdict()['app']
132146

133-
def _get_app_from_state(self, current_dir):
134-
"""
135-
Return the application name from the current directory
136-
137-
Uses the local client's state to map to an application name.
138-
"""
139-
with open(self.state_file) as f:
140-
state = yaml.safe_load(f.read())
141-
app = state.get(current_dir, None)
142-
if app is None:
143-
raise EnvironmentError("Could not find app for {current_dir}".format(**locals()))
144-
return app
145-
146-
def _get_app(self):
147-
"""
148-
Return the application for the current directory
149-
150-
For backwards compatibility, the lookup will use:
151-
152-
1. Local client state stored in ~/.deis (preferred)
153-
2. A git remote for the current directory (for backwards compatibility)
154-
"""
155-
try:
156-
return self._get_app_from_state(os.getcwd())
157-
except EnvironmentError:
158-
return self._get_app_from_git_remote(self.git_root())
159-
160-
def _set_app(self, app):
161-
"""
162-
Set the application for the current directory
163-
"""
164-
with open(self.state_file, 'r') as f:
165-
state = yaml.safe_load(f.read())
166-
state[os.getcwd()] = app
167-
with open(self.state_file, 'w') as f:
168-
f.write(yaml.safe_dump(state))
169-
170-
def _del_app(self):
171-
"""
172-
Delete the application for the current directory
173-
"""
174-
with open(self.state_file, 'r') as f:
175-
state = yaml.safe_load(f.read())
176-
state.pop(os.getcwd())
177-
with open(self.state_file, 'w') as f:
178-
f.write(yaml.safe_dump(state))
179-
180-
app = property(_get_app, _set_app, _del_app)
181-
182147
def request(self, *args, **kwargs):
183148
"""
184149
Issue an HTTP request with proper cookie handling including
@@ -441,14 +406,12 @@ def apps_create(self, args):
441406
--cluster=CLUSTER target cluster to host application [default: dev]
442407
--no-remote do not create a 'deis' git remote
443408
"""
444-
try:
445-
self._session.app
446-
print('App already exists at {}'.format(os.getcwd()))
447-
sys.exit(1)
448-
except EnvironmentError:
449-
pass
450409
body = {}
451-
app_name = args.get('<id>')
410+
if not self._session.is_git_app():
411+
app_name = self._session.app
412+
# prevent app name from being set to None
413+
if args.get('<id>'):
414+
app_name = args.get('<id>')
452415
if app_name:
453416
body.update({'id': app_name})
454417
cluster = args.get('--cluster')
@@ -468,8 +431,6 @@ def apps_create(self, args):
468431
data = response.json()
469432
app_id = data['id']
470433
print("done, created {}".format(app_id))
471-
# store session in local state
472-
self._session.app = app_id
473434
# set a git remote if necessary
474435
try:
475436
self._session.git_root()
@@ -499,11 +460,7 @@ def apps_destroy(self, args):
499460
"""
500461
app = args.get('--app')
501462
if not app:
502-
try:
503-
app = self._session.app
504-
except EnvironmentError:
505-
print('No app exists at {}'.format(os.getcwd()))
506-
sys.exit(1)
463+
app = self._session.app
507464
confirm = args.get('--confirm')
508465
if confirm == app:
509466
pass
@@ -530,16 +487,15 @@ def apps_destroy(self, args):
530487
if response.status_code in (requests.codes.no_content, # @UndefinedVariable
531488
requests.codes.not_found): # @UndefinedVariable
532489
print('done in {}s'.format(int(time.time() - before)))
533-
# If the requested app is in the current dir, delete the git remote and local state
534-
if app == self._session.app:
535-
del self._session.app
536-
try:
490+
try:
491+
# If the requested app is a heroku app, delete the git remote
492+
if self._session.is_git_app():
537493
subprocess.check_call(
538494
['git', 'remote', 'rm', 'deis'],
539495
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
540496
print('Git remote deis removed')
541-
except (EnvironmentError, subprocess.CalledProcessError):
542-
pass # ignore error
497+
except (EnvironmentError, subprocess.CalledProcessError):
498+
pass # ignore error
543499
else:
544500
raise ResponseError(response)
545501

0 commit comments

Comments
 (0)