Skip to content
archversion 8.08 KiB
Newer Older
Seblu's avatar
Seblu committed
#!/usr/bin/python3
Seblu's avatar
Seblu committed
# 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'''

Seblu's avatar
Seblu committed
from archversion import VERSION, DEFAULT_CONFIG_FILENAME, DEFAULT_CACHE_FILENAME
Seblu's avatar
Seblu committed
from archversion.config import BaseConfigFile
from archversion.database import JsonDatabase
Seblu's avatar
Seblu committed
from archversion.error import BaseError, MissingConfigFile, NoSuchFile
Seblu's avatar
Seblu committed
from archversion.error import ERR_FATAL, ERR_ABORT, ERR_UNKNOWN
Seblu's avatar
Seblu committed
from archversion.pacman import parse_pkgbuild, pkgbuild_set_version, pkgbuild_update_checksums
from archversion.version import VersionController
Seblu's avatar
Seblu committed
import argparse
import logging
Seblu's avatar
Seblu committed
import os
Seblu's avatar
Seblu committed

def parse_argv():
    '''Parse command line arguments'''
    p_main = argparse.ArgumentParser()
    p_main.add_argument("--version", action="version",
                        version="%(prog)s version %s" + VERSION)
Seblu's avatar
Seblu committed
    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()
Seblu's avatar
Seblu committed
    # 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.add_argument("packages", nargs='*', help="only check these packages")
Seblu's avatar
Seblu committed
    p_conf.set_defaults(func=command_config)
Seblu's avatar
Seblu committed
    # sync parser
    p_sync = sp_main.add_parser("sync",
                                help="retrieve upstream and dowstream versions")
    p_sync.add_argument("-s", "--sort", action="store_true",
                        help="sort syncing")
    p_sync.add_argument("packages", nargs='*', help="only sync these packages")
    p_sync.set_defaults(func=command_sync)
Seblu's avatar
Seblu committed
    # modes parser
    p_modes = sp_main.add_parser("modes",
Seblu's avatar
Seblu committed
                                 help="list check against modes")
    p_modes.set_defaults(func=command_modes)
Seblu's avatar
Seblu committed
    # report parser
    p_report = sp_main.add_parser("report", aliases=["ck", "ch"],
                                 help="report packages versions")
    p_report.add_argument("-o", "--offline", action="store_true",
                         help="use cached version as upstream. no network required")
    p_report.add_argument("-c", "--diff-cache", action="store_true",
Seblu's avatar
Seblu committed
                         help="doesn't display cached versions")
Seblu's avatar
Seblu committed
    p_report.add_argument("-n", "--diff-new", action="store_true",
Seblu's avatar
Seblu committed
                         help="only display new versions")
Seblu's avatar
Seblu committed
    p_report.add_argument("-s", "--sort", action="store_true",
Seblu's avatar
Seblu committed
                         help="sort packages by name")
Seblu's avatar
Seblu committed
    p_report.add_argument("-S", "--no-save", dest="save", action="store_false",
                         help="don't save version updates in cache")
Seblu's avatar
Seblu committed
    p_report.add_argument("packages", nargs='*',
                         help="only report these packages")
    p_report.set_defaults(func=command_report)
Seblu's avatar
Seblu committed
    # update parser
Seblu's avatar
Seblu committed
    p_update = sp_main.add_parser("update", aliases=["up"],
                                  help="update a PKGBUILD with the latest version")
Seblu's avatar
Seblu committed
    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")
Seblu's avatar
Seblu committed
    p_update.set_defaults(func=command_update)
    # do parse
    namespace = p_main.parse_args()
    # Ensure subparser was choosen
    if "func" not in namespace:
        p_main.error("missing argument")
    return namespace
Seblu's avatar
Seblu committed

Seblu's avatar
Seblu committed
def command_config(args, vctrl):
    '''list configured packages'''
    if len(args.packages) > 0:
        vctrl.reduce_packages(args.packages)
Seblu's avatar
Seblu committed
    if args.sort:
        vctrl.sort_packages()
    vctrl.print_names()

def command_modes(args, vctrl):
    '''list checking against modes'''
    vctrl.print_modes()

Seblu's avatar
Seblu committed
def command_sync(args, vctrl):
    '''Handle sync command call'''
    # reduce the package list
    if len(args.packages) > 0:
        vctrl.reduce_packages(args.packages)
    # sort packages if asked
    if args.sort:
        vctrl.sort_packages()
    # start syncing
    vctrl.sync_packages()

def command_report(args, vctrl):
    '''Handle report command call'''
    # reduce the package list
Seblu's avatar
Seblu committed
    if len(args.packages) > 0:
        vctrl.reduce_packages(args.packages)
Seblu's avatar
Seblu committed
    # sort packages if asked
    if args.sort:
        vctrl.sort_packages()
Seblu's avatar
Seblu committed
    # start checking
    try:
        vctrl.print_versions(args.diff_new, args.diff_cache)
    finally:
        # save version database
        if args.save:
Seblu's avatar
Seblu committed
            vctrl.cache.save(args.cache, DEFAULT_CACHE_FILENAME)

Seblu's avatar
Seblu committed
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))
Seblu's avatar
Seblu committed
    pkgver = pkgdict.get("pkgver", None)
    # some sanity checks
    if pkgname is None:
Seblu's avatar
Seblu committed
        raise BaseError("Unable to detect pkgname in %s" % args.path)
    if pkgver is None:
Seblu's avatar
Seblu committed
        raise BaseError("Unable to detect pkgver 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,))
Seblu's avatar
Seblu committed
    # get upstream version
    upver = list(vctrl.check_versions())[0][1]
Seblu's avatar
Seblu committed
    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)
Seblu's avatar
Seblu committed
    # 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!")
Seblu's avatar
Seblu committed
        return
    # update version with upstream
    pkgbuild_set_version(args.path, upver)
    # update checksum
    if args.checksum:
        pkgbuild_update_checksums(args.path)

Seblu's avatar
Seblu committed
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)
Seblu's avatar
Seblu committed
        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
Seblu's avatar
Seblu committed
        exit(ERR_UNKNOWN)

if __name__ == '__main__':
    main()

# vim:set ts=4 sw=4 et ai: