Commit 9e594325 authored by Jakub Ružička's avatar Jakub Ružička
Browse files

Initial Commit ᕕ( ᐛ )ᕗ

The journey to tame all packaging metadata begins...
parents
This diff is collapsed.
# cznicinfo
is a python module and CLI tool for (managing and) querying project and packaging information
for CZ.NIC open source projects.
## status
This is currently a WIP by `jruzicka`.
import pbr.version
version_info = pbr.version.VersionInfo('cznicinfo')
try:
__version__ = version_info.version_string()
except AttributeError:
__version__ = None
__all__ = ['__version__']
"""CZ.NIC info
Usage: cznicinfo [--help | --version] <command> [<args>...]
cznicinfo <command> --help
Commands:
show Show project info
Options:
-h --help Show this screen.
--version Show version.
"""
from docopt import docopt
import sys
from . import __version__
from . import commands
def run_command(command, args):
modname = 'cznicinfo.commands.%s' % command
mod = __import__(modname, fromlist=[''])
return mod.run_command(args)
def cznicinfo(*cargs):
"""
cznicinfo CLI interface
Execute cznicinfo command with specified arguments
and return shell friendly exit code.
py> cznicinfo('command', 'argument')
is equivalent to
$> cznicinfo command argument
Individual commands map to functions in commands module.
"""
args = docopt(__doc__,
version=__version__,
options_first=True)
if args['<command>']:
run_command(args['<command>'], args)
return 0
def main():
"""
cznicinfo console_scripts entry point
"""
cargs = sys.argv[1:]
sys.exit(cznicinfo(*cargs))
if __name__ == '__main__':
main()
"""
Show information for selected project(s).
Usage: cznicinfo show [-h] <project>...
"""
from docopt import docopt
from cznicinfo import infoparse
from cznicinfo.util import log
def run_command(*args, **kwargs):
cargs = docopt(__doc__)
info = infoparse.load_info();
not_found = []
found = False
for pname in cargs['<project>']:
print("# SHOW info for: %s" % pname)
for proj in info['projects']:
if (proj['short-name'] == pname or
proj['full-name'] == pname):
infoparse.pretty_print_data(proj)
found = True
break
if not found:
not_found.append(pname)
if not_found:
projs = ", ".join(not_found)
log.warn("\nFollowing projects were not found: %s" % projs)
return 0
# -*- coding: utf-8 -*-
import errno
import glob
import imp
import os.path
class Config(dict):
def __init__(self, defaults=None):
dict.__init__(self, defaults or {})
def from_pyfile(self, filename, silent=False):
d = imp.new_module('extconfig')
d.__file__ = filename
try:
with open(filename) as config_file:
exec(compile(config_file.read(), filename, 'exec'), d.__dict__)
except IOError as e:
if silent and e.errno in (errno.ENOENT, errno.EISDIR):
return False
e.strerror = 'Unable to load configuration file (%s)' % e.strerror
raise
self.from_object(d)
return True
def from_object(self, o):
for key in dir(o):
if key.isupper():
self[key] = getattr(o, key)
def __repr__(self):
return '<%s %s>' % (self.__class__.__name__, dict.__repr__(self))
cfg = Config({
'HOME_DIR': os.path.expanduser("~/.config/cznicinfo"),
'FETCH_PERIOD': 600,
})
cfg_files = []
def get_config_fns():
home_glob = cfg['HOME_DIR'] + '/conf.d/*.py'
fns = glob.glob('/etc/cznicinfo.d/*.py') + glob.glob(home_glob)
return fns
def load_config():
for cfn in get_config_fns():
cfg.from_pyfile(cfn)
cfg_files.append(cfn)
load_config()
projects:
- full-name: Knot DNS
short-name: knot
upstream: https://gitlab.nic.cz/knot/knot-dns
homepage: https://www.knot-dns.cz/
mirrors:
- https://github.com/CZ-NIC/knot
pkg:
pkg-name: knot
pkg-style: all-in-upstream-repo
build-system: OBS
build-status-url: https://build.opensuse.org/package/show/home:CZ-NIC:knot-dns-latest/knot
pkg-download-url: https://www.knot-dns.cz/download/
distro-pkgs:
- distro: arch
pkg-name: (INHERITED FROM pkg-name ABOVE)
- distro: debian
- distro: fedora
- full-name: Knot Resolver
short-name: knot
homepage: https://www.knot-resolver.cz/
upstream: https://gitlab.nic.cz/knot/knot-resolver
mirrors:
- https://github.com/CZ-NIC/knot-resolver
class CZNICInfoException(Exception):
msg_fmt = "An unknown error occurred"
exit_code = 1
def __init__(self, msg=None, exit_code=None, **kwargs):
self.kwargs = kwargs
if not msg:
try:
msg = self.msg_fmt % kwargs
except Exception:
# kwargs doesn't match those in message.
# Returning this is still better than nothing.
msg = self.msg_fmt
if exit_code is not None:
self.exit_code = exit_code
super(CZNICInfoException, self).__init__(msg)
import yaml
import os
from cznicinfo.util import log
def get_info_fn(module_path=None):
if module_path:
path = module_path
else:
import cznicinfo
path = os.path.dirname(cznicinfo.__file__)
path = os.path.join(path, 'data', 'cznicinfo.yaml')
return path
def load_info(info_fn=None):
if not info_fn:
info_fn = get_info_fn()
log.info("Loading info file: %s", info_fn)
with open(info_fn, 'r') as stream:
data = yaml.safe_load(stream)
return data
def pretty_print_data(d):
print(yaml.dump(d))
import logging
from cznicinfo.util import terminal
WARN = logging.WARN
INFO = logging.INFO
# between info and debug
VERBOSE = (logging.INFO + logging.DEBUG) / 2
DEBUG = logging.DEBUG
logging.basicConfig(format='%(message)s', level=logging.INFO)
log = logging.getLogger()
class LogTerminal(terminal.Terminal):
@property
def warn(self):
return self.yellow
@property
def important(self):
return self.yellow_bold
@property
def error(self):
return self.red
@property
def good(self):
return self.green
@property
def cmd(self):
return self.cyan
# global terminal instance for color printing
T = LogTerminal()
def set_colors(colors):
global T
if colors == 'yes':
if not terminal.COLOR_TERMINAL:
return False
T = LogTerminal(force_styling=True)
return True
elif colors == 'no':
if not terminal.COLOR_TERMINAL:
return True
T = LogTerminal(force_styling=None)
return True
elif colors == 'auto':
T = LogTerminal()
return True
return False
def error(*args, **kwargs):
if args:
largs = list(args)
largs[0] = T.error(args[0])
args = tuple(largs)
log.error(*args, **kwargs)
def warn(*args, **kwargs):
if args:
largs = list(args)
largs[0] = T.warn(args[0])
args = tuple(largs)
log.warning(*args, **kwargs)
def success(*args, **kwargs):
if args:
largs = list(args)
largs[0] = T.good(args[0])
args = tuple(largs)
log.info(*args, **kwargs)
def info(*args, **kwargs):
log.info(*args, **kwargs)
def verbose(*args, **kwargs):
log.log(VERBOSE, *args, **kwargs)
def debug(*args, **kwargs):
log.debug(*args, **kwargs)
def command(*args, **kwargs):
log.info(*args, **kwargs)
class NullCallableString(str):
"""
This emulates blessings class for cases when blessings aren't available
"""
def __new__(cls):
return str.__new__(cls, u'')
def __call__(self, arg, *extra_args):
if isinstance(arg, int):
return u''
return arg
class PlainTerminal(object):
"""
Mock of blessings Terminal that ignores formatting
"""
nullstr = NullCallableString()
def __getattr__(self, attr):
setattr(self, attr, self.nullstr)
return self.nullstr
COLOR_TERMINAL = False
try:
import blessings
COLOR_TERMINAL = True
Terminal = blessings.Terminal
except ImportError:
Terminal = PlainTerminal
[metadata]
name = cznicinfo
summary = python tool for querying project/packaging information for CZ.NIC projects
description-file = README.md
license = Apache Software License
classifiers =
Programming Language :: Python :: 3
Intended Audience :: Information Technology
Intended Audience :: System Administrators
License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
Operating System :: POSIX :: Linux
author = Jakub Ruzicka
author-email = jakub.ruzicka@nicz.cz
home-page = https://gitlab.nic.cz/packaging/cznicinfo
keywords = packaging, tool
[global]
setup-hooks = pbr.hooks.setup_hook
[files]
packages =
cznicinfo
[entry_points]
console_scripts =
cznicinfo = cznicinfo.cli:main
[aliases]
test=pytest
[pycodestyle]
exclude=build,lib,.tox,third,*.egg,docs,packages,.eggs
# E123, E125, W503 skipped as they are invalid PEP-8.
ignore = E123,E125,W503
show-source = True
#!/usr/bin/env python
import re
import setuptools
import sys
# In python < 2.7.4, a lazy loading of package `pbr` will break
# setuptools if some other modules registered functions in `atexit`.
# solution from: http://bugs.python.org/issue15881#msg170215
try:
import multiprocessing # noqa
except ImportError:
pass
setuptools.setup(
setup_requires=['pbr'],
pbr=True)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment