experimental git support (needs a little more work), thanks Andrew Replogle
This commit is contained in:
@@ -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
|
from glob import glob
|
||||||
import shutil
|
import shutil
|
||||||
import platform
|
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,
|
from gluon.languages import (regex_language, read_possible_languages,
|
||||||
read_possible_plurals, lang_sampling,
|
read_possible_plurals, lang_sampling,
|
||||||
read_dict, write_dict, read_plural_dict,
|
read_dict, write_dict, read_plural_dict,
|
||||||
write_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')
|
session.flash = T('disabled in demo mode')
|
||||||
redirect(URL('site'))
|
redirect(URL('site'))
|
||||||
|
|
||||||
|
|
||||||
if not is_manager() and request.function in ['change_password','upgrade_web2py']:
|
if not is_manager() and request.function in ['change_password','upgrade_web2py']:
|
||||||
session.flash = T('disabled in multi user mode')
|
session.flash = T('disabled in multi user mode')
|
||||||
redirect(URL('site'))
|
redirect(URL('site'))
|
||||||
@@ -188,6 +197,23 @@ def site():
|
|||||||
msg = 'you must specify a name for the uploaded application'
|
msg = 'you must specify a name for the uploaded application'
|
||||||
response.flash = T(msg)
|
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:
|
elif file_or_appurl and request.vars.filename:
|
||||||
# fetch an application via URL or file upload
|
# fetch an application via URL or file upload
|
||||||
f = None
|
f = None
|
||||||
@@ -1558,3 +1584,76 @@ def bulk_register():
|
|||||||
redirect(URL('site'))
|
redirect(URL('site'))
|
||||||
return locals()
|
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)
|
||||||
|
|
||||||
|
|||||||
@@ -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>
|
||||||
@@ -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"))}}
|
{{=button(URL('remove_compiled_app',args=a), T("Remove compiled"))}}
|
||||||
{{pass}}
|
{{pass}}
|
||||||
{{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:}}
|
{{if a!=request.application:}}
|
||||||
{{=button(URL('uninstall',args=a), T("Uninstall"))}}
|
{{=button(URL('uninstall',args=a), T("Uninstall"))}}
|
||||||
{{=button_enable(URL('enable',args=a), a)}}
|
{{=button_enable(URL('enable',args=a), a)}}
|
||||||
@@ -117,16 +121,18 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
{{=LABEL(T("Get from URL:"), _for='upload_url')}}
|
{{=LABEL(T("Get from URL:"), _for='upload_url')}}
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<input id="appurl" name="appurl" type="text" id="upload_url"/>
|
<input id="appurl" name="appurl" type="text" id="upload_url"/><br/>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td></td>
|
<td>
|
||||||
<td>
|
({{=T('can be a git repo')}})
|
||||||
<input type="checkbox" name="overwrite_check" id="upload_overwrite" />
|
</td>
|
||||||
|
<td>
|
||||||
|
<input type="checkbox" name="overwrite_check" id="upload_overwrite" />
|
||||||
{{=LABEL(T("Overwrite installed app"), _for='upload_overwrite')}}
|
{{=LABEL(T("Overwrite installed app"), _for='upload_overwrite')}}
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
Reference in New Issue
Block a user