You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
calculate-toolkit/cl-check-templates

156 lines
5.6 KiB

#!/usr/bin/env python
#-*- coding: utf-8 -*-
# Copyright 2015-2016 Mir Calculate. http://www.calculate-linux.org
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import argparse
import sys
import re
import os
from os import path
from itertools import chain
from calculate.lib.datavars import DataVars
from calculate.lib.cl_template import templateFunction
from calculate.lib.utils.files import readFile, listDirectory, readLinesFile
from calculate.core.result_viewer import ResultViewer
get_pkgname_by_filename = templateFunction.get_pkgname_by_filename
re_pkgname = templateFunction.reData
class ArgumentParserCheck(argparse.ArgumentParser):
def __init__(self):
super(ArgumentParserCheck, self).__init__(
description="Check templates (check pkg and merge function)")
class PackageDb(object):
def __init__(self, reps, installed_db):
self.installed_db = installed_db
self.reps = reps
self.packages = {}
self.renames = None
def __contains__(self, key):
if self.renames is None:
self.load_renames()
category, op, name = key.partition('/')
if category not in self.packages:
self.packages[category] = set()
self.load_pkg_db(category)
self.load_repos(category)
return name in self.packages[category] or key in self.renames
def get_newname(self, key):
return self.renames.get(key,'')
def load_pkg_db(self, category):
packages = self.packages[category]
for pkgname in listDirectory(path.join(self.installed_db,category)):
pkg = re_pkgname.search(pkgname).group(1)
packages.add(pkg)
self.packages[category] = packages
def load_repos(self, category):
packages = self.packages[category]
for rep_dn in self.reps:
for pkgname in listDirectory(path.join(rep_dn,category)):
if "." not in pkgname:
packages.add(pkgname)
self.packages[category] = packages
def load_renames(self):
self.renames = {}
for rep_dn in self.reps:
for fn in listDirectory(path.join(rep_dn,"profiles/updates"),
fullPath=True):
for line in (x for x in readLinesFile(fn) if x.startswith("move ")):
words = [x for x in line.split() if x]
if len(words) == 3:
self.renames[words[1]] = words[2]
class ScanTemplates(object):
reMerge = re.compile("(merge|pkg)\(([-\w/]*)(?::[^)]+?)?(?:\[[^\]]\])?\)[-!=<>]")
CLT_SUFFIX = ".clt"
def __init__(self, dv=None):
if dv is None:
dv = DataVars()
dv.importData()
dv.flIniFile()
self.dv = dv
dbpkg = '/var/db/pkg'
reps = self.dv.Get('cl_repository_location')
self.db = PackageDb(reps, dbpkg)
self.rv = ResultViewer()
def scan(self,dn):
"""
Сканировать директорию с шаблонами
"""
patch_dirs = []
for root, dirs, files in os.walk(dn):
for fn in (path.join(root,x) for x in files):
data = readFile(fn, binary=True)
try:
data_decoded = data.decode("UTF-8")
except UnicodeDecodeError as e:
continue
for fname, pkg in self.reMerge.findall(data_decoded):
pkg = pkg or get_pkgname_by_filename(fn)
if pkg not in self.db:
self._check_pkg(pkg, fname, fn)
def _check_pkg(self, pkg, fname, fn):
if pkg not in self.db:
self.rv.printERROR(
"Package '{pkgname}' specified in "
"the {funcname}() into "
"'{tempname}' template is not found".format(pkgname=pkg,
funcname=fname, tempname=fn))
elif self.db.get_newname(pkg):
self.rv.printERROR(
"Package '{pkgname}' specified in "
"the {funcname}() into "
"'{tempname}' template is renamed to {newname}".format(
pkgname=pkg, funcname=fname, tempname=fn,
newname=self.get_newname(pkg)))
def scan_clt(self, dn):
"""
Сканировать clt шаблоны
"""
for root, dirs, files in os.walk(dn):
for fn in (path.join(root,x) for x in files
if x.endswith(self.CLT_SUFFIX)):
data = readFile(fn, binary=True)
try:
data_decoded = data.decode("UTF-8")
except UnicodeDecodeError as e:
continue
for fname, pkg in self.reMerge.findall(data_decoded):
pkg = pkg or get_pkgname_by_filename(fn)
self._check_pkg(pkg, fname, fn)
def scan_all(self):
template_path = self.dv.Get('main.cl_template_path')
for dn in template_path:
self.scan(dn)
self.scan_clt('/etc')
if __name__=='__main__':
apv = ArgumentParserCheck()
args = apv.parse_args()
ScanTemplates().scan_all()