mirror of
https://github.com/openSUSE/osc.git
synced 2025-02-04 02:26:16 +01:00
More options in commit filelist change
osc commit check for '?' files can be supressed by -f/--force option It also have more options. File can be easily added, removed or the whole filelist should be opened in editor and edited (this is very close to git rebase --interactive behavior).
This commit is contained in:
parent
365be249c3
commit
724f577b41
2
NEWS
2
NEWS
@ -5,7 +5,7 @@
|
|||||||
- fix and improve request list and show output
|
- fix and improve request list and show output
|
||||||
- new osc rremove command for remote source files removal
|
- new osc rremove command for remote source files removal
|
||||||
- handle _service\* files correctly
|
- handle _service\* files correctly
|
||||||
- osc commit asks if some file has a '?' status
|
- osc commit asks if some file has a '?' status (can be skipped by --force option)
|
||||||
|
|
||||||
0.120:
|
0.120:
|
||||||
- support "setlinkrev" for whole projects
|
- support "setlinkrev" for whole projects
|
||||||
|
@ -1619,12 +1619,22 @@ Please submit there instead, or use --nodevelproject to force direct submission.
|
|||||||
help='specify log message TEXT')
|
help='specify log message TEXT')
|
||||||
@cmdln.option('-F', '--file', metavar='FILE',
|
@cmdln.option('-F', '--file', metavar='FILE',
|
||||||
help='read log message from FILE')
|
help='read log message from FILE')
|
||||||
|
@cmdln.option('-f', '--force', default=False, action="store_true",
|
||||||
|
help='force commit - do not tests a file list')
|
||||||
def do_commit(self, subcmd, opts, *args):
|
def do_commit(self, subcmd, opts, *args):
|
||||||
"""${cmd_name}: Upload content to the repository server
|
"""${cmd_name}: Upload content to the repository server
|
||||||
|
|
||||||
Upload content which is changed in your working copy, to the repository
|
Upload content which is changed in your working copy, to the repository
|
||||||
server.
|
server.
|
||||||
|
|
||||||
|
Checks the state of a working copy, if found a file with unknown state,
|
||||||
|
it requests an user input:
|
||||||
|
* skip - don't change anything, just move to another file
|
||||||
|
* remove - remove a file from dir
|
||||||
|
* edit file list - edit filelist using EDITOR
|
||||||
|
* commit - don't check anything and commit package
|
||||||
|
* abort - abort commit - this is default value
|
||||||
|
|
||||||
examples:
|
examples:
|
||||||
osc ci # current dir
|
osc ci # current dir
|
||||||
osc ci <dir>
|
osc ci <dir>
|
||||||
@ -1653,17 +1663,8 @@ Please submit there instead, or use --nodevelproject to force direct submission.
|
|||||||
|
|
||||||
pacs = findpacs(args)
|
pacs = findpacs(args)
|
||||||
|
|
||||||
# warn if any of files has a ? status (usually a patch, or new source was not added to meta)
|
if not opts.force:
|
||||||
for p in pacs:
|
check_filelist_before_commit(pacs)
|
||||||
# no files given as argument? Take all files in current dir
|
|
||||||
if not p.todo:
|
|
||||||
p.todo = p.filenamelist + p.filenamelist_unvers
|
|
||||||
p.todo.sort()
|
|
||||||
for f in (f for f in p.todo if os.path.isfile(f)):
|
|
||||||
if p.status(f) == '?':
|
|
||||||
resp = raw_input("File `%s' is not in package meta. Would you like to continue? [y/N] "% (f, ))
|
|
||||||
if resp not in ('y', 'Y'):
|
|
||||||
return
|
|
||||||
|
|
||||||
if not msg:
|
if not msg:
|
||||||
# open editor for commit message
|
# open editor for commit message
|
||||||
|
122
osc/core.py
122
osc/core.py
@ -1241,7 +1241,101 @@ rev: %s
|
|||||||
|
|
||||||
#print ljust(p.name, 45), 'At revision %s.' % p.rev
|
#print ljust(p.name, 45), 'At revision %s.' % p.rev
|
||||||
print 'At revision %s.' % self.rev
|
print 'At revision %s.' % self.rev
|
||||||
|
|
||||||
|
def prepare_filelist(self):
|
||||||
|
"""Prepare a list of files, which will be processed by process_filelist
|
||||||
|
method. This allows easy modifications of a file list in commit
|
||||||
|
phase.
|
||||||
|
"""
|
||||||
|
if not self.todo:
|
||||||
|
self.todo = self.filenamelist + self.filenamelist_unvers
|
||||||
|
self.todo.sort()
|
||||||
|
|
||||||
|
ret = ""
|
||||||
|
for f in (f for f in self.todo if os.path.isfile(f)):
|
||||||
|
ret += "leave %s %s\n" % (self.status(f), f)
|
||||||
|
|
||||||
|
ret += """
|
||||||
|
# Edit a filelist for package %s
|
||||||
|
# Commands:
|
||||||
|
# l, leave = leave a file as is
|
||||||
|
# r, remove = remove a file
|
||||||
|
# a, add = add a file
|
||||||
|
#
|
||||||
|
# If you remove file from a list, it will be unchanged
|
||||||
|
# If you remove all, commit will be aborted"""
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def edit_filelist(self):
|
||||||
|
"""Opens a package list in editor for eediting. This allows easy
|
||||||
|
modifications of it just by simple text editing
|
||||||
|
"""
|
||||||
|
|
||||||
|
import tempfile
|
||||||
|
tempdir = '/tmp'
|
||||||
|
if sys.platform[:3] == 'win':
|
||||||
|
tempdir = os.getenv('TEMP')
|
||||||
|
|
||||||
|
(fd, filename) = tempfile.mkstemp(prefix = 'osc-filelist', suffix = '.txt', dir = tempdir)
|
||||||
|
f = os.fdopen(fd, 'w')
|
||||||
|
f.write(self.prepare_filelist())
|
||||||
|
f.close()
|
||||||
|
mtime_orig = os.stat(filename).st_mtime
|
||||||
|
|
||||||
|
if sys.platform[:3] != 'win':
|
||||||
|
editor = os.getenv('EDITOR', default='vim')
|
||||||
|
else:
|
||||||
|
editor = os.getenv('EDITOR', default='notepad')
|
||||||
|
while 1:
|
||||||
|
subprocess.call('%s %s' % (editor, filename), shell=True)
|
||||||
|
mtime = os.stat(filename).st_mtime
|
||||||
|
if mtime_orig < mtime:
|
||||||
|
filelist = open(filename).readlines()
|
||||||
|
os.unlink(filename)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
raise oscerr.UserAbort()
|
||||||
|
|
||||||
|
return self.process_filelist(filelist)
|
||||||
|
|
||||||
|
def process_filelist(self, filelist):
|
||||||
|
"""Process a filelist - it add/remove or leave files. This depends on
|
||||||
|
user input. If no file is processed, it raises an ValueError
|
||||||
|
"""
|
||||||
|
|
||||||
|
loop = False
|
||||||
|
for line in (l.strip() for l in filelist if (l[0] != "#" or l.strip() != '')):
|
||||||
|
|
||||||
|
foo = line.split(' ')
|
||||||
|
if len(foo) == 4:
|
||||||
|
action, state, name = (foo[0], ' ', foo[3])
|
||||||
|
elif len(foo) == 3:
|
||||||
|
action, state, name = (foo[0], foo[1], foo[2])
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
action = action.lower()
|
||||||
|
loop = True
|
||||||
|
|
||||||
|
if action in ('r', 'remove'):
|
||||||
|
if self.status(name) == '?':
|
||||||
|
os.unlink(name)
|
||||||
|
if name in self.todo:
|
||||||
|
self.todo.remove(name)
|
||||||
|
else:
|
||||||
|
self.delete_file(name, True)
|
||||||
|
elif action in ('a', 'add'):
|
||||||
|
if self.status(name) != '?':
|
||||||
|
print "Cannot add file %s with state %s, skipped" % (name, self.status(name))
|
||||||
|
else:
|
||||||
|
self.addfile(name)
|
||||||
|
elif action in ('l', 'leave'):
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
raise ValueError("Unknow action `%s'" % action)
|
||||||
|
|
||||||
|
if not loop:
|
||||||
|
raise ValueError("Empty filelist")
|
||||||
|
|
||||||
class RequestState:
|
class RequestState:
|
||||||
"""for objects to represent the "state" of a request"""
|
"""for objects to represent the "state" of a request"""
|
||||||
@ -4004,3 +4098,29 @@ def get_commit_message_template(pac):
|
|||||||
template.append(line[1:])
|
template.append(line[1:])
|
||||||
|
|
||||||
return template
|
return template
|
||||||
|
|
||||||
|
def check_filelist_before_commit(pacs):
|
||||||
|
|
||||||
|
# warn if any of files has a ? status (usually a patch, or new source was not added to meta)
|
||||||
|
for p in pacs:
|
||||||
|
# no files given as argument? Take all files in current dir
|
||||||
|
if not p.todo:
|
||||||
|
p.todo = p.filenamelist + p.filenamelist_unvers
|
||||||
|
p.todo.sort()
|
||||||
|
for f in (f for f in p.todo if os.path.isfile(f)):
|
||||||
|
if p.status(f) == '?':
|
||||||
|
resp = raw_input("File `%s' is not in package meta. Would you like skip/remove/edit file lists/commit/abort? (s/r/e/c/A) "% (f, ))
|
||||||
|
if resp in ('s', 'S'):
|
||||||
|
continue
|
||||||
|
elif resp in ('r', 'R'):
|
||||||
|
p.process_filelist(['r ? %s' % (f, ), ])
|
||||||
|
elif resp in ('e', 'E'):
|
||||||
|
try:
|
||||||
|
p.edit_filelist()
|
||||||
|
except ValueError:
|
||||||
|
print >>sys.stderr, "Error during processiong of file list."
|
||||||
|
raise oscerr.UserAbort()
|
||||||
|
elif resp in ('c', 'C'):
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
raise oscerr.UserAbort()
|
||||||
|
Loading…
Reference in New Issue
Block a user