diff --git a/data/cl-git-wrapper b/data/cl-git-wrapper new file mode 100755 index 0000000..00b955f --- /dev/null +++ b/data/cl-git-wrapper @@ -0,0 +1,30 @@ +#!/bin/bash + +# если выполняется обновление уже полученного репозитория +if [[ $1 == "pull" ]] +then + # получить название репозитория + if [[ -f profiles/repo_name ]] + then + repo_name=$(/bin/cat profiles/repo_name) + else + repo_name=$(/bin/basename `pwd`) + fi +elif [[ $1 == "clone" ]] +then + repo_name=$(/bin/basename $3) +fi + +# получить список репозиториев дистрибутива +native_reps=,$(/usr/sbin/cl-core --method core_variables_show \ + --only-value update.cl_update_rep_name), +# если обновляемый репозиторий от дистрибутива +if echo $native_reps | grep -q ,${repo_name}, +then + # отбновить репозиторий через утилиты Calculate + /usr/sbin/cl-core --method update $repo_name --skip-update-metadata --skip-eix-update --update-rev=off +else + # выполнить обновление через git + /usr/bin/git $* +fi + diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..1eb99da --- /dev/null +++ b/setup.cfg @@ -0,0 +1,8 @@ +[install_man] +install_dir=/usr/share + +[install] +install-scripts=/usr/bin + +[install_data] +install_dir=/ diff --git a/setup.py b/setup.py index 22b2264..b052853 100755 --- a/setup.py +++ b/setup.py @@ -20,7 +20,11 @@ __app__ = "calculate-update" __version__ = "3.1.8" +import os from distutils.core import setup +from calculate.install_data import install_data + +data_files = [('usr/libexec/calculate',[('data/cl-git-wrapper',0755)])] setup( name = __app__, @@ -31,4 +35,6 @@ setup( url = "http://calculate-linux.org", license = "http://www.apache.org/licenses/LICENSE-2.0", package_dir = {'calculate.update': "update"}, - packages = ['calculate.update','calculate.update.utils','calculate.update.variables']) + data_files = data_files, + packages = ['calculate.update','calculate.update.utils','calculate.update.variables'], + cmdclass={'install_data': install_data}) diff --git a/update/update.py b/update/update.py index 8254f30..59ede78 100644 --- a/update/update.py +++ b/update/update.py @@ -1,4 +1,3 @@ -#-*- coding: utf-8 -*- # Copyright 2014 Calculate Ltd. http://www.calculate-linux.org # @@ -21,7 +20,14 @@ import time from os import path from subprocess import Popen from calculate.lib.utils.files import (process,getProgPath,STDOUT,removeDir, - processProgress,PercentProgress,process) + processProgress,PercentProgress,process,readFile) + +import xml.etree.ElementTree as ET + + +from calculate.lib.cl_lang import setLocalTranslate,getLazyLocalTranslate +setLocalTranslate('cl_update3',sys.modules[__name__]) +__ = getLazyLocalTranslate(_) class AddonError(Exception): """ @@ -38,9 +44,80 @@ class UpdateError(AddonError): class GitError(AddonError): """Git Error""" -from calculate.lib.cl_lang import setLocalTranslate,getLazyLocalTranslate -setLocalTranslate('cl_update3',sys.modules[__name__]) -__ = getLazyLocalTranslate(_) +class Layman: + """ + Объект для управления репозиториями Layman + + Args: + installed: путь до installed.xml + makeconf: путь до makeconf + """ + def __init__(self,installed,makeconf): + self.installed = installed + self.makeconf = makeconf + + def _add_to_installed(self,rname,rurl): + """ + Добавить репозиторий в installed.xml + """ + if path.exists(self.installed) and readFile(self.installed).strip(): + tree = ET.parse(self.installed) + root = tree.getroot() + # если репозиторий уже присутсвует в installed.xml + if root.find("repo[name='%s']"%rname) is not None: + return + else: + root = ET.Element("repositories",version="1.0") + tree = ET.ElementTree(root) + + newrepo = ET.SubElement(root,"repo",priority="50", + quality="experimental", + status="unofficial") + name = ET.SubElement(newrepo,"name") + name.text = rname + source = ET.SubElement(newrepo,"source",type="git") + source.text = rurl + try: + from layman.utils import indent + indent(root) + except ImportError as e: + pass + with open(self.installed,'w') as f: + f.write('\n') + tree.write(f, encoding="utf-8") + + def _add_to_makeconf(self,rpath): + """ + Добавить репозиторий в layman/make.conf + """ + def fixContent(match): + repos = match.group(1).strip().split('\n') + if not rpath in repos: + repos.insert(0,rpath) + return 'PORTDIR_OVERLAY="\n%s"'%"\n".join(repos); + if path.exists(self.makeconf): + content = readFile(self.makeconf) + if "PORTDIR_OVERLAY" in content: + new_content = re.sub("\APORTDIR_OVERLAY=\"([^\"]+)\"", + fixContent, content,re.DOTALL) + if new_content == content: + return + else: + content = new_content + else: + content = 'PORTDIR_OVERLAY="\n%s"\n'%rpath + content + else: + content = 'PORTDIR_OVERLAY="\n%s"\n'%rpath + with open(self.makeconf,'w') as f: + f.write(content) + + def add(self,rname,rurl,rpath): + """ + Добавить репозиторий в installed.xml и layman/make.conf + """ + self._add_to_installed(rname,rurl) + self._add_to_makeconf(rpath) + return True class Git: """ @@ -407,6 +484,10 @@ class Update: needMeta = True if needMeta: dv.Set('cl_update_outdate_set','on',force=True) + layman = Layman(dv.Get('cl_update_layman_installed'), + dv.Get('cl_update_layman_make')) + if name != "portage": + layman.add(name,url,rpath) return True def syncRepositories(self,repname,clean_on_error=True): diff --git a/update/utils/cl_update.py b/update/utils/cl_update.py index 3d1ba2d..39b7d87 100644 --- a/update/utils/cl_update.py +++ b/update/utils/cl_update.py @@ -87,7 +87,7 @@ class ClUpdateAction(Action): }, # сообщение удачного завершения при обновлении репозиториев {'name':'success_syncrep', - 'message' : __("Synchronzation finished!"), + 'message' : __("Synchronization finished!"), 'depend': (Tasks.success() & Tasks.has_any("sync_reps", "sync_other_reps","emerge_metadata", "eix_update")), diff --git a/update/variables/update.py b/update/variables/update.py index b6db943..a200b6a 100644 --- a/update/variables/update.py +++ b/update/variables/update.py @@ -65,7 +65,7 @@ class VariableClUpdateRevSet(Variable): type = "bool" opt = ["--update-rev"] untrusted = True - value = "off" + value = "on" check_after = ["cl_update_sync_rep", "cl_update_metadata_force", "cl_update_other_set", @@ -249,7 +249,7 @@ class VariableClUpdateSyncRep(Variable): (orderList.index(x) if x in orderList else -1),reverse=True) def get(self): - return self.Get('cl_update_rep_name') + return list(reversed(self.Get('cl_update_rep_name'))) def choice(self): return self.Get('cl_update_rep_name') @@ -366,3 +366,17 @@ class VariableClUpdateOtherRepPath(FieldValue,ReadonlyVariable): type = "list" source_variable = "cl_update_other_rep_data" column = 1 + +class VariableClUpdateLaymanInstalled(Variable): + """ + Путь до файла layman installed.xml + """ + # TODO: извлечь из layman.cfg + value = "/var/lib/layman/installed.xml" + +class VariableClUpdateLaymanMake(Variable): + """ + Путь до файла make.conf изменяемого layman`ом + """ + # TODO: извлечь из layman.cfg + value = "/var/lib/layman/make.conf"