experimental git support (needs a little more work), thanks Andrew Replogle
This commit is contained in:
2
VERSION
2
VERSION
@@ -1 +1 @@
|
||||
Version 2.00.0 (2012-07-21 13:29:17) dev
|
||||
Version 2.00.0 (2012-07-21 16:12:40) dev
|
||||
|
||||
@@ -14,15 +14,24 @@ from gluon.fileutils import abspath, read_file, write_file
|
||||
from glob import glob
|
||||
import shutil
|
||||
import platform
|
||||
try:
|
||||
from git import *
|
||||
have_git = True
|
||||
except ImportError:
|
||||
have_git = False
|
||||
GIT_MISSING = 'requires python-git module, but not installed'
|
||||
|
||||
from gluon.languages import (regex_language, read_possible_languages,
|
||||
read_possible_plurals, lang_sampling,
|
||||
read_dict, write_dict, read_plural_dict,
|
||||
write_plural_dict)
|
||||
|
||||
if DEMO_MODE and request.function in ['change_password','pack','pack_plugin','upgrade_web2py','uninstall','cleanup','compile_app','remove_compiled_app','delete','delete_plugin','create_file','upload_file','update_languages','reload_routes']:
|
||||
|
||||
if DEMO_MODE and request.function in ['change_password','pack','pack_plugin','upgrade_web2py','uninstall','cleanup','compile_app','remove_compiled_app','delete','delete_plugin','create_file','upload_file','update_languages','reload_routes','git_push','git_pull']:
|
||||
session.flash = T('disabled in demo mode')
|
||||
redirect(URL('site'))
|
||||
|
||||
|
||||
if not is_manager() and request.function in ['change_password','upgrade_web2py']:
|
||||
session.flash = T('disabled in multi user mode')
|
||||
redirect(URL('site'))
|
||||
@@ -188,6 +197,23 @@ def site():
|
||||
msg = 'you must specify a name for the uploaded application'
|
||||
response.flash = T(msg)
|
||||
|
||||
elif (request.vars.appurl or '').endswith('.git') and request.vars.filename:
|
||||
if not have_git:
|
||||
session.flash = GIT_MISSING
|
||||
elif request.vars.filename:
|
||||
target = os.path.join(apath(r=request),request.vars.filename)
|
||||
if os.path.exists(target):
|
||||
session.flash = 'Application by that name already exists.'
|
||||
else:
|
||||
try:
|
||||
new_repo = Repo.clone_from(request.vars.appurl,target)
|
||||
session.flash = T('new application "%s" imported',request.vars.filename)
|
||||
except GitCommandError, err:
|
||||
session.flash = T('Invalid git repository specified.')
|
||||
else:
|
||||
session.flash = 'Application Name required for git import.'
|
||||
redirect(URL(r=request))
|
||||
|
||||
elif file_or_appurl and request.vars.filename:
|
||||
# fetch an application via URL or file upload
|
||||
f = None
|
||||
@@ -1558,3 +1584,76 @@ def bulk_register():
|
||||
redirect(URL('site'))
|
||||
return locals()
|
||||
|
||||
### Begin experimental stuff need fixes:
|
||||
# 1) should run in its own process - cannot os.chdir
|
||||
# 2) should not prompt user at console
|
||||
# 3) should give option to force commit and not reuqire manual merge
|
||||
|
||||
def git_pull():
|
||||
""" Git Pull handler """
|
||||
app = get_app()
|
||||
if not have_git:
|
||||
session.flash = GIT_MISSING
|
||||
redirect(URL('site'))
|
||||
if 'pull' in request.vars:
|
||||
try:
|
||||
repo = Repo(os.path.join(apath(r=request),app))
|
||||
origin = repo.remotes.origin
|
||||
origin.fetch()
|
||||
origin.pull()
|
||||
session.flash = T("Application updated via git pull")
|
||||
redirect(URL('site'))
|
||||
except CheckoutError, message:
|
||||
logging.error(message)
|
||||
session.flash = T("Pull failed, certain files could not be checked out. Check logs for details.")
|
||||
redirect(URL('site'))
|
||||
except UnmergedEntriesError:
|
||||
session.flash = T("Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.")
|
||||
redirect(URL('site'))
|
||||
except AssertionError:
|
||||
session.flash = T("Pull is not possible because you have unmerged files. Fix them up in the work tree, and then try again.")
|
||||
redirect(URL('site'))
|
||||
except GitCommandError, status:
|
||||
logging.error(str(status))
|
||||
session.flash = T("Pull failed, git exited abnormally. See logs for details.")
|
||||
redirect(URL('site'))
|
||||
except Exception,e:
|
||||
logging.error("Unexpected error:", sys.exc_info()[0])
|
||||
session.flash = T("Pull failed, git exited abnormally. See logs for details.")
|
||||
redirect(URL('site'))
|
||||
elif 'cancel' in request.vars:
|
||||
redirect(URL('site'))
|
||||
return dict(app=app)
|
||||
|
||||
|
||||
def git_push():
|
||||
""" Git Push handler """
|
||||
app = get_app()
|
||||
if not have_git:
|
||||
session.flash = GIT_MISSING
|
||||
redirect(URL('site'))
|
||||
form = SQLFORM.factory(Field('changelog',requires=IS_NOT_EMPTY()))
|
||||
form.element('input[type=submit]')['_value']=T('Push')
|
||||
form.add_button(T('Cancel'),URL('site'))
|
||||
form.process()
|
||||
if form.accepted:
|
||||
try:
|
||||
repo = Repo(os.path.join(apath(r=request),app))
|
||||
index = repo.index
|
||||
os.chdir(os.path.join(apath(r=request),app))
|
||||
index.add('*')
|
||||
new_commit = index.commit(form.vars.changelog)
|
||||
origin = repo.remotes.origin
|
||||
origin.push()
|
||||
session.flash = T("Git repo updated with latest application changes.")
|
||||
redirect(URL('site'))
|
||||
except UnmergedEntriesError:
|
||||
session.flash = T("Push failed, there are unmerged entries in the cache. Resolve merge issues manually and try again.")
|
||||
redirect(URL('site'))
|
||||
except Exception, e:
|
||||
logging.error("Unexpected error:", sys.exc_info()[0])
|
||||
session.flash = T("Push failed, git exited abnormally. See logs for details.")
|
||||
redirect(URL('site'))
|
||||
os.chdir(apath(r=request))
|
||||
return dict(app=app,form=form)
|
||||
|
||||
|
||||
9
applications/admin/views/default/git_pull.html
Normal file
9
applications/admin/views/default/git_pull.html
Normal file
@@ -0,0 +1,9 @@
|
||||
{{extend 'layout.html'}}
|
||||
|
||||
<center>
|
||||
<h2>{{=T('This will pull changes from the remote repo for application "%s"?', app)}}</h2>
|
||||
<table><tr>
|
||||
<td>{{=FORM(INPUT(_type='submit',_name='cancel',_value=T('Cancel')))}}</td>
|
||||
<td>{{=FORM(INPUT(_type='submit',_name='pull',_value=T('Pull')))}}</td>
|
||||
</tr></table>
|
||||
</center>
|
||||
6
applications/admin/views/default/git_push.html
Normal file
6
applications/admin/views/default/git_push.html
Normal file
@@ -0,0 +1,6 @@
|
||||
{{extend 'layout.html'}}
|
||||
|
||||
<h2>{{=T('This will push changes to the remote repo for application "%s".', app)}}</h2>
|
||||
<center>
|
||||
{{=form}}
|
||||
</center>
|
||||
@@ -34,6 +34,10 @@
|
||||
{{=button(URL('remove_compiled_app',args=a), T("Remove compiled"))}}
|
||||
{{pass}}
|
||||
{{pass}}
|
||||
{{if os.path.exists(os.path.join(apath(r=request),a,'.git')): }}
|
||||
{{=button(URL('git_pull',args=a), T("Git Pull"))}}
|
||||
{{=button(URL('git_push',args=a), T("Git Push"))}}
|
||||
{{pass}}
|
||||
{{if a!=request.application:}}
|
||||
{{=button(URL('uninstall',args=a), T("Uninstall"))}}
|
||||
{{=button_enable(URL('enable',args=a), a)}}
|
||||
@@ -117,16 +121,18 @@
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
{{=LABEL(T("Get from URL:"), _for='upload_url')}}
|
||||
{{=LABEL(T("Get from URL:"), _for='upload_url')}}
|
||||
</td>
|
||||
<td>
|
||||
<input id="appurl" name="appurl" type="text" id="upload_url"/>
|
||||
<input id="appurl" name="appurl" type="text" id="upload_url"/><br/>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td></td>
|
||||
<td>
|
||||
<input type="checkbox" name="overwrite_check" id="upload_overwrite" />
|
||||
<td>
|
||||
({{=T('can be a git repo')}})
|
||||
</td>
|
||||
<td>
|
||||
<input type="checkbox" name="overwrite_check" id="upload_overwrite" />
|
||||
{{=LABEL(T("Overwrite installed app"), _for='upload_overwrite')}}
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
Reference in New Issue
Block a user