Newer
Older
# coding: utf-8
# archversion - Archlinux Version Controller
# Copyright © 2012 Sébastien Luttringer
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
'''Archlinux Version Controller'''
from archversion import VERSION, DEFAULT_CONFIG_FILENAME, DEFAULT_CACHE_FILENAME
from archversion.config import BaseConfigFile
from archversion.database import JsonDatabase
from archversion.error import BaseError, MissingConfigFile, NoSuchFile
from archversion.error import ERR_FATAL, ERR_ABORT, ERR_UNKNOWN
from archversion.pacman import parse_pkgbuild, pkgbuild_set_version, pkgbuild_update_checksums
from archversion.version import VersionController
def parse_argv():
'''Parse command line arguments'''
p_main = argparse.ArgumentParser()
p_main.add_argument("--version", action="version",
version="%(prog)s version %s" + VERSION)
p_main.add_argument("--debug", action="store_true",
help="debug mode")
p_main.add_argument("-c", "--config", default=None,
help="config file path")
p_main.add_argument("-C", "--cache", default=None,
help="cache file path")
sp_main = p_main.add_subparsers()
# config parser
p_conf = sp_main.add_parser("config", aliases=["co", "conf"],
help="list configured packages")
p_conf.add_argument("-s", "--sort", action="store_true",
help="sort listing")
p_conf.set_defaults(func=command_config)
# cache parser
p_cache = sp_main.add_parser("cache", aliases=["ca"],
help="list cached verions")
p_cache.add_argument("-s", "--sort", action="store_true",
help="sort listing")
p_cache.set_defaults(func=command_cache)
# modes parser
p_modes = sp_main.add_parser("modes", aliases=["mo"],
help="list check against modes")
p_modes.set_defaults(func=command_modes)
p_check = sp_main.add_parser("check", aliases=["ck", "ch"],
p_check.add_argument("-c", "--diff-cache", action="store_true",
help="doesn't display cached versions")
p_check.add_argument("-n", "--diff-new", action="store_true",
help="only display new versions")
p_check.add_argument("-s", "--sort", action="store_true",
help="sort packages by name")
p_check.add_argument("-S", "--no-save", dest="save", action="store_false",
help="don't save version updates in cache")
p_check.add_argument("packages", nargs='*',
help="only check this packages")
p_check.set_defaults(func=command_check)
help="update a PKGBUILD with the latest version")
p_update.add_argument("-p", "--path", default="PKGBUILD",
help="name of the file to update. Default PKGBUILD")
p_update.add_argument("-c", "--checksum", action="store_true",
help="run updpkgsums after update")
p_update.add_argument("-S", "--no-save", dest="save", action="store_false",
help="don't save version updates in cache")
namespace = p_main.parse_args()
# Ensure subparser was choosen
if "func" not in namespace:
p_main.error("missing argument")
return namespace
def command_config(args, vctrl):
'''list configured packages'''
if args.sort:
vctrl.sort_packages()
vctrl.print_names()
def command_cache(args, vctrl):
'''list cached versions'''
if args.sort:
vctrl.sort_cache()
vctrl.print_cache()
def command_modes(args, vctrl):
'''list checking against modes'''
vctrl.print_modes()
def command_check(args, vctrl):
'''Handle check command call'''
vctrl.reduce_packages(args.packages)
# start checking
try:
vctrl.print_versions(args.diff_new, args.diff_cache)
finally:
# save version database
vctrl.cache.save(args.cache, DEFAULT_CACHE_FILENAME)
def command_update(args, vctrl):
'''Handle update command call'''
if not os.path.exists(args.path):
raise NoSuchFile(args.path)
if os.getresuid()[1] == 0:
logging.warn("Warning: You should not run this as root")
pkgdict = parse_pkgbuild(args.path)
pkgname = pkgdict.get("pkgname0", pkgdict.get("pkgbase", None))
pkgver = pkgdict.get("pkgver", None)
# some sanity checks
raise BaseError("Unable to detect pkgname in %s" % args.path)
if pkgname not in vctrl.packages:
raise BaseError("No registered package %s" % pkgname)
# redure packge list to the extracted one
vctrl.reduce_packages((pkgname,))
upver = list(vctrl.check_versions())[0][1]
if upver is None:
raise BaseError("Unable to detect upstream version of %s" % pkgname)
# save cache
if args.save:
vctrl.cache.save(args.cache, DEFAULT_CACHE_FILENAME)
# print what we detect
print("Package name: %s" % pkgname)
print("PKGBUILD version: %s" % pkgver)
print("Upstream version: %s" % vctrl.cache[pkgname])
# compare version
if pkgver == upver:
print("Version are the same. Do nothing!")
return
# update version with upstream
pkgbuild_set_version(args.path, upver)
# update checksum
if args.checksum:
pkgbuild_update_checksums(args.path)
def main():
'''Program entry point'''
try:
# parse command line
args = parse_argv()
# set global debug mode
if args.debug:
logging.getLogger().setLevel(logging.DEBUG)
# load configuration
packages = BaseConfigFile(args.config, DEFAULT_CONFIG_FILENAME)
# load cache database
cachedb = JsonDatabase()
cachedb.load(args.cache, DEFAULT_CACHE_FILENAME)
# load checking controller
vctrl = VersionController(packages, cachedb)
# call command function
return args.func(args, vctrl)
except KeyboardInterrupt:
exit(ERR_ABORT)
except BaseError as exp:
logging.error(exp)
exit(ERR_FATAL)
except Exception as exp:
logging.error("Unknown error. Please report it with --debug.")
logging.error(exp)
if logging.getLogger().getEffectiveLevel() == logging.DEBUG:
raise