From 3c64b5788c3e6b10528a81285b71da2edbed8950 Mon Sep 17 00:00:00 2001 From: Rob Browning Date: Sat, 12 Oct 2019 17:46:38 -0500 Subject: [PATCH] Simplify bup startup process Now that we've moved bup to cmd/, we adjust bup-python at install time, and we can rely on that to find the module and cmd dirs, simplify the startup process. Let bup-python handle all the PYTHONPATH settings, etc., and drop BUP_MAIN_EXE, relying instead on a path.exe() that finds the binary via path.__file__. Signed-off-by: Rob Browning Tested-by: Rob Browning --- Makefile | 10 ++++++++++ cmd/bup | 35 ++++++---------------------------- cmd/help-cmd.py | 2 +- cmd/import-rdiff-backup-cmd.sh | 4 +++- cmd/import-rsnapshot-cmd.sh | 4 +++- cmd/python-cmd.sh | 16 ++++++++++++++++ lib/bup/path.py | 25 ++++++++++++++---------- lib/bup/t/tclient.py | 11 ++--------- lib/bup/t/tgit.py | 11 ++--------- lib/bup/t/tresolve.py | 8 ++------ lib/cmd | 1 + 11 files changed, 61 insertions(+), 66 deletions(-) create mode 120000 lib/cmd diff --git a/Makefile b/Makefile index d285f3a..e5e2b67 100644 --- a/Makefile +++ b/Makefile @@ -57,6 +57,15 @@ all: $(bup_deps) Documentation/all $(current_sampledata) $(current_sampledata): t/configure-sampledata --setup + +bup_libdir="$script_home/../lib" # bup_libdir will be adjusted during install + +define install-bup-python + set -e; \ + sed -e 's|.*# bup_libdir will be adjusted during install|bup_libdir="$$script_home/.."|' $1 > $2; \ + chmod 0755 $2; +endef + PANDOC ?= $(shell type -p pandoc) ifeq (,$(PANDOC)) @@ -91,6 +100,7 @@ install: all test -z "$(man_html)" || $(INSTALL) -m 0644 $(man_html) $(dest_docdir) $(INSTALL) -pm 0755 cmd/bup $(dest_libdir)/cmd/ $(INSTALL) -pm 0755 cmd/bup-* $(dest_libdir)/cmd/ + $(call install-bup-python,cmd/bup-python,"$(dest_libdir)/cmd/bup-python") cd "$(dest_bindir)" && \ ln -sf "$$($(bup_python) -c 'import os; print(os.path.relpath("$(abspath $(dest_libdir))/cmd/bup"))')" set -e; \ diff --git a/cmd/bup b/cmd/bup index e442541..4b5097d 100755 --- a/cmd/bup +++ b/cmd/bup @@ -28,31 +28,11 @@ from subprocess import PIPE from sys import stderr, stdout import select -argv = sys.argv -exe = os.path.realpath(argv[0]) -exepath = os.path.split(exe)[0] or '.' - -# fix the PYTHONPATH to include our lib dir -if os.path.exists("%s/../bup/." % exepath): - # Everything is relative to exepath (i.e. LIBDIR/cmd/) - cmdpath = exepath - libpath = os.path.join(exepath, '..') - resourcepath = libpath -else: - # running from the src directory without being installed first - cmdpath = exepath - libpath = os.path.join(exepath, '../lib') - resourcepath = libpath -sys.path[:0] = [libpath] -os.environ['PYTHONPATH'] = libpath + ':' + os.environ.get('PYTHONPATH', '') -os.environ['BUP_MAIN_EXE'] = os.path.abspath(exe) -os.environ['BUP_RESOURCE_PATH'] = resourcepath - - -from bup import compat, helpers +from bup import compat, path, helpers from bup.compat import add_ex_tb, add_ex_ctx, wrap_main from bup.helpers import atoi, columnate, debug1, log, merge_dict, tty_width +cmdpath = path.cmddir() def usage(msg=""): log('Usage: bup [-?|--help] [-d BUP_DIR] [--debug] [--profile] ' @@ -77,7 +57,7 @@ def usage(msg=""): log('Other available commands:\n') cmds = [] - for c in sorted(os.listdir(cmdpath) + os.listdir(exepath)): + for c in sorted(os.listdir(cmdpath)): if c.startswith('bup-') and c.find('.') < 0: cname = c[4:] if cname not in common: @@ -92,13 +72,13 @@ def usage(msg=""): sys.exit(99) -if len(argv) < 2: +if len(sys.argv) < 2: usage() # Handle global options. try: optspec = ['help', 'version', 'debug', 'profile', 'bup-dir='] - global_args, subcmd = getopt.getopt(argv[1:], '?VDd:', optspec) + global_args, subcmd = getopt.getopt(sys.argv[1:], '?VDd:', optspec) except getopt.GetoptError as ex: usage('error: %s' % ex.msg) @@ -141,10 +121,7 @@ if not subcmd_name: usage() def subpath(s): - sp = os.path.join(exepath, 'bup-%s' % s) - if not os.path.exists(sp): - sp = os.path.join(cmdpath, 'bup-%s' % s) - return sp + return os.path.join(cmdpath, 'bup-%s' % s) subcmd[0] = subpath(subcmd_name) if not os.path.exists(subcmd[0]): diff --git a/cmd/help-cmd.py b/cmd/help-cmd.py index 384d0cf..4ad5f74 100755 --- a/cmd/help-cmd.py +++ b/cmd/help-cmd.py @@ -17,7 +17,7 @@ o = options.Options(optspec) if len(extra) == 0: # the wrapper program provides the default usage string - os.execvp(os.environ['BUP_MAIN_EXE'], ['bup']) + os.execvp(path.exe(), ['bup']) elif len(extra) == 1: docname = (extra[0]=='bup' and 'bup' or ('bup-%s' % extra[0])) manpath = os.path.join(path.exedir(), diff --git a/cmd/import-rdiff-backup-cmd.sh b/cmd/import-rdiff-backup-cmd.sh index 466b6a6..bd32402 100755 --- a/cmd/import-rdiff-backup-cmd.sh +++ b/cmd/import-rdiff-backup-cmd.sh @@ -1,5 +1,7 @@ #!/usr/bin/env bash +cmd_dir="$(cd "$(dirname "$0")" && pwd)" || exit $? + set -o pipefail must() { @@ -35,7 +37,7 @@ done bup() { - $dry_run "${BUP_MAIN_EXE:=bup}" "$@" + $dry_run "$cmd_dir/bup" "$@" } snapshot_root="$1" diff --git a/cmd/import-rsnapshot-cmd.sh b/cmd/import-rsnapshot-cmd.sh index 6ab3984..91f711e 100755 --- a/cmd/import-rsnapshot-cmd.sh +++ b/cmd/import-rsnapshot-cmd.sh @@ -1,6 +1,8 @@ #!/bin/sh # Does an import of a rsnapshot archive. +cmd_dir="$(cd "$(dirname "$0")" && pwd)" || exit $? + usage() { echo "Usage: bup import-rsnapshot [-n]" \ " []" @@ -16,7 +18,7 @@ done bup() { - $DRY_RUN "${BUP_MAIN_EXE:=bup}" "$@" + $DRY_RUN "$cmd_dir/bup" "$@" } SNAPSHOT_ROOT=$1 diff --git a/cmd/python-cmd.sh b/cmd/python-cmd.sh index 6de5867..cce1b8b 100644 --- a/cmd/python-cmd.sh +++ b/cmd/python-cmd.sh @@ -2,4 +2,20 @@ set -e +top="$(pwd)" +cmdpath="$0" +# loop because macos has no recursive resolution +while test -L "$cmdpath"; do + link="$(readlink "$cmdpath")" + cd "$(dirname "$cmdpath")" + cmdpath="$link" +done +script_home="$(cd "$(dirname "$cmdpath")" && pwd -P)" +cd "$top" + +bup_libdir="$script_home/../lib" # bup_libdir will be adjusted during install + +export PYTHONPATH="$bup_libdir${PYTHONPATH:+:$PYTHONPATH}" +export BUP_RESOURCE_PATH="$bup_libdir" + # This last line will be replaced with 'exec some/python "$@" diff --git a/lib/bup/path.py b/lib/bup/path.py index 9b9445e..7a4f31c 100644 --- a/lib/bup/path.py +++ b/lib/bup/path.py @@ -1,18 +1,23 @@ -"""This is a separate module so we can cleanly getcwd() before anyone - does chdir(). -""" from __future__ import absolute_import -import sys, os +import os + + +# Eventually, if we physically move the source tree cmd/ to lib/, then +# we could use realpath here and save some stats... + +_libdir = os.path.abspath(os.path.dirname(__file__) + '/..') +_exedir = os.path.abspath(_libdir + '/cmd') +_exe = os.path.join(_exedir, 'bup') -startdir = os.getcwd() def exe(): - return (os.environ.get('BUP_MAIN_EXE') or - os.path.join(startdir, sys.argv[0])) + return _exe def exedir(): - return os.path.split(exe())[0] + return _exedir + +cmddir = exedir -def exefile(): - return os.path.split(exe())[1] +def libdir(): + return _libdir diff --git a/lib/bup/t/tclient.py b/lib/bup/t/tclient.py index 2ea4dca..284effc 100644 --- a/lib/bup/t/tclient.py +++ b/lib/bup/t/tclient.py @@ -4,7 +4,7 @@ import sys, os, stat, time, random, subprocess, glob from wvtest import * -from bup import client, git +from bup import client, git, path from bup.helpers import mkdirp from buptest import no_lingering_errors, test_tempdir @@ -16,9 +16,6 @@ def randbytes(sz): return s -top_dir = os.path.realpath('../../..') -bup_exe = top_dir + '/cmd/bup' - s1 = randbytes(10000) s2 = randbytes(10000) s3 = randbytes(10000) @@ -30,7 +27,6 @@ IDX_PAT = '/*.idx' def test_server_split_with_indexes(): with no_lingering_errors(): with test_tempdir('bup-tclient-') as tmpdir: - os.environ['BUP_MAIN_EXE'] = bup_exe os.environ['BUP_DIR'] = bupdir = tmpdir git.init_repo(bupdir) lw = git.PackWriter() @@ -50,7 +46,6 @@ def test_server_split_with_indexes(): def test_multiple_suggestions(): with no_lingering_errors(): with test_tempdir('bup-tclient-') as tmpdir: - os.environ['BUP_MAIN_EXE'] = bup_exe os.environ['BUP_DIR'] = bupdir = tmpdir git.init_repo(bupdir) @@ -86,7 +81,6 @@ def test_multiple_suggestions(): def test_dumb_client_server(): with no_lingering_errors(): with test_tempdir('bup-tclient-') as tmpdir: - os.environ['BUP_MAIN_EXE'] = bup_exe os.environ['BUP_DIR'] = bupdir = tmpdir git.init_repo(bupdir) open(git.repo('bup-dumb-server'), 'w').close() @@ -109,7 +103,6 @@ def test_dumb_client_server(): def test_midx_refreshing(): with no_lingering_errors(): with test_tempdir('bup-tclient-') as tmpdir: - os.environ['BUP_MAIN_EXE'] = bupmain = '../../../bup' os.environ['BUP_DIR'] = bupdir = tmpdir git.init_repo(bupdir) c = client.Client(bupdir, create=True) @@ -136,7 +129,7 @@ def test_midx_refreshing(): WVFAIL(p2.exists(s1sha)) WVPASS(p2.exists(s2sha)) - subprocess.call([bupmain, 'midx', '-f']) + subprocess.call([path.exe(), 'midx', '-f']) pi.refresh() WVPASSEQ(len(pi.packs), 1) pi.refresh(skip_midx=True) diff --git a/lib/bup/t/tgit.py b/lib/bup/t/tgit.py index 2cf8230..4227e78 100644 --- a/lib/bup/t/tgit.py +++ b/lib/bup/t/tgit.py @@ -5,14 +5,13 @@ import struct, os, time from wvtest import * -from bup import git +from bup import git, path from bup.compat import range from bup.helpers import localtime, log, mkdirp, readpipe from buptest import no_lingering_errors, test_tempdir -top_dir = os.path.realpath('../../..') -bup_exe = top_dir + '/cmd/bup' +bup_exe = path.exe() def exc(*cmd): @@ -87,7 +86,6 @@ def testencode(): def testpacks(): with no_lingering_errors(): with test_tempdir('bup-tgit-') as tmpdir: - os.environ['BUP_MAIN_EXE'] = bup_exe os.environ['BUP_DIR'] = bupdir = tmpdir + "/bup" git.init_repo(bupdir) git.verbose = 1 @@ -132,7 +130,6 @@ def testpacks(): def test_pack_name_lookup(): with no_lingering_errors(): with test_tempdir('bup-tgit-') as tmpdir: - os.environ['BUP_MAIN_EXE'] = bup_exe os.environ['BUP_DIR'] = bupdir = tmpdir + "/bup" git.init_repo(bupdir) git.verbose = 1 @@ -159,7 +156,6 @@ def test_pack_name_lookup(): def test_long_index(): with no_lingering_errors(): with test_tempdir('bup-tgit-') as tmpdir: - os.environ['BUP_MAIN_EXE'] = bup_exe os.environ['BUP_DIR'] = bupdir = tmpdir + "/bup" git.init_repo(bupdir) w = git.PackWriter() @@ -300,7 +296,6 @@ def test_commit_parsing(): def test_new_commit(): with no_lingering_errors(): with test_tempdir('bup-tgit-') as tmpdir: - os.environ['BUP_MAIN_EXE'] = bup_exe os.environ['BUP_DIR'] = bupdir = tmpdir + "/bup" git.init_repo(bupdir) git.verbose = 1 @@ -364,7 +359,6 @@ def test_new_commit(): def test_list_refs(): with no_lingering_errors(): with test_tempdir('bup-tgit-') as tmpdir: - os.environ['BUP_MAIN_EXE'] = bup_exe os.environ['BUP_DIR'] = bupdir = tmpdir + "/bup" src = tmpdir + '/src' mkdirp(src) @@ -423,7 +417,6 @@ def test__git_date_str(): def test_cat_pipe(): with no_lingering_errors(): with test_tempdir('bup-tgit-') as tmpdir: - os.environ['BUP_MAIN_EXE'] = bup_exe os.environ['BUP_DIR'] = bupdir = tmpdir + "/bup" src = tmpdir + '/src' mkdirp(src) diff --git a/lib/bup/t/tresolve.py b/lib/bup/t/tresolve.py index 646d78a..b66bee3 100644 --- a/lib/bup/t/tresolve.py +++ b/lib/bup/t/tresolve.py @@ -8,16 +8,13 @@ from time import localtime, strftime from wvtest import * -from bup import git, vfs +from bup import git, path, vfs from bup.metadata import Metadata from bup.repo import LocalRepo, RemoteRepo from bup.test.vfs import tree_dict from buptest import ex, exo, no_lingering_errors, test_tempdir -top_dir = '../../..' -bup_tmp = os.path.realpath('../../../t/tmp') -bup_path = top_dir + '/bup' -start_dir = os.getcwd() +bup_path = path.exe() ## The clear_cache() calls below are to make sure that the test starts ## from a known state since at the moment the cache entry for a given @@ -31,7 +28,6 @@ def prep_and_test_repo(name, create_repo, test_repo): bup_dir = tmpdir + '/bup' environ['GIT_DIR'] = bup_dir environ['BUP_DIR'] = bup_dir - environ['BUP_MAIN_EXE'] = bup_path ex((bup_path, 'init')) git.repodir = bup_dir with create_repo(bup_dir) as repo: diff --git a/lib/cmd b/lib/cmd new file mode 120000 index 0000000..9287aae --- /dev/null +++ b/lib/cmd @@ -0,0 +1 @@ +../cmd \ No newline at end of file -- 2.39.2