~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/osutils.py

  • Committer: Martin Pool
  • Date: 2005-06-24 04:48:14 UTC
  • Revision ID: mbp@sourcefrog.net-20050624044814-1db5090ffeaa95d9
- Patch from Torsten Marek to take commit messages through an 
  editor.

Show diffs side-by-side

added added

removed removed

Lines of Context:
384
384
        if not ignore_errors:
385
385
            raise BzrError('command failed')
386
386
 
 
387
 
 
388
def _read_config_value(name):
 
389
    """Read a config value from the file ~/.bzr.conf/<name>
 
390
    Return None if the file does not exist"""
 
391
    try:
 
392
        f = file(os.path.join(config_dir(), name), "r")
 
393
        return f.read().decode(bzrlib.user_encoding).rstrip("\r\n")
 
394
    except IOError, e:
 
395
        if e.errno == errno.ENOENT:
 
396
            return None
 
397
        raise
 
398
 
 
399
 
 
400
def _get_editor():
 
401
    """Return a sequence of possible editor binaries for the current platform"""
 
402
    e = _read_config_value("editor")
 
403
    if e is not None:
 
404
        yield e
 
405
        
 
406
    if os.name == "windows":
 
407
        yield "notepad.exe"
 
408
    elif os.name == "posix":
 
409
        try:
 
410
            yield os.environ["EDITOR"]
 
411
        except KeyError:
 
412
            yield "/usr/bin/vi"
 
413
 
 
414
 
 
415
def _run_editor(filename):
 
416
    """Try to execute an editor to edit the commit message. Returns True on success,
 
417
    False on failure"""
 
418
    for e in _get_editor():
 
419
        x = os.spawnvp(os.P_WAIT, e, (e, filename))
 
420
        if x == 0:
 
421
            return True
 
422
        elif x == 127:
 
423
            continue
 
424
        else:
 
425
            break
 
426
    raise BzrError("Could not start any editor. Please specify $EDITOR or use ~/.bzr.conf/editor")
 
427
    return False
 
428
                          
 
429
 
 
430
def get_text_message(infotext, ignoreline = "default"):
 
431
    import tempfile
 
432
    
 
433
    if ignoreline == "default":
 
434
        ignoreline = "-- This line and the following will be ignored --"
 
435
        
 
436
    try:
 
437
        tmp_fileno, msgfilename = tempfile.mkstemp()
 
438
        msgfile = os.close(tmp_fileno)
 
439
        if infotext is not None and infotext != "":
 
440
            hasinfo = True
 
441
            msgfile = file(msgfilename, "w")
 
442
            msgfile.write("\n\n%s\n\n%s" % (ignoreline, infotext))
 
443
            msgfile.close()
 
444
        else:
 
445
            hasinfo = False
 
446
 
 
447
        if not _run_editor(msgfilename):
 
448
            return None
 
449
        
 
450
        started = False
 
451
        msg = []
 
452
        lastline, nlines = 0, 0
 
453
        for line in file(msgfilename, "r"):
 
454
            stripped_line = line.strip()
 
455
            # strip empty line before the log message starts
 
456
            if not started:
 
457
                if stripped_line != "":
 
458
                    started = True
 
459
                else:
 
460
                    continue
 
461
            # check for the ignore line only if there
 
462
            # is additional information at the end
 
463
            if hasinfo and stripped_line == ignoreline:
 
464
                break
 
465
            nlines += 1
 
466
            # keep track of the last line that had some content
 
467
            if stripped_line != "":
 
468
                lastline = nlines
 
469
            msg.append(line)
 
470
            
 
471
        if len(msg) == 0:
 
472
            return None
 
473
        # delete empty lines at the end
 
474
        del msg[lastline:]
 
475
        # add a newline at the end, if needed
 
476
        if not msg[-1].endswith("\n"):
 
477
            return "%s%s" % ("".join(msg), "\n")
 
478
        else:
 
479
            return "".join(msg)
 
480
    finally:
 
481
        # delete the msg file in any case
 
482
        try: os.unlink(msgfilename)
 
483
        except IOError: pass