Skip to content
archversion 7.05 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()
    # check parser
Seblu's avatar
Seblu committed
    p_check = sp_main.add_parser("check", aliases=["ck"],
                                 help="check packages versions")
Seblu's avatar
Seblu committed
    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")
Seblu's avatar
Seblu committed
    p_check.add_argument("packages", nargs='*',
                         help="only check this packages")
    p_check.set_defaults(func=command_check)
    # list parser
Seblu's avatar
Seblu committed
    p_list = sp_main.add_parser("list", aliases=["ls"],
                                help="list various informations")
Seblu's avatar
Seblu committed
    p_list.add_argument("-s", "--sort", action="store_true",
                        help="sort listing")
    p_list.add_argument("what", choices=("config", "cache", "modes"),
                        help="config: list configured packages. "
                        "cache: list packages in cache. "
                        "modes: list comparaison modes. ")
    p_list.set_defaults(func=command_list)
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 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("-C", "--cache", action="store_true",
                          help="use cache")
    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

def command_check(args, vctrl):
    '''Handle check 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)

def command_list(args, vctrl):
    '''Handle list command call'''
    if args.what == "config":
        if args.sort:
            vctrl.sort_packages()
Seblu's avatar
Seblu committed
        vctrl.print_names()
    elif args.what == "cache":
        if args.sort:
            vctrl.sort_cache()
Seblu's avatar
Seblu committed
        vctrl.print_cache()
    elif args.what == "modes":
        vctrl.print_modes()

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:
        raise BaseError("Unable to detect pkgname in %s" % args.path)
    if "pkgver" is None:
        raise BaseError("Unable to detect pkgver in %s" % args.path)
    # get upstream version
    vctrl.packages = [ pkgname ]
    if not args.cache:
        vctrl.check_versions()
    upver = vctrl.cache.get(pkgname, None)
    if upver is None:
        raise BaseError("Unable to detect upstream version of %s" % pkgname)
    # 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: