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
from collections import OrderedDict
import argparse
import logging
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()
# check parser
p_check = sp_main.add_parser("check", help="check packages versions")
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-cache", action="store_true",
help="don't save version in cache")
p_check.add_argument("packages", nargs='*',
help="only check this packages")
p_check.set_defaults(func=command_check)
# list parser
p_list = sp_main.add_parser("list", help="list various informations")
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)
# update parser
p_update = sp_main.add_parser("update", help="update a PKGBUILD with 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("-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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
def command_check(args, vctrl):
'''Handle check command call'''
# filter packages
if len(args.packages) > 0:
for pkg in list(vctrl.packages):
if pkg not in args.packages:
vctrl.packages.pop(pkg, None)
# sort packages if asked
if args.sort:
vctrl.packages = OrderedDict(sorted(vctrl.packages.items(),
key=lambda t: t[0]))
# start checking
try:
vctrl.print_versions(args.diff_new, args.diff_cache)
finally:
# save version database
if not args.no_cache:
vctrl.cache.save(args.cache, DEFAULT_CACHE_FILENAME)
def command_list(args, vctrl):
'''Handle list command call'''
# sort if asked
if args.sort:
# sort packages
vctrl.packages = OrderedDict(sorted(vctrl.packages.items(),
key=lambda t: t[0]))
# sort cache
vctrl.cache = OrderedDict(sorted(vctrl.cache.items(),
key=lambda t: t[0]))
# call the right action
if args.what == "config":
vctrl.print_names()
elif args.what == "cache":
vctrl.print_cache()
elif args.what == "modes":
vctrl.print_modes()
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))
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
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.")
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