Gentooシステムで.keywordsファイルをどのように整理しますか?

Gentooシステムで.keywordsファイルをどのように整理しますか?

gentoo stableキーワードリストに次の構文を含む行を追加して、システムのテストパッケージを選択できます。

cat /etc/portage/package.keywords

=dev-python/ipython-0.13.2 ~amd64
# and many lines later
=dev-python/ipython-0.14.1 ~amd64
# and many lines later
>=dev-python/ipython-0.13.4 ~amd64

ファイルは時間の経過とともに大きくなり、遅かれ早かれ、人々はどの行が古いのか覚えていないでしょう。

スクリプトで頻繁にリストを整理するにはどうすればよいですか?

行を削除する必要があります。

  • テストバージョンがすでに安定している場合
  • >=同じパッケージの場合
  • =バージョン番号が小さい同じパッケージの場合

答え1

今これを行うための公式パッケージがあります。アプリケーションPortage/Portpic

それはできる

  • 役に立たないUSEフラグを探して
  • 古いキーワードと
  • -f引数として追加(修正)すると、ファイルがクリーンアップされます。

答え2

この問題を解決するために、小さなPythonスクリプトを作成しました。このロジックは、ファイル内のすべての行を見て、またはで始まる行でのみpackage.accept_keywords機能します。この行には最大限のバージョンがあるため、不要になったことを確認できます。修飾子やaのない行は、その行が使用されなくなったかどうかわからないため、そのまま残ります。=<=>=

次に、関心のある行を解析し、インストールされているパッケージのバージョンを確認します。インストールされているバージョンがキーワードのバージョンより最新であるか、まったくインストールされていない場合、キーワードは廃止予定と見なされます。インストールされているパッケージがキーワードのあるバージョンと同じバージョンの場合は、インストールされているパッケージにキーワードがまだ存在していることを確認してください。安定するとラインは削除され、そうでなければ維持されます。

#!/bin/env python

import re
import portage

vartree = portage.db[portage.root]['vartree']

with open('/etc/portage/package.accept_keywords') as f:
    for x in f:
        # eat newline
        x = x.rstrip()
        # we only want lines with a bounded max version
        if re.match('^(=|<=)',x):
            # get the package cpv atom -- strip the =|<= and the trailing keyword(s)
            cpv_masked = re.sub('[<=]','',x.split(' ',1)[0])
            cat, pkg, ver, rev = portage.catpkgsplit(cpv_masked)
            # get cpv for all installed versions of the package
            cpv_installed = vartree.dep_match(cat+'/'+pkg)
            for cpv in cpv_installed:
                cmp = portage.pkgcmp(portage.pkgsplit(cpv), portage.pkgsplit(cpv_masked))
                # if the installed version is not newer than the masked version
                if (cmp <= 0):
                    # check if this version is still keyworded
                    cpv_keywords = vartree.dbapi.aux_get(cpv, ['KEYWORDS'])
                    # keep keyword if the package has no keywords (**)
                    if not cpv_keywords[0]:
                        print(x)
                        break
                    # check if the installed package is still keyworded
                    for cpv_keyword in cpv_keywords[0].split(' '):
                        if cpv_masked_keyword == cpv_keyword:
                            # it is, keep the atom and move on to the next one
                            print(x)
                            break                    
        else:
            # keep atoms that have an unbounded max version
            print(x)

これにより、新しいキーワードファイルが標準出力として印刷されます。 ノート処置: 出力をリダイレクトしないでください。/etc/portage/package.accept_keywordsそうしないと、ファイルが破損し、すべてのコンテンツが失われます。

これはキーワードファイルを整理するのに非常に役立ち、他の問題の場合は、ファイルを並べ替えてから同じパッケージに対して複数行をチェックすると、残りの問題の大部分を解決するのに役立ちます。

答え3

package.*ファイルをディレクトリに変換できることをご存知ですか?

その後、原子を複数のファイルにまとめることができます。たとえば、私のシステムから次の情報を取得しました。

/etc/portage/package.keywords:
  package.keywords
  qt5.keywords
  xfce.keywords

/etc/portage/package.use:
  package.use
  qt5.use
  xfce.use

など。

私はこれが私のファイルを更新するのに非常に便利であることを知りました。

答え4

これは、インストールされなくなった/etc/portage/package.*ファイルのエントリをフィルタリングする小さなスクリプトです。また、削除されたアイテムのすぐ上にあるすべてのコメント行を削除します。 (たとえば、自動マスク解除で作成されます)コメントを空白行で区切ると、サブコメントのみが削除されます。スクリプトは重複エントリを削除しません。

参考にしてくださいPortageユーティリティpostsyncフックをインストールする必要があります。/etc/portage/postsync.d/q-reinitialize有効にする必要があります。このスクリプトを機能させるには。

#!/usr/bin/env python3

import argparse
import sys
import os
from subprocess import call
import contextlib

if __name__ != '__main__':
    raise Exception("ust be used as a main module with a parameter as the input file")

parser = argparse.ArgumentParser(description="cleanup /etc/portage/package.* files")
parser.add_argument("infile", help="an input file to clean")
parser.add_argument("--out", dest="outfile", help="the output is written to this file. if not specified, the output is written to stdout.")
parser.add_argument("--inplace", action='store_true', help="overwrite the in file. if specified, --out is ignored.")

args = parser.parse_args()

def checkInstalled(package):
    with open(os.devnull, 'w') as devnull:
        status = call('qlist -IC "' + str(package.split()[0].strip()) + '"', shell=True, stdout=devnull)
        return status == 0

@contextlib.contextmanager
def getOutFile(args):
    if args.inplace:
        fh = open(args.infile, 'w')
    elif args.outfile != None:
        fh = open(args.outfile, 'w')
    else:
        fh = sys.stdout
    try:
        yield fh
    finally:
        if fh is not sys.stdout:
            fh.close()

commentBuffer = []
lines = []

with open(args.infile, 'r') as f:
    lines = f.readlines()

with getOutFile(args) as out:
    for line in lines: 
        if line.lstrip().startswith("#"):
            commentBuffer.append(line)
        else:
            if line.strip() == "" or checkInstalled(line):
                if  commentBuffer:
                    out.write("".join(commentBuffer))
                out.write(line)
            commentBuffer = []

関連情報