@ -1,14 +1,16 @@
import os
import os
import sys
import sys
import argparse
import argparse
from subprocess import Popen , PIPE
from subprocess import Popen , PIPE , STDOUT
from pipes import quote as shell_quote
from pipes import quote as shell_quote
from . . . import uis
from . . . plugins import PapersPlugin
from . . . plugins import PapersPlugin
from . . . events import PaperChangeEvent , PostCommandEvent
from . . . events import PaperChangeEvent , PostCommandEvent
GITIGNORE = """ # files or directories for the git plugin to ignore
GITIGNORE = """ # files or directories for the git plugin to ignore
. gitignore
. cache /
. cache /
"""
"""
@ -26,8 +28,9 @@ class GitPlugin(PapersPlugin):
def __init__ ( self , conf , ui ) :
def __init__ ( self , conf , ui ) :
self . ui = ui
self . ui = ui
self . pubsdir = conf [ ' main ' ] [ ' pubsdir ' ]
self . pubsdir = os . path . expanduser ( conf [ ' main ' ] [ ' pubsdir ' ] )
self . manual = conf [ ' plugins ' ] . get ( ' git ' , { } ) . get ( ' manual ' , False )
self . manual = conf [ ' plugins ' ] . get ( ' git ' , { } ) . get ( ' manual ' , False )
self . force_color = conf [ ' plugins ' ] . get ( ' git ' , { } ) . get ( ' force_color ' , True )
self . quiet = conf [ ' plugins ' ] . get ( ' git ' , { } ) . get ( ' quiet ' , True )
self . quiet = conf [ ' plugins ' ] . get ( ' git ' , { } ) . get ( ' quiet ' , True )
self . list_of_changes = [ ]
self . list_of_changes = [ ]
self . _gitinit ( )
self . _gitinit ( )
@ -35,13 +38,16 @@ class GitPlugin(PapersPlugin):
def _gitinit ( self ) :
def _gitinit ( self ) :
""" Initialize the git repository if necessary. """
""" Initialize the git repository if necessary. """
# check that a `.git` directory is present in the pubs dir
# check that a `.git` directory is present in the pubs dir
git_path = os . path . expanduser( os . path . join( self . pubsdir , ' .git ' ) )
git_path = os . path . join( self . pubsdir , ' .git ' )
if not os . path . isdir ( git_path ) :
if not os . path . isdir ( git_path ) :
self . shell ( ' init ' )
try :
self . shell ( ' init ' )
except RuntimeError as exc :
self . ui . error ( exc . args [ 0 ] )
sys . exit ( 1 )
# check that a `.gitignore` file is present
# check that a `.gitignore` file is present
gitignore_path = os . path . expanduser ( os . path . join ( self . pubsdir , ' .gitignore ' ) )
gitignore_path = os . path . join( self . pubsdir , ' .gitignore ' )
if not os . path . isfile ( gitignore_path ) :
if not os . path . isfile ( gitignore_path ) :
print ( ' bla ' )
with open ( gitignore_path , ' w ' ) as fd :
with open ( gitignore_path , ' w ' ) as fd :
fd . write ( GITIGNORE )
fd . write ( GITIGNORE )
@ -55,25 +61,30 @@ class GitPlugin(PapersPlugin):
def command ( self , conf , args ) :
def command ( self , conf , args ) :
""" Execute a git command in the pubs directory """
""" Execute a git command in the pubs directory """
self . shell ( ' ' . join ( [ shell_quote ( a ) for a in args . arguments ] ) )
self . shell ( ' ' . join ( [ shell_quote ( a ) for a in args . arguments ] ) , command = True )
def shell ( self , cmd , input_stdin = None ):
def shell ( self , cmd , input_stdin = None , command = False ):
""" Runs the git program in a shell
""" Runs the git program in a shell
: param cmd : the git command , and all arguments , as a single string ( e . g . ' add . ' )
: param cmd : the git command , and all arguments , as a single string ( e . g . ' add . ' )
: param input_stdin : if Python 3 , must be bytes ( i . e . , from str , s . encode ( ' utf-8 ' ) )
: param input_stdin : if Python 3 , must be bytes ( i . e . , from str , s . encode ( ' utf-8 ' ) )
: param command : if True , we ' re dealing with an explicit `pubs git` invocation.
"""
"""
git_cmd = ' git -C {} {} ' . format ( self . pubsdir , cmd )
colorize = ' -c color.ui=always ' if self . force_color else ' '
p = Popen ( git_cmd , stdin = PIPE , stdout = PIPE , stderr = PIPE , shell = True )
git_cmd = ' git -C {} {} {} ' . format ( self . pubsdir , colorize , cmd )
#print(git_cmd)
p = Popen ( git_cmd , stdin = PIPE , stdout = PIPE , stderr = STDOUT , shell = True )
output , err = p . communicate ( input_stdin )
output , err = p . communicate ( input_stdin )
p . wait ( )
p . wait ( )
if p . returncode != 0 :
if p . returncode != 0 :
msg = ( ' The git plugin encountered an error when running the git command: \n ' +
raise RuntimeError ( ' The git plugin encountered an error when running the git command: \n ' +
' {} \n {} \n ' . format ( git_cmd , err . decode ( ' utf-8 ' ) ) +
' {} \n \n Returned output: \n {} \n ' . format ( git_cmd , output . decode ( ' utf-8 ' ) ) +
' You may fix the state of the git repository {} manually. \n ' . format ( self . pubsdir ) +
' If needed, you may fix the state of the {} git repository ' . format ( self . pubsdir ) +
' If relevant, you may submit a bug report at ' +
' manually. \n If relevant, you may submit a bug report at ' +
' https://github.com/pubs/pubs/issues ' )
' https://github.com/pubs/pubs/issues ' )
self . ui . warning ( msg )
elif command :
self . ui . message ( output . decode ( ' utf-8 ' ) , end = ' ' )
elif not self . quiet :
elif not self . quiet :
self . ui . info ( output . decode ( ' utf-8 ' ) )
self . ui . info ( output . decode ( ' utf-8 ' ) )
return output , err , p . returncode
return output , err , p . returncode
@ -82,26 +93,25 @@ class GitPlugin(PapersPlugin):
@PaperChangeEvent.listen ( )
@PaperChangeEvent.listen ( )
def paper_change_event ( event ) :
def paper_change_event ( event ) :
""" When a paper is changed, commit the changes to the directory. """
""" When a paper is changed, commit the changes to the directory. """
try :
if GitPlugin . is_loaded ( ) :
git = GitPlugin . get_instance ( )
git = GitPlugin . get_instance ( )
if not git . manual :
if not git . manual :
event_desc = event . description
event_desc = event . description
for a , b in [ ( ' \\ ' , ' \\ \\ ' ) , ( ' " ' , ' \\ " ' ) , ( ' $ ' , ' \\ $ ' ) , ( ' ` ' , ' \\ ` ' ) ] :
for a , b in [ ( ' \\ ' , ' \\ \\ ' ) , ( ' " ' , ' \\ " ' ) , ( ' $ ' , ' \\ $ ' ) , ( ' ` ' , ' \\ ` ' ) ] :
event_desc = event_desc . replace ( a , b )
event_desc = event_desc . replace ( a , b )
git . list_of_changes . append ( event_desc )
git . list_of_changes . append ( event_desc )
except RuntimeError :
pass
@PostCommandEvent.listen ( )
@PostCommandEvent.listen ( )
def git_commit ( event ) :
def git_commit ( event ) :
try :
if GitPlugin . is_loaded ( ) :
git = GitPlugin . get_instance ( )
try :
if len ( git . list_of_changes ) > 0 :
git = GitPlugin . get_instance ( )
if not git . manual :
if len ( git . list_of_changes ) > 0 :
title = ' ' . join ( sys . argv ) + ' \n '
if not git . manual :
message = ' \n ' . join ( [ title ] + git . list_of_changes )
title = ' ' . join ( sys . argv ) + ' \n '
message = ' \n ' . join ( [ title ] + git . list_of_changes )
git . shell ( ' add . ' )
git . shell ( ' commit -F- ' , message . encode ( ' utf-8 ' ) )
git . shell ( ' add . ' )
except RuntimeError :
git . shell ( ' commit -F- ' , message . encode ( ' utf-8 ' ) )
pass
except RuntimeError as exc :
uis . get_ui ( ) . warning ( exc . args [ 0 ] )