From d18c334b456bd3a08779a404ccf54d45448016f1 Mon Sep 17 00:00:00 2001 From: fuzzyray Date: Wed, 6 Jan 2010 16:11:52 +0000 Subject: [PATCH] Tagging the 0.3.0_rc8 release of gentoolkit. svn path=/tags/gentoolkit-0.3.0_rc8/; revision=730 --- deprecated/change/AUTHORS | 5 + deprecated/change/ChangeLog | 7 + deprecated/change/README | 20 + deprecated/change/change | 343 +++++ deprecated/change/change.1 | 0 deprecated/dep-clean/AUTHORS | 9 + deprecated/dep-clean/ChangeLog | 13 + deprecated/dep-clean/README | 4 + deprecated/dep-clean/dep-clean | 164 +++ deprecated/dep-clean/dep-clean.1 | 194 +++ deprecated/dev-scripts/README | 2 + deprecated/dev-scripts/included_headers.sh | 159 +++ deprecated/dev-scripts/linking_libs.sh | 204 +++ deprecated/distfiles-clean/AUTHORS | 6 + deprecated/distfiles-clean/ChangeLog | 2 + deprecated/distfiles-clean/TODO | 0 deprecated/distfiles-clean/distfiles-clean | 78 ++ deprecated/epkginfo/AUTHORS | 3 + deprecated/epkginfo/README | 1 + deprecated/epkginfo/epkginfo | 244 ++++ deprecated/epkginfo/epkginfo.1 | 34 + deprecated/epkgmove/AUTHORS | 2 + deprecated/epkgmove/ChangeLog | 20 + deprecated/epkgmove/Makefile | 20 + deprecated/epkgmove/README | 16 + deprecated/epkgmove/TODO | 0 deprecated/epkgmove/epkgmove | 895 +++++++++++++ deprecated/etc-update/AUTHORS | 0 deprecated/etc-update/ChangeLog | 0 deprecated/etc-update/Makefile | 20 + deprecated/etc-update/README | 0 deprecated/etc-update/etc-update | 165 +++ deprecated/etc-update/etc-update.1 | 12 + deprecated/etcat/AUTHORS | 5 + deprecated/etcat/ChangeLog | 36 + deprecated/etcat/Makefile | 18 + deprecated/etcat/README | 2 + deprecated/etcat/TODO | 0 deprecated/etcat/etcat | 688 ++++++++++ deprecated/etcat/etcat.1 | 79 ++ deprecated/genpkgindex/Makefile | 18 + deprecated/genpkgindex/genpkgindex | 336 +++++ deprecated/genpkgindex/genpkgindex.1 | 59 + deprecated/gensync/AUTHORS | 5 + deprecated/gensync/ChangeLog | 12 + deprecated/gensync/Makefile | 24 + deprecated/gensync/README | 16 + deprecated/gensync/TODO | 4 + .../gensync/bmg-gnome-current.syncsource | 18 + deprecated/gensync/bmg-main.syncsource | 18 + deprecated/gensync/gensync | 226 ++++ deprecated/gensync/gensync.1 | 75 ++ deprecated/gensync/gensync.conf | 8 + deprecated/lintool/AUTHORS | 1 + deprecated/lintool/COPYING | 340 +++++ deprecated/lintool/ChangeLog | 71 + deprecated/lintool/NEWS | 0 deprecated/lintool/README | 23 + deprecated/lintool/lintool.1 | 41 + deprecated/lintool/lintool.py | 320 +++++ deprecated/lintool/lintool/__init__.py | 3 + deprecated/lintool/lintool/changelog.py | 105 ++ deprecated/lintool/lintool/digest.py | 28 + deprecated/lintool/lintool/ebuild.py | 349 +++++ deprecated/lintool/lintool/test.py | 30 + deprecated/moo/AUTHORS | 1 + deprecated/moo/README | 0 deprecated/moo/TODO | 0 deprecated/moo/moo | 244 ++++ deprecated/moo/moo.1 | 12 + deprecated/old-scripts/Makefile | 32 + deprecated/old-scripts/dep-clean | 272 ++++ deprecated/old-scripts/dep-clean.1 | 190 +++ deprecated/old-scripts/ewhich | 44 + deprecated/old-scripts/ewhich.1 | 24 + deprecated/old-scripts/mkebuild | 216 +++ deprecated/old-scripts/mkebuild.1 | 20 + deprecated/old-scripts/pkg-clean | 107 ++ deprecated/old-scripts/pkg-clean.1 | 20 + deprecated/old-scripts/pkg-size | 63 + deprecated/old-scripts/pkg-size.1 | 11 + deprecated/pkg-clean/AUTHORS | 5 + deprecated/pkg-clean/ChangeLog | 0 deprecated/pkg-clean/README | 0 deprecated/pkg-clean/pkg-clean | 99 ++ deprecated/pkg-clean/pkg-clean.1 | 20 + deprecated/pkg-size/pkg-size | 66 + deprecated/qpkg/AUTHORS | 0 deprecated/qpkg/ChangeLog | 5 + deprecated/qpkg/Makefile | 19 + deprecated/qpkg/README | 0 deprecated/qpkg/TODO | 0 deprecated/qpkg/qpkg | 581 +++++++++ deprecated/qpkg/qpkg.1 | 112 ++ deprecated/qpkg/qpkg.sh | 520 ++++++++ deprecated/useflag/AUTHORS | 0 deprecated/useflag/ChangeLog | 0 deprecated/useflag/README | 0 deprecated/useflag/useflag | 610 +++++++++ deprecated/useflag/useflag.1 | 69 + gentoolkit-dev/AUTHORS | 6 + gentoolkit-dev/COPYING | 340 +++++ gentoolkit-dev/ChangeLog | 902 +++++++++++++ gentoolkit-dev/Makefile | 54 + gentoolkit-dev/Makefile.skel | 18 + gentoolkit-dev/NEWS | 0 gentoolkit-dev/README | 37 + gentoolkit-dev/README.Developer | 49 + gentoolkit-dev/TODO | 8 + gentoolkit-dev/makedefs.mak | 21 + gentoolkit-dev/src/ebump/AUTHORS | 5 + gentoolkit-dev/src/ebump/ChangeLog | 8 + gentoolkit-dev/src/ebump/Makefile | 20 + gentoolkit-dev/src/ebump/README | 18 + gentoolkit-dev/src/ebump/TODO | 0 gentoolkit-dev/src/ebump/ebump | 390 ++++++ gentoolkit-dev/src/ebump/ebump.1 | 110 ++ gentoolkit-dev/src/echangelog/AUTHORS | 1 + gentoolkit-dev/src/echangelog/ChangeLog | 84 ++ gentoolkit-dev/src/echangelog/Makefile | 26 + gentoolkit-dev/src/echangelog/README | 11 + gentoolkit-dev/src/echangelog/TODO | 0 gentoolkit-dev/src/echangelog/echangelog | 794 +++++++++++ gentoolkit-dev/src/echangelog/echangelog.1 | 270 ++++ gentoolkit-dev/src/echangelog/test/TEST.pm | 26 + .../src/echangelog/test/templates/test.patch | 6 + .../test/templates/vcstest-0.0.1.ebuild | 16 + gentoolkit-dev/src/echangelog/test/test.sh | 176 +++ gentoolkit-dev/src/ego/AUTHOR | 1 + gentoolkit-dev/src/ego/AUTHORS | 1 + gentoolkit-dev/src/ego/ChangeLog | 2 + gentoolkit-dev/src/ego/Makefile | 18 + gentoolkit-dev/src/ego/README | 2 + gentoolkit-dev/src/ego/TODO | 0 gentoolkit-dev/src/ego/ego | 86 ++ gentoolkit-dev/src/ekeyword/AUTHORS | 1 + gentoolkit-dev/src/ekeyword/ChangeLog | 46 + gentoolkit-dev/src/ekeyword/Makefile | 26 + gentoolkit-dev/src/ekeyword/README | 20 + gentoolkit-dev/src/ekeyword/TODO | 0 gentoolkit-dev/src/ekeyword/ekeyword | 147 +++ gentoolkit-dev/src/ekeyword/ekeyword.pod | 68 + gentoolkit-dev/src/ekeyword2/ekeyword2 | 96 ++ gentoolkit-dev/src/eshowkw/Makefile | 18 + gentoolkit-dev/src/eshowkw/eshowkw | 357 +++++ gentoolkit-dev/src/eshowkw/eshowkw.1 | 14 + gentoolkit-dev/src/eviewcvs/AUTHORS | 1 + gentoolkit-dev/src/eviewcvs/Makefile | 25 + gentoolkit-dev/src/eviewcvs/README | 11 + gentoolkit-dev/src/eviewcvs/eviewcvs | 95 ++ gentoolkit-dev/src/eviewcvs/eviewcvs.pod | 48 + gentoolkit-dev/src/imlate/Makefile | 18 + gentoolkit-dev/src/imlate/imlate | 484 +++++++ gentoolkit-dev/src/imlate/imlate.1 | 48 + gentoolkit/AUTHORS | 28 + gentoolkit/COPYING | 340 +++++ gentoolkit/CREDITS | 16 + gentoolkit/ChangeLog | 864 ++++++++++++ gentoolkit/DEVELOPING | 161 +++ gentoolkit/MANIFEST.in | 13 + gentoolkit/NEWS | 40 + gentoolkit/README | 46 + gentoolkit/README.dev | 40 + gentoolkit/THANKS | 8 + gentoolkit/TODO | 60 + gentoolkit/bin/eclean | 834 ++++++++++++ gentoolkit/bin/epkginfo | 39 + gentoolkit/bin/equery | 44 + gentoolkit/bin/eread | 94 ++ gentoolkit/bin/euse | 551 ++++++++ gentoolkit/bin/glsa-check | 396 ++++++ gentoolkit/bin/revdep-rebuild | 1159 +++++++++++++++++ gentoolkit/data/99gentoolkit-env | 1 + gentoolkit/data/eclean/distfiles.exclude | 5 + gentoolkit/data/eclean/packages.exclude | 4 + .../data/revdep-rebuild/99revdep-rebuild | 21 + gentoolkit/man/eclean.1 | 173 +++ gentoolkit/man/epkginfo.1 | 38 + gentoolkit/man/equery.1 | 538 ++++++++ gentoolkit/man/eread.1 | 12 + gentoolkit/man/euse.1 | 102 ++ gentoolkit/man/glsa-check.1 | 66 + gentoolkit/man/revdep-rebuild.1 | 137 ++ gentoolkit/pylintrc | 321 +++++ gentoolkit/pym/gentoolkit/__init__.py | 23 + gentoolkit/pym/gentoolkit/atom.py | 357 +++++ gentoolkit/pym/gentoolkit/cpv.py | 158 +++ gentoolkit/pym/gentoolkit/dbapi.py | 17 + gentoolkit/pym/gentoolkit/dependencies.py | 320 +++++ .../pym/gentoolkit/deprecated/helpers.py | 176 +++ gentoolkit/pym/gentoolkit/equery/__init__.py | 351 +++++ gentoolkit/pym/gentoolkit/equery/belongs.py | 156 +++ gentoolkit/pym/gentoolkit/equery/changes.py | 205 +++ gentoolkit/pym/gentoolkit/equery/check.py | 291 +++++ gentoolkit/pym/gentoolkit/equery/depends.py | 193 +++ gentoolkit/pym/gentoolkit/equery/depgraph.py | 223 ++++ gentoolkit/pym/gentoolkit/equery/files.py | 320 +++++ gentoolkit/pym/gentoolkit/equery/hasuse.py | 156 +++ gentoolkit/pym/gentoolkit/equery/list_.py | 224 ++++ gentoolkit/pym/gentoolkit/equery/meta.py | 492 +++++++ gentoolkit/pym/gentoolkit/equery/size.py | 193 +++ gentoolkit/pym/gentoolkit/equery/uses.py | 317 +++++ gentoolkit/pym/gentoolkit/equery/which.py | 102 ++ gentoolkit/pym/gentoolkit/errors.py | 114 ++ gentoolkit/pym/gentoolkit/glsa/__init__.py | 726 +++++++++++ gentoolkit/pym/gentoolkit/helpers.py | 709 ++++++++++ gentoolkit/pym/gentoolkit/metadata.py | 302 +++++ gentoolkit/pym/gentoolkit/package.py | 459 +++++++ gentoolkit/pym/gentoolkit/pprinter.py | 131 ++ gentoolkit/pym/gentoolkit/query.py | 34 + gentoolkit/pym/gentoolkit/test/__init__.py | 6 + .../pym/gentoolkit/test/equery/__init__.py | 6 + .../pym/gentoolkit/test/equery/test_init.py | 46 + gentoolkit/pym/gentoolkit/test/test_atom.py | 149 +++ gentoolkit/pym/gentoolkit/test/test_cpv.py | 59 + .../pym/gentoolkit/test/test_helpers.py | 107 ++ gentoolkit/pym/gentoolkit/test/test_syntax.py | 33 + gentoolkit/pym/gentoolkit/textwrap_.py | 99 ++ gentoolkit/pym/gentoolkit/versionmatch.py | 132 ++ gentoolkit/setup.py | 116 ++ 220 files changed, 27644 insertions(+) create mode 100644 deprecated/change/AUTHORS create mode 100644 deprecated/change/ChangeLog create mode 100644 deprecated/change/README create mode 100644 deprecated/change/change create mode 100644 deprecated/change/change.1 create mode 100644 deprecated/dep-clean/AUTHORS create mode 100644 deprecated/dep-clean/ChangeLog create mode 100644 deprecated/dep-clean/README create mode 100644 deprecated/dep-clean/dep-clean create mode 100644 deprecated/dep-clean/dep-clean.1 create mode 100644 deprecated/dev-scripts/README create mode 100755 deprecated/dev-scripts/included_headers.sh create mode 100755 deprecated/dev-scripts/linking_libs.sh create mode 100644 deprecated/distfiles-clean/AUTHORS create mode 100644 deprecated/distfiles-clean/ChangeLog create mode 100644 deprecated/distfiles-clean/TODO create mode 100644 deprecated/distfiles-clean/distfiles-clean create mode 100644 deprecated/epkginfo/AUTHORS create mode 100644 deprecated/epkginfo/README create mode 100755 deprecated/epkginfo/epkginfo create mode 100644 deprecated/epkginfo/epkginfo.1 create mode 100644 deprecated/epkgmove/AUTHORS create mode 100644 deprecated/epkgmove/ChangeLog create mode 100644 deprecated/epkgmove/Makefile create mode 100644 deprecated/epkgmove/README create mode 100644 deprecated/epkgmove/TODO create mode 100644 deprecated/epkgmove/epkgmove create mode 100644 deprecated/etc-update/AUTHORS create mode 100644 deprecated/etc-update/ChangeLog create mode 100644 deprecated/etc-update/Makefile create mode 100644 deprecated/etc-update/README create mode 100755 deprecated/etc-update/etc-update create mode 100644 deprecated/etc-update/etc-update.1 create mode 100644 deprecated/etcat/AUTHORS create mode 100644 deprecated/etcat/ChangeLog create mode 100644 deprecated/etcat/Makefile create mode 100644 deprecated/etcat/README create mode 100644 deprecated/etcat/TODO create mode 100755 deprecated/etcat/etcat create mode 100644 deprecated/etcat/etcat.1 create mode 100644 deprecated/genpkgindex/Makefile create mode 100644 deprecated/genpkgindex/genpkgindex create mode 100644 deprecated/genpkgindex/genpkgindex.1 create mode 100644 deprecated/gensync/AUTHORS create mode 100644 deprecated/gensync/ChangeLog create mode 100644 deprecated/gensync/Makefile create mode 100644 deprecated/gensync/README create mode 100644 deprecated/gensync/TODO create mode 100644 deprecated/gensync/bmg-gnome-current.syncsource create mode 100644 deprecated/gensync/bmg-main.syncsource create mode 100755 deprecated/gensync/gensync create mode 100644 deprecated/gensync/gensync.1 create mode 100644 deprecated/gensync/gensync.conf create mode 100644 deprecated/lintool/AUTHORS create mode 100644 deprecated/lintool/COPYING create mode 100644 deprecated/lintool/ChangeLog create mode 100644 deprecated/lintool/NEWS create mode 100644 deprecated/lintool/README create mode 100644 deprecated/lintool/lintool.1 create mode 100755 deprecated/lintool/lintool.py create mode 100644 deprecated/lintool/lintool/__init__.py create mode 100644 deprecated/lintool/lintool/changelog.py create mode 100644 deprecated/lintool/lintool/digest.py create mode 100644 deprecated/lintool/lintool/ebuild.py create mode 100644 deprecated/lintool/lintool/test.py create mode 100644 deprecated/moo/AUTHORS create mode 100644 deprecated/moo/README create mode 100644 deprecated/moo/TODO create mode 100755 deprecated/moo/moo create mode 100644 deprecated/moo/moo.1 create mode 100644 deprecated/old-scripts/Makefile create mode 100644 deprecated/old-scripts/dep-clean create mode 100644 deprecated/old-scripts/dep-clean.1 create mode 100755 deprecated/old-scripts/ewhich create mode 100644 deprecated/old-scripts/ewhich.1 create mode 100644 deprecated/old-scripts/mkebuild create mode 100644 deprecated/old-scripts/mkebuild.1 create mode 100644 deprecated/old-scripts/pkg-clean create mode 100644 deprecated/old-scripts/pkg-clean.1 create mode 100644 deprecated/old-scripts/pkg-size create mode 100644 deprecated/old-scripts/pkg-size.1 create mode 100644 deprecated/pkg-clean/AUTHORS create mode 100644 deprecated/pkg-clean/ChangeLog create mode 100644 deprecated/pkg-clean/README create mode 100644 deprecated/pkg-clean/pkg-clean create mode 100644 deprecated/pkg-clean/pkg-clean.1 create mode 100644 deprecated/pkg-size/pkg-size create mode 100644 deprecated/qpkg/AUTHORS create mode 100644 deprecated/qpkg/ChangeLog create mode 100644 deprecated/qpkg/Makefile create mode 100644 deprecated/qpkg/README create mode 100644 deprecated/qpkg/TODO create mode 100644 deprecated/qpkg/qpkg create mode 100644 deprecated/qpkg/qpkg.1 create mode 100644 deprecated/qpkg/qpkg.sh create mode 100644 deprecated/useflag/AUTHORS create mode 100644 deprecated/useflag/ChangeLog create mode 100644 deprecated/useflag/README create mode 100644 deprecated/useflag/useflag create mode 100644 deprecated/useflag/useflag.1 create mode 100644 gentoolkit-dev/AUTHORS create mode 100644 gentoolkit-dev/COPYING create mode 100644 gentoolkit-dev/ChangeLog create mode 100644 gentoolkit-dev/Makefile create mode 100644 gentoolkit-dev/Makefile.skel create mode 100644 gentoolkit-dev/NEWS create mode 100644 gentoolkit-dev/README create mode 100644 gentoolkit-dev/README.Developer create mode 100644 gentoolkit-dev/TODO create mode 100644 gentoolkit-dev/makedefs.mak create mode 100644 gentoolkit-dev/src/ebump/AUTHORS create mode 100644 gentoolkit-dev/src/ebump/ChangeLog create mode 100644 gentoolkit-dev/src/ebump/Makefile create mode 100644 gentoolkit-dev/src/ebump/README create mode 100644 gentoolkit-dev/src/ebump/TODO create mode 100755 gentoolkit-dev/src/ebump/ebump create mode 100644 gentoolkit-dev/src/ebump/ebump.1 create mode 100644 gentoolkit-dev/src/echangelog/AUTHORS create mode 100644 gentoolkit-dev/src/echangelog/ChangeLog create mode 100644 gentoolkit-dev/src/echangelog/Makefile create mode 100644 gentoolkit-dev/src/echangelog/README create mode 100644 gentoolkit-dev/src/echangelog/TODO create mode 100755 gentoolkit-dev/src/echangelog/echangelog create mode 100644 gentoolkit-dev/src/echangelog/echangelog.1 create mode 100644 gentoolkit-dev/src/echangelog/test/TEST.pm create mode 100644 gentoolkit-dev/src/echangelog/test/templates/test.patch create mode 100644 gentoolkit-dev/src/echangelog/test/templates/vcstest-0.0.1.ebuild create mode 100755 gentoolkit-dev/src/echangelog/test/test.sh create mode 100644 gentoolkit-dev/src/ego/AUTHOR create mode 100644 gentoolkit-dev/src/ego/AUTHORS create mode 100644 gentoolkit-dev/src/ego/ChangeLog create mode 100644 gentoolkit-dev/src/ego/Makefile create mode 100644 gentoolkit-dev/src/ego/README create mode 100644 gentoolkit-dev/src/ego/TODO create mode 100644 gentoolkit-dev/src/ego/ego create mode 100644 gentoolkit-dev/src/ekeyword/AUTHORS create mode 100644 gentoolkit-dev/src/ekeyword/ChangeLog create mode 100644 gentoolkit-dev/src/ekeyword/Makefile create mode 100644 gentoolkit-dev/src/ekeyword/README create mode 100644 gentoolkit-dev/src/ekeyword/TODO create mode 100755 gentoolkit-dev/src/ekeyword/ekeyword create mode 100644 gentoolkit-dev/src/ekeyword/ekeyword.pod create mode 100755 gentoolkit-dev/src/ekeyword2/ekeyword2 create mode 100644 gentoolkit-dev/src/eshowkw/Makefile create mode 100644 gentoolkit-dev/src/eshowkw/eshowkw create mode 100644 gentoolkit-dev/src/eshowkw/eshowkw.1 create mode 100644 gentoolkit-dev/src/eviewcvs/AUTHORS create mode 100644 gentoolkit-dev/src/eviewcvs/Makefile create mode 100644 gentoolkit-dev/src/eviewcvs/README create mode 100755 gentoolkit-dev/src/eviewcvs/eviewcvs create mode 100644 gentoolkit-dev/src/eviewcvs/eviewcvs.pod create mode 100644 gentoolkit-dev/src/imlate/Makefile create mode 100755 gentoolkit-dev/src/imlate/imlate create mode 100644 gentoolkit-dev/src/imlate/imlate.1 create mode 100644 gentoolkit/AUTHORS create mode 100644 gentoolkit/COPYING create mode 100644 gentoolkit/CREDITS create mode 100644 gentoolkit/ChangeLog create mode 100644 gentoolkit/DEVELOPING create mode 100644 gentoolkit/MANIFEST.in create mode 100644 gentoolkit/NEWS create mode 100644 gentoolkit/README create mode 100644 gentoolkit/README.dev create mode 100644 gentoolkit/THANKS create mode 100644 gentoolkit/TODO create mode 100755 gentoolkit/bin/eclean create mode 100755 gentoolkit/bin/epkginfo create mode 100755 gentoolkit/bin/equery create mode 100755 gentoolkit/bin/eread create mode 100755 gentoolkit/bin/euse create mode 100755 gentoolkit/bin/glsa-check create mode 100755 gentoolkit/bin/revdep-rebuild create mode 100644 gentoolkit/data/99gentoolkit-env create mode 100644 gentoolkit/data/eclean/distfiles.exclude create mode 100644 gentoolkit/data/eclean/packages.exclude create mode 100644 gentoolkit/data/revdep-rebuild/99revdep-rebuild create mode 100644 gentoolkit/man/eclean.1 create mode 100644 gentoolkit/man/epkginfo.1 create mode 100644 gentoolkit/man/equery.1 create mode 100644 gentoolkit/man/eread.1 create mode 100644 gentoolkit/man/euse.1 create mode 100644 gentoolkit/man/glsa-check.1 create mode 100644 gentoolkit/man/revdep-rebuild.1 create mode 100644 gentoolkit/pylintrc create mode 100644 gentoolkit/pym/gentoolkit/__init__.py create mode 100644 gentoolkit/pym/gentoolkit/atom.py create mode 100644 gentoolkit/pym/gentoolkit/cpv.py create mode 100644 gentoolkit/pym/gentoolkit/dbapi.py create mode 100644 gentoolkit/pym/gentoolkit/dependencies.py create mode 100644 gentoolkit/pym/gentoolkit/deprecated/helpers.py create mode 100644 gentoolkit/pym/gentoolkit/equery/__init__.py create mode 100644 gentoolkit/pym/gentoolkit/equery/belongs.py create mode 100644 gentoolkit/pym/gentoolkit/equery/changes.py create mode 100644 gentoolkit/pym/gentoolkit/equery/check.py create mode 100644 gentoolkit/pym/gentoolkit/equery/depends.py create mode 100644 gentoolkit/pym/gentoolkit/equery/depgraph.py create mode 100644 gentoolkit/pym/gentoolkit/equery/files.py create mode 100644 gentoolkit/pym/gentoolkit/equery/hasuse.py create mode 100644 gentoolkit/pym/gentoolkit/equery/list_.py create mode 100644 gentoolkit/pym/gentoolkit/equery/meta.py create mode 100644 gentoolkit/pym/gentoolkit/equery/size.py create mode 100644 gentoolkit/pym/gentoolkit/equery/uses.py create mode 100644 gentoolkit/pym/gentoolkit/equery/which.py create mode 100644 gentoolkit/pym/gentoolkit/errors.py create mode 100644 gentoolkit/pym/gentoolkit/glsa/__init__.py create mode 100644 gentoolkit/pym/gentoolkit/helpers.py create mode 100644 gentoolkit/pym/gentoolkit/metadata.py create mode 100644 gentoolkit/pym/gentoolkit/package.py create mode 100644 gentoolkit/pym/gentoolkit/pprinter.py create mode 100644 gentoolkit/pym/gentoolkit/query.py create mode 100644 gentoolkit/pym/gentoolkit/test/__init__.py create mode 100644 gentoolkit/pym/gentoolkit/test/equery/__init__.py create mode 100644 gentoolkit/pym/gentoolkit/test/equery/test_init.py create mode 100644 gentoolkit/pym/gentoolkit/test/test_atom.py create mode 100644 gentoolkit/pym/gentoolkit/test/test_cpv.py create mode 100644 gentoolkit/pym/gentoolkit/test/test_helpers.py create mode 100644 gentoolkit/pym/gentoolkit/test/test_syntax.py create mode 100644 gentoolkit/pym/gentoolkit/textwrap_.py create mode 100644 gentoolkit/pym/gentoolkit/versionmatch.py create mode 100755 gentoolkit/setup.py diff --git a/deprecated/change/AUTHORS b/deprecated/change/AUTHORS new file mode 100644 index 0000000..4b3873a --- /dev/null +++ b/deprecated/change/AUTHORS @@ -0,0 +1,5 @@ +Dan Armak + * Basic idea + * Initial version +Karl Trygve Kalleberg + * Gentoolkit-specific changes diff --git a/deprecated/change/ChangeLog b/deprecated/change/ChangeLog new file mode 100644 index 0000000..bd7d5dd --- /dev/null +++ b/deprecated/change/ChangeLog @@ -0,0 +1,7 @@ +2002-08-11 Dan Armak : + * Fix two bugs which are long to describe, so I won't do so here. + They caused malformed or incomplete changelog files to be created. + +2002-08-09 Karl Trygve Kalleberg : + * Reformatted usage to work with 80 columns + * Now loads ~/.gentoo/gentool-env instead of ~/.change diff --git a/deprecated/change/README b/deprecated/change/README new file mode 100644 index 0000000..bda1842 --- /dev/null +++ b/deprecated/change/README @@ -0,0 +1,20 @@ +Package : change +Version : 0.2.4 +Author : See AUTHORS + +MOTIVATION + +Maintaing Gentoo's ChangeLog files in the Portage Tree is a tedious affair. +Many of the details are well-defined enough for a tool to do. change is this +tool. + +MECHANICS + +change can create a ChangeLog, add entries to the ChangeLog file, scan for +updated files. + + +IMPROVEMENTS + +For improvements, send a mail to karltk@gentoo.org or make out a bug at +bugs.gentoo.org and assign it to me. diff --git a/deprecated/change/change b/deprecated/change/change new file mode 100644 index 0000000..094573b --- /dev/null +++ b/deprecated/change/change @@ -0,0 +1,343 @@ +#! /bin/bash + +# Copyright 1999-2002 Gentoo Technologies, Inc. +# Distributed under the terms of the GNU General Public License v2 +# Author: Dan Armak +# $Header: /space/gentoo/cvsroot/gentoolkit/src/change/change,v 1.2 2002/08/11 13:32:12 karltk Exp $ + +eval `grep PORTDIR= /etc/make.globals` +eval `grep PORTDIR= /etc/make.conf` +[ -z "$PORTDIR" ] && PORTDIR="/usr/portage" + +# register temp files (we delete them in the end) +TMPMESSAGE=`tempfile -p change` || cleanup 1 +TMPHEADER=`tempfile -p change` || cleanup 1 +TMPENTRY=`tempfile -p change` || cleanup 1 +TMPOLDLOG=`tempfile -p change` || cleanup 1 +TMPCHANGELOG=`tempfile -p change` || cleanup 1 + +# get user info from config file - $AUTHORNAME and $AUTHOREMAIL +init() { + . ~/.gentoo/gentool-env || return 1 +} + +print_about() { + + echo "change v 0.2.4 - A Gentoo ChangeLog editor." + echo "Author Dan Armak " +} + +print_usage() { + + echo "Usage: +change [-shv] [-m|--message msg] [-f|--message-file file] + [-a|--authorname name] [-l|--authormail mail] + [-n|--new-version ver] [-o|--output dest] + +: List of packages whose changelogs are to be edited. All +changelogs edited in one run will be added the same log message. + +Acceptable formats: Example: +category/package kde-base/kdebase +path to package dir kdebase || ../../kdebase +path to changelog file portage/kde-base/kdebase/ChangeLog + +Note that you must use -g for changelog files outside $PORTDIR. + +-m, --message \"msg\" Use log message \"msg\", do not open editor. +-f, --message-file Use contents of as log message, do not open + editor. +-a, --authorname \"name\" Use \"name\" (e.g. Dan Armak) in log. +-l, --authormail \"email\" Use \"email\" (e.g. danarmak@gentoo.org) in log. +-n, --new-version \"ver\" Add a line about a new version number \"ver\" to + the log. +-g, --generate Create a new changelog file if one does not exist. + This option must come before the list of affected + changelog files. Incidentally, this option also + enables you to work with a changelog file outside + $PORTDIR. + You must use it every time you edit such a file. + However, change won't be able to figure out the + category and package names of your changelog file + and those parts will be missing. (FIXME!) +-o, --output \"file\" Save new changelog in file \"file\". + Default is the the same file we're changing (i.e. + no backup). +-s, --stdout Print new changelog to stdout (disables saving to + file). This suppresses the usual info messages. +-c, --changed-files List of changed files (goes into entry header). + Default is to simply say \"ChangeLog :\". Multiple + -c options can be given. +-h, --help Print this usage information. +-v, --version Print a short about line and the version number and + exit. + +See also the mandatory config file ~/.gentoo/gentool-env (the gentool-env man +page contains a template). +" + +} + +# parse command line parameters +# this function should be called before all others (e.g. before init()) +# or else it might stomp on some settings +parse_params() { + + # at least one parameter required - changelog to process + if [ -z "$1" ]; then + echo "At least one parameter is required." + print_about + print_usage + cleanup 1 + fi + + while [ -n "$1" ]; do + + # note: with parameters that come in two pieces (i.e. -m foo) + # we identify the first one, grab the second one from $2 and + # shift an extra time + case "$1" in + + # optional log message, if defined then we won't launch $EDITOR + # comes in explicit string and file reference variations + -m | --message) + MESSAGE="$2" + shift + ;; + -f | --message-file) + cp $2 $TMPMESSAGE + shift + ;; + + # general settings (usually set in .change) + -a | --authorname) + AUTHORNAME="$2" + shift + ;; + -l | --authormail) + AUTHOREMAIL="$2" + shift + ;; + + # add a line about a new version (starting with *) to the changelog + # to add the line but no changelog info, call with -n -m "" + -n | --new-version) + NEWVERSION="$2" + shift + ;; + + # create a new changelog file + -g | --generate) + GENERATE=true + ;; + + # output redirection. default (if $OUTPUT isn't set) is to change the + # specified changelog file. + # illegal if more than one changelog file/package is specified. + -o | --output) + OUTPUT="$2" + shift + ;; + # redirect output to stdout - can be combined with -o + -s | --stdout) + STDOUT="true" + OUTPUT="/dev/null" + ;; + + # list of files changed (second part inclosed in quotes!) + -c | --changed-files) + CHANGED="$CHANGED $2" + shift + ;; + + # request for version/usage information etc + -h | --help) + print_about + print_usage + cleanup 0 + ;; + -v | --version) + print_about + cleanup 0 + ;; + + # everything else we couldn't identify. most of it is packages/files to work on. + *) + for x in "$MYPORTDIR/$1/ChangeLog" "$PORTDIR/$1/ChangeLog" "$PWD/$1/ChangeLog" "$PWD/$1"; do + if [ -f "$x" ]; then + FILES="$FILES $x" + shift # because by calling continue we skip the shift at the end of the case block + continue 2 # next while iteration + fi + done + # if we haveb't detected a changelog file, maybe we need to create one + if [ -n "$GENERATE" ]; then + for x in "$PWD/$1" "$1" "$MYPORTDIR/$1" "$PORTDIR/$1"; do + if [ -d "$x" ]; then + touch $x/ChangeLog + FILES="$FILES $x/ChangeLog" + shift # because by calling continue we skip the shift at the end of the case block + continue 2 # next while iteration + fi + done + fi + + echo "!!! Error: unrecognized option: $1" + echo + print_usage + cleanup 1 + + ;; + + esac + + shift + done + + if [ -z "$FILES" ]; then + echo "No changelog path or package name passed, mandatory parameter missing." + echo + print_usage + cleanup 1 + fi + +} + +# get the log message +get_msg() { + + if [ -n "`cat $TMPMESSAGE`" ]; then + echo "Using message-on-file." + elif [ -n "$MESSAGE" ]; then + echo "$MESSAGE" > $TMPMESSAGE + else # [ -z "$MESSAGE" ] + + echo > $TMPMESSAGE + echo "Please enter changelog. You can leave this line, it will be automatically removed." >> $TMPMESSAGE + $EDITOR $TMPMESSAGE + cp $TMPMESSAGE ${TMPMESSAGE}2 + sed -e '/Please enter changelog. You can leave this line, it will be automatically removed./ D' \ + ${TMPMESSAGE}2 > $TMPMESSAGE + rm ${TMPMESSAGE}2 + + fi + + # break up into 80-character columns (actually 78 chars because we'll + # add two spaces to every line) + cp $TMPMESSAGE ${TMPMESSAGE}2 + fmt -s -w 78 ${TMPMESSAGE}2 > $TMPMESSAGE + rm ${TMPMESSAGE}2 + + # add two spaces to the beginning of every line of the message. + # do this separately from the sed in the else section above + # because it should be executed for the if and elif sections too. + cp $TMPMESSAGE ${TMPMESSAGE}2 + sed -e 's:^: :g' ${TMPMESSAGE}2 > $TMPMESSAGE + rm ${TMPMESSAGE}2 + +} + +# get list of files and wrap it in the following manner: +# 1 item on the first list and upto 80 chars on every other. +# also adds 2 spaces to the beginning of every line but the first. +wrap_list() { + + echo -n $1 + shift + + while [ -n "$1" ]; do + if [ -n "$LIST" ]; then + LIST="$LIST, $1" + else + echo , + LIST="$1" + fi + shift + done + LIST="$LIST :" + + echo $LIST | fmt -s -w 78 | sed -e 's:^: :g' - + +} + +# do the actual work on te changelog file passed as $1 +process() { + # figure out category and package names + name=${1//${PORTDIR}} + name=${name//${MYPORTDIR}} + name=${name//\/ChangeLog} + + OLDIFS="$IFS" + IFS="/" + for x in $name; do + if [ -z "$CATEGORY" ]; then + CATEGORY="$x" + else + PACKAGE="$x" + fi + done + IFS="$OLDIFS" + + # create header + echo \ +"# ChangeLog for $CATEGORY/$PACKAGE +# Copyright 2002 Gentoo Technologies, Inc.; Distributed under the GPL v2 +# \$Header: \$ +" > $TMPHEADER + + # create entry line + if [ -n "$NEWVERSION" ]; then + echo "*$PACKAGE-$NEWVERSION (`date '+%d %b %Y'`)" > $TMPENTRY + echo >> $TMPENTRY + fi + + echo -n " `date "+%d %b %Y"`; ${AUTHORNAME} <${AUTHOREMAIL}> " >> $TMPENTRY + [ -z "$CHANGED" ] && CHANGED="ChangeLog " + wrap_list $CHANGED >> $TMPENTRY + + echo >> $TMPENTRY + + # get the original changelog, minus the old header + sed -e '/^# ChangeLog for/ D + /^# Copyright 2002 Gentoo Technologies/ D + /^# \$Header:/ D' $1 > $TMPOLDLOG + + # join everything together + cat $TMPHEADER $TMPENTRY $TMPMESSAGE $TMPOLDLOG > $TMPCHANGELOG + + # various output options + if [ -n "$OUTPUT" ]; then + cp $TMPCHANGELOG $OUTPUT + [ -z "$STDOUT" ] && echo "New changelog saved in $OUTPUT." + else + cp $TMPCHANGELOG $1 + [ -z "$STDOUT" ] && echo "Original changelog $1 replaced." + fi + + if [ -n "$STDOUT" ]; then + cat $TMPCHANGELOG + fi + +} + +# pass exit code to this function +cleanup() { + + rm -f $TMPMESSAGE $TMPHEADER $TMPENTRY $TMPCHANGELOG $TMPOLDLOG + + exit $1 + +} + +parse_params "${@}" + +init + +get_msg + +for x in $FILES; do + process $x +done + +cleanup 0 + diff --git a/deprecated/change/change.1 b/deprecated/change/change.1 new file mode 100644 index 0000000..e69de29 diff --git a/deprecated/dep-clean/AUTHORS b/deprecated/dep-clean/AUTHORS new file mode 100644 index 0000000..2fa030f --- /dev/null +++ b/deprecated/dep-clean/AUTHORS @@ -0,0 +1,9 @@ +Maintainer: +Karl Trygve Kalleberg + +Authors: +Karl Trygve Kalleberg (dep-clean, man page) +Jerry Haltom (dep-clean) +Brandon Low (dep-clean) +Paul Belt (man page) +Brandon Low (dep-clean) diff --git a/deprecated/dep-clean/ChangeLog b/deprecated/dep-clean/ChangeLog new file mode 100644 index 0000000..dc6980e --- /dev/null +++ b/deprecated/dep-clean/ChangeLog @@ -0,0 +1,13 @@ + 04 Oct 2003: Karl Trygve Kalleberg dep-clean, dep-clean.1: + * Rewrote to Python + * Uses gentoolkit + * Changed the switches to be proper toggles + + 25 Feb 2003; Brandon Low dep-clean, dep-clean.1: + * Update to work with current everything + * Add -q and change the default behaviour and the verbose behavior + * Make a lot faster by rewriting most everything + * Make script much more readable + * Make pay attention to PORTDIR_OVERLAY + * Bring back from the dead as it give more info + than the depclean action in portage. diff --git a/deprecated/dep-clean/README b/deprecated/dep-clean/README new file mode 100644 index 0000000..6521aef --- /dev/null +++ b/deprecated/dep-clean/README @@ -0,0 +1,4 @@ +See man dep-clean or just run dep-clean --help. + +QuickStart: +dep-clean displays missing, extra, and removed packages on your system. diff --git a/deprecated/dep-clean/dep-clean b/deprecated/dep-clean/dep-clean new file mode 100644 index 0000000..2f2bde0 --- /dev/null +++ b/deprecated/dep-clean/dep-clean @@ -0,0 +1,164 @@ +#!/usr/bin/python +# +# Terminology: +# +# portdir = /usr/portage + /usr/local/portage +# vardir = /var/db/pkg + +import sys +import gentoolkit +try: + from portage.output import * +except ImportError: + from output import * + +__author__ = "Karl Trygve Kalleberg, Brandon Low, Jerry Haltom" +__email__ = "karltk@gentoo.org, lostlogic@gentoo.org, ssrit@larvalstage" +__version__ = "0.2.0" +__productname__ = "dep-clean" +__description__ = "Portage auxiliary dependency checker" + +class Config: + pass + +def defaultConfig(): + Config.displayUnneeded = 1 + Config.displayNeeded = 1 + Config.displayRemoved = 1 + Config.color = -1 + Config.verbosity = 2 + Config.prefixes = { "R" : "", + "U" : "", + "N" : "" } +def asCPVs(pkgs): + return map(lambda x: x.get_cpv(), pkgs) + +def asCPs(pkgs): + return map(lambda x: x.get_cp(), pkgs) + +def toCP(cpvs): + def _(x): + (c,p,v,r) = gentoolkit.split_package_name(x) + return c + "/" + p + return map(_, cpvs) + +def checkDeps(): + if Config.verbosity > 1: + print "Scanning packages, please be patient..." + + unmerged = asCPVs(gentoolkit.find_all_uninstalled_packages()) + unmerged_cp = toCP(unmerged) + + merged = asCPVs(gentoolkit.find_all_installed_packages()) + merged_cp = toCP(merged) + + (system, unres_system) = gentoolkit.find_system_packages() + system = asCPVs(system) + + (world, unres_world) = gentoolkit.find_world_packages() + world = asCPVs(world) + + desired = system + world + + unneeded = filter(lambda x: x not in desired, merged) + needed = filter(lambda x: x not in merged, desired) + old = filter(lambda x: x not in unmerged_cp, merged_cp) + + if len(needed): + print "Packages required, but not by world and system:" + for x in needed: print " " + x + raise "Internal error, please report." + + if len(unres_system) and Config.displayNeeded: + if Config.verbosity > 0: + print white("Packages in system but not installed:") + for x in unres_system: + print " " + Config.prefixes["N"] + red(x) + + if len(unres_world) and Config.displayNeeded: + if Config.verbosity > 0: + print white("Packages in world but not installed:") + for x in unres_world: + print " " + Config.prefixes["N"] + red(x) + + if len(old) and Config.displayRemoved: + if Config.verbosity > 0: + print white("Packages installed, but no longer available:") + for x in old: + print " " + Config.prefixes["R"] + yellow(x) + + if len(unneeded) and Config.displayUnneeded: + if Config.verbosity > 0: + print white("Packages installed, but not required by system or world:") + for x in unneeded: + print " " + Config.prefixes["U"] + green(x) + +def main(): + + defaultConfig() + + for x in sys.argv: + if 0: + pass + elif x in ["-h","--help"]: + printUsage() + sys.exit(0) + elif x in ["-V","--version"]: + printVersion() + sys.exit(0) + + elif x in ["-n","--needed","--needed=yes"]: + Config.displayNeeded = 1 + elif x in ["-N","--needed=no"]: + Config.displayNeeded = 0 + + elif x in ["-u","--unneeded","--unneeded=yes"]: + Config.displayUnneeded = 1 + elif x in ["-U","--unneeded=no"]: + Config.displayUnneeded = 0 + + elif x in ["-r","--removed","--removed=yes"]: + Config.displayRemoved = 1 + elif x in ["-R","--removed","--removed=no"]: + Config.displayRemoved = 0 + elif x in ["-c","--color=yes"]: + Config.color = 1 + elif x in ["-C","--color=no"]: + Config.color = 0 + + elif x in ["-v", "--verbose"]: + Config.verbosity += 1 + elif x in ["-q", "--quiet"]: + Config.verbosity = 0 + + # Set up colour output correctly + if (Config.color == -1 and \ + ((not sys.stdout.isatty()) or \ + (gentoolkit.settings["NOCOLOR"] in ["yes","true"]))) \ + or \ + Config.color == 0: + nocolor() + Config.prefixes = { "R": "R ", "N": "N ", "U": "U " } + + checkDeps() + +def printVersion(): + print __productname__ + "(" + __version__ + ") - " + \ + __description__ + print "Authors: " + __author__ + +def printUsage(): + print white("Usage: ") + turquoise(__productname__) + \ + " [" + turquoise("options") + "]" + print "Where " + turquoise("options") + " is one of:" + print white("Display:") + print " -N,--needed needed packages that are not installed." + print " -R,--removed installed packages not in portage." + print " -U,--unneeded potentially unneeded packages that are installed." + print white("Other:") + print " -C,--nocolor output without color. Categories will be denoted by P,N,U." + print " -h,--help print this help" + print " -v,--version print version information" + +if __name__ == "__main__": + main() diff --git a/deprecated/dep-clean/dep-clean.1 b/deprecated/dep-clean/dep-clean.1 new file mode 100644 index 0000000..9e42019 --- /dev/null +++ b/deprecated/dep-clean/dep-clean.1 @@ -0,0 +1,194 @@ +.\" Automatically generated by Pod::Man version 1.15 +.\" Thu Jul 18 15:59:55 2002 +.\" +.\" Standard preamble: +.\" ====================================================================== +.de Sh \" Subsection heading +.br +.if t .Sp +.ne 5 +.PP +\fB\\$1\fR +.PP +.. +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Ip \" List item +.br +.ie \\n(.$>=3 .ne \\$3 +.el .ne 3 +.IP "\\$1" \\$2 +.. +.de Vb \" Begin verbatim text +.ft CW +.nf +.ne \\$1 +.. +.de Ve \" End verbatim text +.ft R + +.fi +.. +.\" Set up some character translations and predefined strings. \*(-- will +.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +.\" double quote, and \*(R" will give a right double quote. | will give a +.\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used +.\" to do unbreakable dashes and therefore won't be available. \*(C` and +.\" \*(C' expand to `' in nroff, nothing in troff, for use with C<> +.tr \(*W-|\(bv\*(Tr +.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +.ie n \{\ +. ds -- \(*W- +. ds PI pi +. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +. ds L" "" +. ds R" "" +. ds C` "" +. ds C' "" +'br\} +.el\{\ +. ds -- \|\(em\| +. ds PI \(*p +. ds L" `` +. ds R" '' +'br\} +.\" +.\" If the F register is turned on, we'll generate index entries on stderr +.\" for titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and +.\" index entries marked with X<> in POD. Of course, you'll have to process +.\" the output yourself in some meaningful fashion. +.if \nF \{\ +. de IX +. tm Index:\\$1\t\\n%\t"\\$2" +.. +. nr % 0 +. rr F +.\} +.\" +.\" For nroff, turn off justification. Always turn off hyphenation; it +.\" makes way too many mistakes in technical documents. +.hy 0 +.if n .na +.\" +.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +.\" Fear. Run. Save yourself. No user-serviceable parts. +.bd B 3 +. \" fudge factors for nroff and troff +.if n \{\ +. ds #H 0 +. ds #V .8m +. ds #F .3m +. ds #[ \f1 +. ds #] \fP +.\} +.if t \{\ +. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +. ds #V .6m +. ds #F 0 +. ds #[ \& +. ds #] \& +.\} +. \" simple accents for nroff and troff +.if n \{\ +. ds ' \& +. ds ` \& +. ds ^ \& +. ds , \& +. ds ~ ~ +. ds / +.\} +.if t \{\ +. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +.\} +. \" troff and (daisy-wheel) nroff accents +.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +.ds ae a\h'-(\w'a'u*4/10)'e +.ds Ae A\h'-(\w'A'u*4/10)'E +. \" corrections for vroff +.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +. \" for low resolution devices (crt and lpr) +.if \n(.H>23 .if \n(.V>19 \ +\{\ +. ds : e +. ds 8 ss +. ds o a +. ds d- d\h'-1'\(ga +. ds D- D\h'-1'\(hy +. ds th \o'bp' +. ds Th \o'LP' +. ds ae ae +. ds Ae AE +.\} +.rm #[ #] #H #V #F C +.\" ====================================================================== +.\" +.IX Title "DEP-CLEAN 1" +.TH DEP-CLEAN 1 "Copyright 2002 Gentoo Technologies, Inc." "2002-07-18" "GenToolKit's Dependency Checker!" +.UC +.SH "NAME" +dep-clean \- Shows unrequired packages and missing dependencies. +.SH "SYNOPSIS" +.IX Header "SYNOPSIS" +.Vb 1 +\& dep-clean [-RUNICv] +.Ve +.SH "DESCRIPTION" +.IX Header "DESCRIPTION" +dep-clean displays extraneous, missing or extra packages. Extra packages are those in which are not a part of the portage tree (/usr/portage). It does \s-1NOT\s0 modify the system in any way. +.SH "OPTIONS" +.IX Header "OPTIONS" +.Ip "\-n, \-\-needed" 4 +.Ip "\-N, \-\-needed=no" 4 +.IX Item "-n, --needed" +Toggle display of needed packages that are not installed. (red) (default=yes) +.Ip "\-r, \-\-removed" 4 +.Ip "\-R, \-\-removed=no" 4 +.IX Item "-R, --removed" +Toggle display of installed packages not in portage. (yellow) (default=yes) +.Ip "\-u, \-\-unneeded" 4 +.Ip "\-U, \-\-unneeded=no" 4 +.IX Item "-U, --unneeded" +Toggle display of unneeded packages that are installed. (green) (default=yes) +.Ip "\-c, \-\-color" 4 +.Ip "\-C, \-\-color=no" 4 +.IX Item "-c, --color" +Toggle output of color. Without color, package types will be noted with R, U and N. +Default is use whatever Portage is set for. +.Ip "\-v, \-\-verbose" 4 +.IX Item "-v, --verbose" +Be more verbose. +.Ip "\-q, \-\-quiet" 4 +.IX Item "-q, --quiet" +Be quiet (display only packages). +.SH "NOTES" +.IX Header "NOTES" +.Ip "" 4 +If this script is run on a system that is not up-to-date or which hasn't been cleaned (with 'emerge \-c') recently, the output may be deceptive. +.Ip "" 4 +If the same package name appears in all three categories, then it is definitely time to update that package and then run 'emerge \-c'. +.Ip "" 4 +The \-U, \-N and \-R options may be combined, default is \-UNR +.SH "AUTHORS" +.IX Header "AUTHORS" +Jerry Haltom (dep-clean) +.br +Brandon Low (dep-clean) +.PP +Paul Belt (man page) +.br +Karl Trygve Kalleberg (dep-clean, man page) diff --git a/deprecated/dev-scripts/README b/deprecated/dev-scripts/README new file mode 100644 index 0000000..990a2ab --- /dev/null +++ b/deprecated/dev-scripts/README @@ -0,0 +1,2 @@ +This directory is intended to be used for small developer oriented scripts used in gentoolkit-dev. +If a script develops into a full fledged tool, it will be moved into its own subdirectory. diff --git a/deprecated/dev-scripts/included_headers.sh b/deprecated/dev-scripts/included_headers.sh new file mode 100755 index 0000000..915628b --- /dev/null +++ b/deprecated/dev-scripts/included_headers.sh @@ -0,0 +1,159 @@ +#!/bin/bash + +# CHANGES +# +# 20051211: Add qfile use from portage-utils, prefer over equery. Create new +# function track_headers() to handle package manager queries for both +# relative and absolute headers. Split relative and absolute queries into two +# separate places, since relative aren't quite as reliable. Prefer headers +# found in the tarball over those in /usr/include. Also, note which headers +# weren't considered in the calculation and the reasons why not. + +location=${1} + +usage() { + echo "${0##*/} [ -d ] source_location" + echo " Returns owners of all include files used. ${0##*/} defaults to" + echo " files in /usr/include, so if a file with the same name within the" + echo " source is the actual one used, false dependencies may be printed." + echo + echo " -d" + echo " Show debug output: Print files not found" + exit 1 +} + +decho() { + if [[ -n "${DEBUG}" ]]; then + echo "${1}" + fi +} + +if [[ $# -le 0 ]] || [[ $# -ge 3 ]]; then + usage +fi + +# Handle command-line options +while getopts d options; do + case ${options} in + d) DEBUG=1 + ;; + *) usage + ;; + esac +done +# Reset post-option stuff to positional parameters +shift $((OPTIND - 1)) + +get_absolute_includes() { + grep '^#[[:space:]]*include' -r ${1} | grep '.*.[ch]' | grep -e '<' -e '>' \ + | cut -d':' -f2 | cut -d'<' -f2 | cut -d'>' -f1 | grep '.*.[ch]' \ + | sort | uniq +} + +get_relative_includes() { + grep '^#[[:space:]]*include' -r ${1} | grep '.*.[ch]' | grep -e '"' -e '"' \ + | cut -d':' -f2 | cut -d'"' -f2 | cut -d'"' -f1 | grep '.*.[ch]' \ + | sort | uniq +} + +track_headers() { + if [[ -x $(which qfile 2> /dev/null) ]]; then + qfile ${@} | cut -d'(' -f1 | sort | uniq + elif [[ -x $(which equery 2> /dev/null) ]]; then + equery -q belongs ${@} | cut -d'(' -f1 + elif [[ -x $(which rpm 2> /dev/null) ]]; then + rpm -qf ${@} + else + echo "Couldn't find package query tool! Printing headerpaths instead." + echo + for header in ${@}; do + echo ${header} + done + fi +} + +echo "Analyzing source ... " +absolute_headers="$(get_absolute_includes ${1})" +relative_headers="$(get_relative_includes ${1})" + +echo "Looking for absolute headers ... " +echo +for header in ${absolute_headers}; do + absheader="/usr/include/${header}" + if [[ -e ${absheader} ]]; then + abs_headerpaths="${abs_headerpaths} ${absheader}" + echo " Looking for ${absheader} ... OK" + else + # Try as a relative header in case people use -I with <> + relative_headers="${relative_headers} ${header}" + decho " Looking for ${absheader} ... Not found!" + fi +done + +echo +echo "Looking for relative headers ... " +echo +for header in ${relative_headers}; do + fullheader=${header} + header=${header##*/} + # Prefer headers in tarball over /usr/include + header_options=$(find ${location} -name ${header} | grep ${fullheader}) + if [[ -z ${header_options} ]]; then + header_options="$(find /usr/include -name ${header} | grep ${fullheader})" + header_loc="/usr/include" + else + decho " Local header ${header} ... Not considering." + local_headers="${local_headers} ${header}" + continue + fi + count="0" + for found in ${header_options}; do + (( count++ )) + done + if [[ ${count} -ge 2 ]]; then + echo " Looking for ${header} ... " + echo " More than one option found for ${header} in ${header_loc}." + echo " Not considering ${header}." + duplicate_headers="${duplicate_headers} ${header}" + continue + elif [[ ${count} -le 0 ]]; then + decho " Looking for ${header} ... Not found!" + unfound_headers="${unfound_headers} ${header}" + continue + fi + header=${header_options} + if [[ -e ${header} ]] && [[ ${header_loc} = /usr/include ]]; then + rel_headerpaths="${rel_headerpaths} ${header}" + echo " Looking for ${header} ... OK" + else + decho " Looking for ${header} ... Not found!" + fi +done + +echo "Tracing headers back to packages ..." +echo +echo "Headers ignored because they exist in the tarball:" +echo +for header in ${local_headers}; do + echo "${header}" +done +echo +echo "Headers ignored because of duplicates in /usr/include:" +echo +for header in ${duplicate_headers}; do + echo "${header}" +done +echo +echo "Headers ignored because they weren't found:" +echo +for header in ${unfound_headers}; do + echo "${header}" +done +echo +echo "Absolute headers:" +echo +track_headers ${abs_headerpaths} +echo +echo "Relative headers:" +echo +track_headers ${rel_headerpaths} diff --git a/deprecated/dev-scripts/linking_libs.sh b/deprecated/dev-scripts/linking_libs.sh new file mode 100755 index 0000000..a249305 --- /dev/null +++ b/deprecated/dev-scripts/linking_libs.sh @@ -0,0 +1,204 @@ +#!/bin/bash + +# CHANGES +# +# 20051211: Move most of the logic to check for bad links into get_libnames() +# seds, so we don't wrongly sed out whole link lines. Seems to catch more +# problems, such as ' or ` or -- in a link. +# 20051210: Prefer qfile from portage-utils over equery if it's available. +# Check for ... in "link" lines because configure checks are not links. +# Change get_link_generic() to handle whole lines at a time instead of single +# words, so get_linklines() works. +# 20051210: Rework get_libnames() to use a new style of grep, because the old +# way was broken on some packages from the \b. Also optimize the "Looking for +# libraries" section to only grep the log file once for links and cache it; +# also only grep the link lines ones for a given library, then parse the +# output for static or shared. Should speed things up considerably for large +# packages. I get 5 seconds in Analyzing log and 15 in Looking for libs on an +# xorg-x11-6.8.99.15 log on second run. +# Create get_link_generic() that both sections call with different options. + +usage() { + echo "${0##*/} compilation_log" + echo " Checks for -lfoo link commands and finds the library owners." + exit 1 +} + +if [[ $# -lt 1 || $1 == -h || $1 == --help ]]; then + usage +fi + + +# Finds all lines in a file that involve linking +# get_link_generic(char *grep_opts, char *filename) +get_link_generic() { + egrep ${1} '\-l\w[^[:space:]]*' ${2} \ + | while read linker; do + # -linker is passed through to ld and doesn't mean the inker lib. + # The new -w in grep makes sure they're separate "words", but its + # "word" characters only include alnum and underscore, so -- gets + # through. + # Some configure lines with ... match, so we drop them + # Some of the configure options match, so we get rid of = for that. + if \ + [[ "${linker}" != *...* ]] \ + && [[ "${linker}" != -lib ]] \ + && [[ "${linker}" != -libs ]]; then + echo ${linker} + fi + done +} + +# Note the lack of -o, as compared to get_libnames() egrep +get_linklines() { + get_link_generic "-w" ${1} | sort | uniq +} + +get_libnames() { + for x; do + get_link_generic "-o -w" ${x} \ + | sed \ + -e "/^-link/d" \ + -e "/^-lib/d" \ + -e "s:^-l::g" \ + -e "/=/d" \ + -e "/'/d" \ + -e "/^-/d" \ + -e "s:\.*$::g" \ + -e "s:|::g" \ + -e "s:\"::g" \ + -e "/^-link/d" \ + -e "/^-lib/d" + done | sort | uniq +} + +get_libdirs() { + cat /etc/ld.so.conf | sed -e "/^#/d" +} + +check_exists() { + if [[ -n ${1// } ]]; then + return 0 + fi + + return 1 +} + +trace_to_packages() { + local paths=$1 + + check_exists "${paths}" + local ret=$? + if [[ $ret -ne 0 ]]; then + return 1 + fi + + if [[ -x $(which qfile 2> /dev/null) ]]; then + qfile -q ${paths} | sort | uniq + elif [[ -x $(which equery 2> /dev/null) ]]; then + equery -q belongs ${paths} | cut -d'(' -f1 + elif [[ -x $(which rpm 2> /dev/null) ]]; then + rpm -qf ${paths} + else + echo "Couldn't find package query tool! Printing paths instead." + echo + for path in ${paths}; do + echo ${path} + done + fi +} + +# *64 needs to be first, as *lib is a symlink to it so equery screws up +libdirs="/lib64 /usr/lib64 /lib /usr/lib $(get_libdirs)" + +echo "Analyzing log ..." +libnames=$(get_libnames "$@") + +#echo libnames=$libnames + +echo "Looking for libraries ..." +linker_lines=$(get_linklines ${1}) + +#echo linker_lines=$linker_lines + +for libname in ${libnames}; do + static=0 + shared=0 + line=$(echo ${linker_lines} | grep "\b-l${libname}\b") + if echo ${line} | grep -q '\b-static\b'; then + static=1 + fi + if ! echo ${line} | grep -q '\b-static\b'; then + shared=1 + fi + staticlibname="lib${libname}.a" + sharedlibname="lib${libname}.so" + if [[ ${static} -eq 1 ]]; then + echo -n " Looking for ${staticlibname} ... " + for libdir in ${libdirs}; do + found=0 + if [[ -e ${libdir}/${staticlibname} ]]; then + libpaths="${libpaths} ${libdir}/${staticlibname}" + found=1 + echo "OK" + break + fi + done + if [[ ${found} -ne 1 ]]; then + echo "Not found!" + fi + fi + if [[ ${shared} -eq 1 ]]; then + echo -n " Looking for ${sharedlibname} ... " + for libdir in ${libdirs}; do + found=0 + if [[ -e ${libdir}/${sharedlibname} ]]; then + libpaths="${libpaths} ${libdir}/${sharedlibname}" + found=1 + echo "OK" + break + fi + done + if [[ ${found} -ne 1 ]]; then + echo "Not found!" + fi + fi +done + +# Add backslashes in front of any + symbols +libpaths=${libpaths//+/\\+} + +echo "Looking for build tools (imake, etc) ..." +BUILD_PKGS=$(egrep -h "$@" \ + -e '^(/usr/(X11R6/)?bin/)?rman' \ + -e '^(/usr/(X11R6/)?bin/)?gccmakedep' \ + -e '^(/usr/(X11R6/)?bin/)?makedepend' \ + -e '^(/usr/(X11R6/)?bin/)?imake' \ + -e '^(/usr/(X11R6/)?bin/)?rman' \ + -e '^(/usr/(X11R6/)?bin/)?lndir' \ + -e '^(/usr/(X11R6/)?bin/)?xmkmf' \ + | awk '{ print $1 }' \ + | sort \ + | uniq) + +for PKG in ${BUILD_PKGS}; do + PKG=$(basename ${PKG}) + echo -n " Looking for ${PKG} ... " + if [[ -e /usr/bin/${PKG} ]]; then + echo "OK" + buildpaths="${buildpaths} ${PKG}" + else + echo "Not found!" + fi +done + +echo +echo "Tracing libraries back to packages ..." +echo +trace_to_packages "${libpaths}" + +echo +echo "Tracing build tools back to packages ..." +echo + +trace_to_packages "${buildpaths}" diff --git a/deprecated/distfiles-clean/AUTHORS b/deprecated/distfiles-clean/AUTHORS new file mode 100644 index 0000000..d913891 --- /dev/null +++ b/deprecated/distfiles-clean/AUTHORS @@ -0,0 +1,6 @@ +José Fonseca + * Wrote the script + +Karl Trygve Kalleberg + * Wrote the man page. + diff --git a/deprecated/distfiles-clean/ChangeLog b/deprecated/distfiles-clean/ChangeLog new file mode 100644 index 0000000..dfe6aa8 --- /dev/null +++ b/deprecated/distfiles-clean/ChangeLog @@ -0,0 +1,2 @@ +2002-15-11: Karl Trygve Kalleberg + * Imported newest contributions from #10647. diff --git a/deprecated/distfiles-clean/TODO b/deprecated/distfiles-clean/TODO new file mode 100644 index 0000000..e69de29 diff --git a/deprecated/distfiles-clean/distfiles-clean b/deprecated/distfiles-clean/distfiles-clean new file mode 100644 index 0000000..23af32b --- /dev/null +++ b/deprecated/distfiles-clean/distfiles-clean @@ -0,0 +1,78 @@ +#!/bin/sh +# +# distfiles-clean +# +# Cleans unused files from Portage's distfiles directory. +# +# José Fonseca + +PROGRAM=`basename "$0"` + +while [ ${#} -gt 0 ] +do + case "$1" in + -h|--help) + USAGE=y + break + ;; + -i|--ignore) + IGNORE="$IGNORE $2" + shift 2 + ;; + -I|--ignore-file) + IGNORE="$IGNORE `cat "$2"`" + shift 2 + ;; + -p|--pretend) + PRETEND=y + shift + ;; + *) + echo "$PROGRAM: Invalid option \'$1\'" 1>&2 + USAGE=y + break + ;; + esac +done + +# For PORTDIR and DISTDIR +. /etc/make.globals +. /etc/make.conf + +if [ "$USAGE" ] +then + echo "Usage: $PROGRAM [-h|--help] [-i|--ignore ] [-I|--ignore-file ] [-p|--pretend]" + echo "Cleans unused files from $DISTDIR directory." + exit +fi + +DBDIR=/var/db/pkg +CACHEDIR=/var/cache/edb/dep + +for DIR in "$PORTDIR" "$DISTDIR" "$DBDIR" "$CACHEDIR" +do + if [ ! -d "$DIR" ] + then + echo "$PROGRAM: \'$DIR\' not found." + exit + fi +done + +TMPFILE=`mktemp /tmp/$PROGRAM.XXXXXX` + +cd "$DISTDIR" + +{ + echo "cvs-src" + [ "$IGNORE" ] && ls -1d $IGNORE + find "$DBDIR" -name '*.ebuild' | sed -n -e "s:^$DBDIR/\([^/]*\)/\([^/]*\)/\([^/]*\)\.ebuild$:$CACHEDIR/\1/\3:p" | xargs sed -s -e '4!d;/^$/d;s/[[:alnum:]]\+?\|(\|)//g;s/\<[^[:space:]]\+\/\ "$TMPFILE" && ls -1 | comm -23 - "$TMPFILE" | { + if [ "$PRETEND" ] + then + cat + else + xargs rm -f + fi +} + +rm "$TMPFILE" diff --git a/deprecated/epkginfo/AUTHORS b/deprecated/epkginfo/AUTHORS new file mode 100644 index 0000000..f499856 --- /dev/null +++ b/deprecated/epkginfo/AUTHORS @@ -0,0 +1,3 @@ +Author: Ned Ludd (glue all the parts together) +Author: Eldad Zack (earch) +Author : Eric Olinger (metadata) diff --git a/deprecated/epkginfo/README b/deprecated/epkginfo/README new file mode 100644 index 0000000..f0e3656 --- /dev/null +++ b/deprecated/epkginfo/README @@ -0,0 +1 @@ +epkginfo is now a an alias for equery meta. This is the original version that was written by solar. diff --git a/deprecated/epkginfo/epkginfo b/deprecated/epkginfo/epkginfo new file mode 100755 index 0000000..fd59e4b --- /dev/null +++ b/deprecated/epkginfo/epkginfo @@ -0,0 +1,244 @@ +#!/usr/bin/python +############################################################################## +# $Header: $ +############################################################################## +# Distributed under the terms of the GNU General Public License, v2 or later +# Author: Ned Ludd (glue all the parts together) +# Author: Eldad Zack (earch) +# Author : Eric Olinger (metadata) + +# Gentoo metadata xml and arch keyword checking tool. + +import os +import sys +import re +from stat import * +from xml.sax import saxutils, make_parser, handler +from xml.sax.handler import feature_namespaces + +import portage +from portage.output import * + +__version__ = "svn" + +def earch(workdir): + """Prints arch keywords for a given dir""" + portdir = portage.settings["PORTDIR"] + #workdir = "." + os.chdir(workdir) + + archdict = {} + ebuildlist = [] + for file in os.listdir(workdir): + if re.search("\.ebuild$",file): + ebuildlist.append(re.split("\.ebuild$",file)[0]) + + ebuildlist.sort(lambda x,y: portage.pkgcmp(portage.pkgsplit(x),portage.pkgsplit(y))) + + slot_list = [] + + for pkg in ebuildlist: + portdb = portage.portdbapi(portdir) + aux = portdb.aux_get(workdir.rsplit("/")[-2] + "/" + pkg, ['SLOT', 'KEYWORDS']) + + slot = aux[0] + keywords = keywords = re.split(' ',aux[1]) + + if not slot in slot_list: + slot_list.append(slot) + + for arch in keywords: + if arch in archdict: + archdict[arch].append((pkg, slot)) + else: + archdict[arch] = [ (pkg, slot) ] + + archlist = archdict.keys(); + archlist.sort() + + slot_list.sort() + + for slot in slot_list: + visible_stable = {} + visible_unstable = {} + + for arch in archlist: + visible_stable[arch] = None + visible_unstable[arch] = None + + for pkg in ebuildlist: + for arch in archlist: + if (arch and (pkg, slot) in archdict[arch]): + if arch[0] == "-": + pass + elif "~" == arch[0]: + visible_unstable[arch] = pkg + else: + visible_unstable["~" + arch] = None + visible_stable[arch] = pkg + + for pkg in ebuildlist: + found = False + for arch in archlist: + if (pkg, slot) in archdict[arch]: + found = True + + if not found: + continue + + if not pkg == ebuildlist[0]: + print "" + + print darkgreen("Keywords: ") + pkg + "[" + slot + "]:", + + for arch in archlist: + if (arch and (pkg, slot) in archdict[arch]): + if arch[0] == "-": + print red(arch), + elif "~" == arch[0]: + if visible_unstable[arch] == pkg: + print blue(arch), + else: + if visible_stable[arch] == pkg: + print green(arch), + + +class Metadata_XML(handler.ContentHandler): + _inside_herd="No" + _inside_maintainer="No" + _inside_email="No" + _inside_longdescription="No" + + _herd = [] + _maintainers = [] + _longdescription = "" + + def startElement(self, tag, attr): + if tag == "herd": + self._inside_herd="Yes" + if tag == "longdescription": + self._inside_longdescription="Yes" + if tag == "maintainer": + self._inside_maintainer="Yes" + if tag == "email": + self._inside_email="Yes" + + def endElement(self, tag): + if tag == "herd": + self._inside_herd="No" + if tag == "longdescription": + self._inside_longdescription="No" + if tag == "maintainer": + self._inside_maintainer="No" + if tag == "email": + self._inside_email="No" + + def characters(self, contents): + if self._inside_herd == "Yes": + self._herd.append(contents) + + if self._inside_longdescription == "Yes": + self._longdescription = contents + + if self._inside_maintainer=="Yes" and self._inside_email=="Yes": + self._maintainers.append(contents) + + +def check_metadata(full_package): + """Checks that the primary maintainer is still an active dev and list the herd the package belongs to""" + metadata_file=portage.settings["PORTDIR"] + "/" + portage.pkgsplit(full_package)[0] + "/metadata.xml" + if not os.path.exists(metadata_file): + print darkgreen("Maintainer: ") + red("Error (Missing metadata.xml)") + return 1 + + parser = make_parser() + handler = Metadata_XML() + handler._maintainers = [] + parser.setContentHandler(handler) + parser.parse( metadata_file ) + + if handler._herd: + herds = ", ".join(handler._herd) + print darkgreen("Herd: ") + herds + else: + print darkgreen("Herd: ") + red("Error (No Herd)") + return 1 + + + if handler._maintainers: + print darkgreen("Maintainer: ") + ", ".join(handler._maintainers) + else: + print darkgreen("Maintainer: ") + "none" + + if len(handler._longdescription) > 1: + print darkgreen("Description: ") + handler._longdescription + print darkgreen("Location: ") + os.path.normpath(portage.settings["PORTDIR"] + "/" + portage.pkgsplit(full_package)[0]) + + +def usage(code): + """Prints the uage information for this script""" + print green("epkginfo"), "(%s)" % __version__ + print + print "Usage: epkginfo [package-cat/]package" + sys.exit(code) + + +# default color setup +if ( not sys.stdout.isatty() ) or ( portage.settings["NOCOLOR"] in ["yes","true"] ): + nocolor() + +def fc(x,y): + return cmp(y[0], x[0]) + + +def grab_changelog_devs(catpkg): + try: + os.chdir(portage.settings["PORTDIR"] + "/" + catpkg) + foo="" + r=re.compile("<[^@]+@gentoo.org>", re.I) + s="\n".join(portage.grabfile("ChangeLog")) + d={} + for x in r.findall(s): + if x not in d: + d[x] = 0 + d[x] += 1 + + l=[(d[x], x) for x in d.keys()] + #l.sort(lambda x,y: cmp(y[0], x[0])) + l.sort(fc) + for x in l: + p = str(x[0]) +" "+ x[1].lstrip("<").rstrip(">") + foo += p[:p.find("@")]+", " + return foo + except: + raise + +def main (): + if len( sys.argv ) < 2: + usage(1) + + for pkg in sys.argv[1:]: + + if sys.argv[1:][:1] == "-": + print "NOT WORKING?=="+sys.argv[1:] + continue + + try: + package_list = portage.portdb.xmatch("match-all", pkg) + if package_list: + + catpkg = portage.pkgsplit(package_list[0])[0] + + print darkgreen("Package: ") + catpkg + check_metadata(package_list[0]) + earch(portage.settings["PORTDIR"] + "/" + catpkg) + #print darkgreen("ChangeLog: ") + grab_changelog_devs(catpkg) + print "" + else: + print "!!! No package '%s'" % pkg + except: + print red("Error: "+pkg+"\n") + + +if __name__ == '__main__': + main() diff --git a/deprecated/epkginfo/epkginfo.1 b/deprecated/epkginfo/epkginfo.1 new file mode 100644 index 0000000..cefe602 --- /dev/null +++ b/deprecated/epkginfo/epkginfo.1 @@ -0,0 +1,34 @@ +.TH "epkginfo" "1" "0.4.1" "Ned Ludd" "gentoolkit" +.SH "NAME" +.LP +epkginfo \- Displays metadata information from packages in portage +.SH "SYNTAX" +.LP +epkginfo [\fIpackage\-cat/\fP]package +.SH "EXAMPLES" +$ epkginfo app\-portage/gentoolkit +.br +\fBPackage:\fR app\-portage/gentoolkit +.br +\fBHerd:\fR tools\-portage +.br +\fBMaintainer:\fR tools\-portage +.br +\fBLocation:\fR /usr/portage/app\-portage/gentoolkit +.br +\fBKeywords:\fR gentoolkit\-0.2.2: +.br +\fBKeywords:\fR gentoolkit\-0.2.3: mips +.br +\fBKeywords:\fR gentoolkit\-0.2.3\-r1: ppc ppc64 alpha arm s390 amd64 hppa x86 sparc ia64 m68k sh +.br +\fBKeywords:\fR gentoolkit\-0.2.4_pre3: +.br +\fBKeywords:\fR gentoolkit\-0.2.4_pre4: +.br +\fBKeywords:\fR gentoolkit\-0.2.4_pre5: ~arm ~hppa ~x86 ~m68k ~amd64 ~ppc ~sh ~x86\-fbsd ~ia64 ~alpha ~sparc ~ppc64 ~sparc\-fbsd ~mips ~s390 +.SH "AUTHORS" +.LP +Ned Ludd +.SH "BUGS" +Please report any bugs to http://bugs.gentoo.org diff --git a/deprecated/epkgmove/AUTHORS b/deprecated/epkgmove/AUTHORS new file mode 100644 index 0000000..38fdca1 --- /dev/null +++ b/deprecated/epkgmove/AUTHORS @@ -0,0 +1,2 @@ +Maintainer: +Ian Leitch diff --git a/deprecated/epkgmove/ChangeLog b/deprecated/epkgmove/ChangeLog new file mode 100644 index 0000000..6bfb8d7 --- /dev/null +++ b/deprecated/epkgmove/ChangeLog @@ -0,0 +1,20 @@ +2004-02-03 Karl Trygve Kalleberg + * Updated epkgmove to 1.3.1, as availble on + http://dev.gentoo.org/~port001/DevTools/epkgmove/epkgmove-1.3.1.py + +2004-09-27 Karl Trygve Kalleberg + * Updated epkgmove to 1.1, as availble on + http://dev.gentoo.org/~port001/DevTools/epkgmove/epkgmove-1.1.py + +2004-09-10 Karl Trygve Kalleberg + * Updated epkgmove to 1.0, as availble on + http://dev.gentoo.org/~port001/DevTools/epkgmove/epkgmove-1.0.py + +2004-07-21 Karl Trygve Kalleberg + * Updated epkgmove to 0.5, as availble on + http://dev.gentoo.org/~port001/DevTools/epkgmove/epkgmove-0.5.py + +2004-04-02 Karl Trygve Kalleberg + * Updated epkgmove to 0.4, as availble on + http://dev.gentoo.org/~port001/DevTools/epkgmove/epkgmove-0.4.py + diff --git a/deprecated/epkgmove/Makefile b/deprecated/epkgmove/Makefile new file mode 100644 index 0000000..ce9b950 --- /dev/null +++ b/deprecated/epkgmove/Makefile @@ -0,0 +1,20 @@ +# Copyright 2004 Karl Trygve Kalleberg +# Copyright 2004 Gentoo Technologies, Inc. +# Distributed under the terms of the GNU General Public License v2 +# +# $Header$ + +include ../../makedefs.mak + +.PHONY: all +all: + +dist: + mkdir -p ../../$(distdir)/src/epkgmove/ + cp Makefile AUTHORS README TODO ChangeLog epkgmove ../../$(distdir)/src/epkgmove/ + +install: all + install -m 0755 epkgmove $(bindir)/ + install -d $(docdir)/epkgmove + install -m 0644 AUTHORS README TODO ChangeLog $(docdir)/epkgmove/ +# install -m 0644 epkgmove.1 $(mandir)/ diff --git a/deprecated/epkgmove/README b/deprecated/epkgmove/README new file mode 100644 index 0000000..4668fa3 --- /dev/null +++ b/deprecated/epkgmove/README @@ -0,0 +1,16 @@ + +Package : epkgmove +Version : 0.5 +Author : See AUTHORS + +MOTIVATION + +Eases moving around ebuilds in the Portage CVS tree. + +MECHANICS + +N/A + +IMPROVEMENTS + +N/A diff --git a/deprecated/epkgmove/TODO b/deprecated/epkgmove/TODO new file mode 100644 index 0000000..e69de29 diff --git a/deprecated/epkgmove/epkgmove b/deprecated/epkgmove/epkgmove new file mode 100644 index 0000000..42b6e7d --- /dev/null +++ b/deprecated/epkgmove/epkgmove @@ -0,0 +1,895 @@ +#!/usr/bin/python -O +# Copyright 2004 Ian Leitch +# Copyright 1999-2004 Gentoo Foundation +# $Header$ +# +# Author: +# Ian Leitch +# + +import os +import re +import sys +import signal +import commands +from time import sleep +from random import randint +from optparse import OptionParser + +import portage +try: + from portage.output import * +except ImportError: + from output import * + +__author__ = "Ian Leitch" +__email__ = "port001@gentoo.org" +__productname__ = "epkgmove" +__version__ = "1.3.1 - \"Moving Fusion + Bandages + Plasters\"" +__description__ = "A tool for moving and renaming packages in CVS" + +def print_usage(): + + print + print "%s %s [ %s ] [ %s ] [ %s ]" % (white("Usage:"), turquoise(__productname__), green("option"), green("origin"), green("destination")) + print " '%s' and '%s' are expected as a full package name, e.g. net-im/gaim" % (green("origin"), green("destination")) + print " See %s --help for a list of options" % __productname__ + print + +def check_cwd(portdir): + + if os.getcwd() != portdir: + print + print "%s Not in PORTDIR!" % yellow(" *") + print "%s Setting to: %s" % (yellow(" *"), os.getcwd()) + os.environ["PORTDIR"]=os.getcwd() + return os.getcwd() + + return portdir + +def check_args(args, portdir, options, cvscmd): + + booboo = False + re_expr = "^[\da-zA-Z-]{,}/[\d\w0-9-]{,}$" + o_re_expr = re.compile(re_expr) + + if len(args) == 0: + print "\n%s ERROR: errr, didn't you forget something" % red("!!!"), + count = range(3) + for second in count: + sys.stdout.write(".") + sys.stdout.flush() + sleep(1) + sys.stdout.write("?") + sys.stdout.flush() + sleep(1) + print "\n\n%s %s hits you with a clue stick %s" % (green(" *"), __productname__, green("*")) + sleep(1) + print_usage() + sys.exit(1) + + if options.remove: + if len(args) > 1: + error("Please remove packages one at a time") + sys.exit(1) + elif not o_re_expr.match(args[0].rstrip("/")): + error("Expected full package name as argument") + sys.exit(1) + elif not os.path.exists(os.path.join(portdir, args[0].rstrip("/"))): + error("No such package '%s'" % args[0].rstrip("/")) + sys.exit(1) + else: + if not options.cvs_up: + update_categories(portdir, args, cvscmd["update"]) + return (args[0].rstrip("/"), None) + + if len(args) == 2: + if not o_re_expr.match(args[0].rstrip("/")): + error("Expected full package name as origin argument") + booboo = True + elif not o_re_expr.match(args[1].rstrip("/")): + error("Expected full package name as destination argument") + booboo = True + + if booboo == True: + sys.exit(1) + else: + error("Expected two arguments as input.") + print_usage() + sys.exit(1) + + if not options.cvs_up: + update_categories(portdir, args, cvscmd["update"]) + + if not os.path.exists(os.path.join(portdir, args[0].rstrip("/"))): + error("No such package '%s'" % args[0].rstrip("/")) + booboo = True + elif os.path.exists(os.path.join(portdir, args[1].rstrip("/"))): + error("Package '%s' already exists" % args[1].rstrip("/")) + booboo = True + + if booboo == True: + sys.exit(1) + + return (args[0].rstrip("/"), args[1].rstrip("/")) + +def check_repos(portdir): + + files = os.listdir(portdir) + + for file in files: + if not os.path.isdir(file): + files.remove(file) + + if "CVS" not in files: + error("Current directory doesn't look like a CVS repository") + sys.exit(1) + +def check_commit_queue(): + + empty = True + + print + print "%s Checking commit queue for outstanding changes..." % green(" *") + print "%s Note: This may take a VERY long time" % yellow(" *") + print + + output = commands.getoutput("cvs diff") + + for line in output.split("\n"): + if not line.startswith("?"): + empty = False + break + + if empty == False: + error("Commit queue not empty! Please commit all outstanding changes before using %s." % __productname__) + sys.exit(1) + +def update_categories(portdir, catpkgs, cvsupcmd): + + my_catpkgs = [] + + print + print "%s Updating categories: " % green(" *") + + if len(catpkgs) >= 2: + if catpkgs[0].split("/", 1)[0] == catpkgs[1].split("/", 1)[0]: + my_catpkgs.append(catpkgs[0]) + else: + my_catpkgs.append(catpkgs[0]) + my_catpkgs.append(catpkgs[1]) + else: + my_catpkgs.append(catpkgs[0]) + + for catpkg in my_catpkgs: + (category, package) = catpkg.split("/", 1) + if os.path.exists(os.path.join(portdir, category)): + os.chdir(os.path.join(portdir, category)) + print " %s %s" % (green("*"), category) + do_cmd(cvsupcmd) + else: + print " %s %s" % (red("!"), category) + + os.chdir(portdir) + +def error(msg): + + sys.stderr.write("\n%s ERROR: %s\n" % (red("!!!"), msg)) + +def signal_handler(signal_number=None, stack_frame=None): + + error("Caught SIGINT; exiting...") + sys.exit(1) + os.kill(0, signal.SIGKILL) + +def do_cmd(cmd): + + (status, output) = commands.getstatusoutput(cmd) + if status != 0: + error("Command '%s' failed with exit status %d." % (cmd, status)) + for line in output.split("\n"): + if line != "": + print " %s %s" % (red("!"), line) + sys.exit(1) + +class CVSAbstraction: + + def __init__(self, portdir, oldcatpkg, newcatpkg, cvscmd, options): + + self._portdir = portdir + self._cvscmd = cvscmd + self._options = options + self._ignore = ("CVS") + + self._old_category = "" + self._old_package = "" + self._new_category = "" + self._new_package = "" + self._old_catpkg = oldcatpkg + self._new_catpkg = newcatpkg + + self._action = "" + + self._distinguish_action(oldcatpkg, newcatpkg) + + def _distinguish_action(self, oldcatpkg, newcatpkg): + + (self._old_category, self._old_package) = oldcatpkg.split("/") + if newcatpkg: + (self._new_category, self._new_package) = newcatpkg.split("/") + + if self._old_category != self._new_category and self._new_category: + if self._old_package != self._new_package and self._new_package: + self._action = "MOVE & RENAME" + else: + self._action = "MOVE" + elif self._old_package != self._new_package and self._new_package: + self._action = "RENAME" + elif not self._new_package: + self._action = "REMOVE" + else: + error("Unable to distingush required action.") + sys.exit(1) + + def __backup(self): + + print "%s Backing up %s..." % (green(" *"), turquoise(self._old_catpkg)) + + if not os.path.exists("/tmp/%s" % __productname__): + os.mkdir("/tmp/%s" % __productname__) + + if os.path.exists("/tmp/%s/%s" % (__productname__, self._old_package)): + do_cmd("rm -rf /tmp/%s/%s" % (__productname__, self._old_package)) + + do_cmd("cp -R %s /tmp/%s/%s" % (os.path.join(self._portdir, self._old_catpkg), __productname__, self._old_package)) + + def perform_action(self): + + count_down = 5 + + print + if self._action == "REMOVE": + print "%s Performing a '%s' of %s..." % (green(" *"), green(self._action), turquoise(self._old_catpkg)) + else: + print "%s Performing a '%s' of %s to %s..." % (green(" *"), green(self._action), turquoise(self._old_catpkg), yellow(self._new_catpkg)) + + if not self._options.countdown: + print "%s Performing in: " % green(" *"), + count = range(count_down) + count.reverse() + for second in count: + sys.stdout.write("%s " % red(str(second + 1))) + sys.stdout.flush() + sleep(1) + print + + if not self._action == "REMOVE": + self.__backup() + + if self._action == "MOVE & RENAME": + self._perform_move_rename() + elif self._action == "MOVE": + self._perform_move() + elif self._action == "RENAME": + self._perform_rename() + elif self._action == "REMOVE": + self._perform_remove() + + def _perform_remove(self): + + deps = self.__get_reverse_deps() + + if deps: + print "%s The following ebuild(s) depend on this package:" % red(" *") + for dep in deps: + print "%s %s" % (red(" !"), dep) + if self._options.force: + print "%s Are you sure you wish to force removal of this package?" % yellow(" *"), + try: + choice = raw_input("(Yes/No): ") + except KeyboardInterrupt: + error("Interrupted by user.") + sys.exit(1) + if choice.strip().lower() != "yes": + error("Bailing on forced removal.") + sys.exit(1) + else: + error("Refusing to remove from CVS, package has dependents.") + sys.exit(1) + + self.__remove_old_package() + + def _perform_move(self): + + self.__add_new_package() + self.__regen_manifest() + self.__update_dependents(self.__get_reverse_deps()) + self.__remove_old_package() + + def _perform_move_rename(self): + + self._perform_rename() + + def _perform_rename(self): + + self.__rename_files() + self.__add_new_package() + self.__regen_digests() + self.__update_dependents(self.__get_reverse_deps()) + self.__remove_old_package() + + def __rename_files(self): + + def rename_files(arg, dir, files): + + if os.path.basename(dir) not in self._ignore: + if os.path.basename(dir) != self._old_package: + for file in files: + new_file = "" + if file.find(self._old_package) >= 0: + new_file = file.replace(self._old_package, self._new_package) + do_cmd("mv %s %s" % (os.path.join(dir, file), os.path.join(dir, new_file))) + if not os.path.isdir(os.path.join(dir, new_file)) and not file.startswith("digest-"): + self.__rename_file_contents(os.path.join(dir, new_file)) + else: + for file in files: + if file.endswith(".ebuild"): + new_file = file.replace(self._old_package, self._new_package) + do_cmd("mv %s %s" % (os.path.join(dir, file), os.path.join(dir, new_file))) + self.__rename_file_contents(os.path.join(dir, new_file)) + elif file.endswith(".xml"): + self.__rename_file_contents(os.path.join(dir, file)) + + print "%s Renaming files..." % green(" *") + os.path.walk("/tmp/%s/%s" % (__productname__, self._old_package), rename_files , None) + do_cmd("mv /tmp/%s/%s /tmp/%s/%s" % (__productname__, self._old_package, __productname__, self._new_package)) + + def __regen_manifest(self, path=None, dep=False): + + if dep: + print "%s Regenerating Manifest..." % green(" *") + else: + print "%s Regenerating Manifest..." % green(" *") + if path: + os.chdir(path) + else: + os.chdir(os.path.join(self._portdir, self._new_catpkg)) + for ebuild in os.listdir("."): + if ebuild.endswith(".ebuild"): + do_cmd("/usr/lib/portage/bin/ebuild %s manifest" % ebuild) + break + + self.__gpg_sign(dep) + + def __regen_digests(self): + + print "%s Regenerating digests:" % green(" *") + os.chdir(os.path.join(self._portdir, self._new_catpkg)) + for digest in os.listdir("files/"): + if digest.startswith("digest-"): + os.unlink("files/%s" % digest) + for ebuild in os.listdir("."): + if ebuild.endswith(".ebuild"): + print " >>> %s" % ebuild + do_cmd("/usr/lib/portage/bin/ebuild %s digest" % ebuild) + + self.__gpg_sign() + + def __gpg_sign(self, dep=False): + + gpg_cmd = "" + + os.chdir(os.path.join(self._portdir, self._new_catpkg)) + + if "sign" in portage.features: + if dep: + print "%s GPG Signing Manifest..." % green(" *") + else: + print "%s GPG Signing Manifest..." % green(" *") + gpg_cmd = "gpg --quiet --sign --clearsign --yes --default-key %s" % portage.settings["PORTAGE_GPG_KEY"] + if portage.settings.has_key("PORTAGE_GPG_DIR"): + gpg_cmd = "%s --homedir %s" % (gpg_cmd, portage.settings["PORTAGE_GPG_DIR"]) + do_cmd("%s Manifest" % gpg_cmd) + do_cmd("mv Manifest.asc Manifest") + do_cmd("%s 'Manifest recommit'" % self._cvscmd["commit"]) + + def __rename_file_contents(self, file): + + def choice_loop(line, match_count, choice_list, type="name", replace=""): + + new_line = line + accepted = False + skipp = False + + while(not accepted): + print " ", + if len(choice_list) > 0: + for choice in choice_list: + print "%s: Replace with '%s'," % (white(choice), green(choice_list[choice])), + if match_count == 0: + print "%s: Pass, %s: Skip this file, %s: Custom" % (white(str(len(choice_list)+1)), white(str(len(choice_list)+2)), white(str(len(choice_list)+3))), + else: + print "%s: Pass, %s: Custom" % (white(str(len(choice_list)+1)), white(str(len(choice_list)+2))), + try: + input = raw_input("%s " % white(":")) + except KeyboardInterrupt: + print + error("Interrupted by user.") + sys.exit(1) + if choice_list.has_key(input): + if type == "name": + new_line = new_line.replace(self._old_package, choice_list[input]) + accepted = True + elif type == "P": + new_line = new_line.replace("${P}", choice_list[input]) + accepted = True + elif type == "PN": + new_line = new_line.replace("${PN}", choice_list[input]) + accepted = True + elif type == "PV": + new_line = new_line.replace("${PV}", choice_list[input]) + accepted = True + elif type == "PVR": + new_line = new_line.replace("${PVR}", choice_list[input]) + accepted = True + elif type == "PR": + new_line = new_line.replace("${PR}", choice_list[input]) + accepted = True + elif type == "PF": + new_line = new_line.replace("${PF}", choice_list[input]) + accepted = True + elif input == str(len(choice_list)+1): + accepted = True + elif input == str(len(choice_list)+2) and match_count == 0: + accepted = True + skipp = True + elif input == str(len(choice_list)+3) and match_count == 0 or input == str(len(choice_list)+2) and match_count != 0: + + input_accepted = False + + while(not input_accepted): + try: + custom_input = raw_input(" %s Replacement string: " % green("*")) + except KeyboardInterrupt: + print + error("Interrupted by user.") + sys.exit(1) + while(1): + print " %s Replace '%s' with '%s'? (Y/N)" % (yellow("*"), white(replace), white(custom_input)), + try: + yes_no = raw_input(": ") + except KeyboardInterrupt: + print + error("Interrupted by user.") + sys.exit(1) + if yes_no.lower() == "y": + input_accepted = True + break + elif yes_no.lower() == "n": + break + + new_line = new_line.replace(replace, custom_input) + accepted = True + else: + accepted = False + + if skipp: + break + + return (new_line, skipp) + + found = False + contents = [] + new_contents = [] + match_count = 0 + skipp = False + + try: + readfd = open(file, "r") + contents = readfd.readlines() + readfd.close() + except IOError, e: + error(e) + sys.exit(1) + + for line in contents: + if line.find(self._old_package) >= 0: + found = True + break + + if found == True: + print "%s Editing %s:" % (green(" *"), white(file.split("/tmp/%s/%s/" % (__productname__, self._old_package))[1])) + try: + writefd = open(file, "w") + except IOError, e: + error(e) + sys.exit(1) + for line in contents: + tmp_line = line + if not line.startswith("# $Header:"): + if line.find(self._old_package) >= 0: + print "%s %s" % (green(" !"), line.strip().replace(self._old_package, yellow(self._old_package))) + (tmp_line, skipp) = choice_loop(tmp_line, match_count, {"1": self._new_package, + "2": "${PN}"}, type="name", replace=self._old_package) + match_count += 1 + if skipp: + break + if line.find("${P}") >= 0: + print "%s %s" % (green(" !"), line.strip().replace("${P}", yellow("${P}"))) + (pkg, version, revising) = portage.pkgsplit(os.path.split(file)[1][:-7]) + (tmp_line, skipp) = choice_loop(tmp_line, match_count, {"1": "%s-%s" % (pkg, version), + "2": "%s-%s" % (self._old_package, version)}, type="P", replace="${P}") + match_count += 1 + if skipp: + break + if line.find("${PN}") >= 0: + print "%s %s" % (green(" !"), line.strip().replace("${PN}", yellow("${PN}"))) + (tmp_line, skipp) = choice_loop(tmp_line, match_count, {"1": self._new_package, + "2": self._old_package}, type="PN", replace="${PN}") + match_count += 1 + if skipp: + break + if line.find("${PV}") >= 0: + print "%s %s" % (green(" !"), line.strip().replace("${PV}", yellow("${PV}"))) + (pkg, version, revision) = portage.pkgsplit(os.path.split(file)[1][:-7]) + (tmp_line, skipp) = choice_loop(tmp_line, match_count, {"1": version}, type="PV", replace="${PV}") + match_count += 1 + if skipp: + break + if line.find("${PVR}") >= 0: + print "%s %s" % (green(" !"), line.strip().replace("${PVR}", yellow("${PVR}"))) + (pkg, version, revision) = portage.pkgsplit(os.path.split(file)[1][:-7]) + (tmp_line, skipp) = choice_loop(tmp_line, match_count, {"1": "%s-%s" % (version, revision)}, type="PVR", replace="${PVR}") + match_count += 1 + if skipp: + break + if line.find("${PR}") >= 0: + print "%s %s" % (green(" !"), line.strip().replace("${PR}", yellow("${PR}"))) + (pkg, version, revision) = portage.pkgsplit(os.path.split(file)[1][:-7]) + (tmp_line, skipp) = choice_loop(tmp_line, match_count, {"1": revision}, type="PR", replace="${PR}") + match_count += 1 + if skipp: + break + if line.find("${PF}") >= 0: + print "%s %s" % (green(" !"), line.strip().replace("${PF}", yellow("${PF}"))) + (pkg, version, revision) = portage.pkgsplit(os.path.split(file)[1][:-7]) + (tmp_line, skipp) = choice_loop(tmp_line, match_count, {"1": "%s-%s-%s" % (pkg, version, revision), + "2": "%s-%s-%s" % (self._old_package, version, revision)}, type="PF", replace="${PF}") + match_count += 1 + if skipp: + break + if line.find("${P/") >= 0: + start = line.find("${P/") + i = 0 + hi_str = "" + while(line[start + (i - 1)] != "}"): + hi_str += line[start + i] + i += 1 + print "%s %s" % (green(" !"), line.strip().replace(hi_str, red(hi_str))) + (tmp_line, skipp) = choice_loop(tmp_line, match_count, {}, type=None, replace=hi_str) + match_count += 1 + if skipp: + break + if line.find("${PN/") >= 0: + start = line.find("${PN/") + i = 0 + hi_str = "" + while(line[start + (i - 1)] != "}"): + hi_str += line[start + i] + i += 1 + print "%s %s" % (green(" !"), line.strip().replace(hi_str, red(hi_str))) + (tmp_line, skipp) = choice_loop(tmp_line, match_count, {}, type=None, replace=hi_str) + match_count += 1 + if skipp: + break + if line.find("${PV/") >= 0: + start = line.find("${PV/") + i = 0 + hi_str = "" + while(line[start + (i - 1)] != "}"): + hi_str += line[start + i] + i += 1 + print "%s %s" % (green(" !"), line.strip().replace(hi_str, red(hi_str))) + (tmp_line, skipp) = choice_loop(tmp_line, match_count, {}, type=None, replace=hi_str) + match_count += 1 + if skipp: + break + if line.find("${PVR/") >= 0: + start = line.find("${PVR/") + i = 0 + hi_str = "" + while(line[start + (i - 1)] != "}"): + hi_str += line[start + i] + i += 1 + print "%s %s" % (green(" !"), line.strip().replace(hi_str, red(hi_str))) + (tmp_line, skipp) = choice_loop(tmp_line, match_count, {}, type=None, replace=hi_str) + match_count += 1 + if skipp: + break + if line.find("${PR/") >= 0: + start = line.find("${PR/") + i = 0 + hi_str = "" + while(line[start + (i - 1)] != "}"): + hi_str += line[start + i] + i += 1 + print "%s %s" % (green(" !"), line.strip().replace(hi_str, red(hi_str))) + (tmp_line, skipp) = choice_loop(tmp_line, match_count, {}, type=None, replace=hi_str) + match_count += 1 + if skipp: + break + if line.find("${PF/") >= 0: + start = line.find("${PF/") + i = 0 + hi_str = "" + while(line[start + (i - 1)] != "}"): + hi_str += line[start + i] + i += 1 + print "%s %s" % (green(" !"), line.strip().replace(hi_str, red(hi_str))) + (tmp_line, skipp) = choice_loop(tmp_line, match_count, {}, type=None, replace=hi_str) + match_count += 1 + if skipp: + break + + new_contents.append(tmp_line) + + if not skipp: + for line in new_contents: + writefd.write(line) + else: + for line in contents: + writefd.write(line) + + writefd.close() + + def __update_dependents(self, dep_list): + + if len(dep_list) <= 0: + return + + print "%s Updating dependents:" % green(" *") + os.chdir(self._portdir) + + for dep in dep_list: + print " >>> %s" % dep + new_contents = [] + (category, pkg) = dep.split("/") + pkg_split = portage.pkgsplit(pkg) + os.chdir(self._portdir) + do_cmd("%s %s" % (self._cvscmd["update"], os.path.join(category, pkg_split[0]))) + + try: + readfd = open(os.path.join(self._portdir, category, pkg_split[0], "%s.ebuild" % pkg), "r") + contents = readfd.readlines() + readfd.close() + except IOError, e: + error(e) + sys.exit(1) + + for line in contents: + if self._old_catpkg in line: + new_contents.append(line.replace(self._old_catpkg, self._new_catpkg)) + else: + new_contents.append(line) + + try: + writefd = open(os.path.join(self._portdir, category, pkg_split[0], "%s.ebuild" % pkg), "w") + writefd.write("".join(new_contents)) + writefd.close() + except IOError, e: + error(e) + sys.exit(1) + + os.chdir(os.path.join(self._portdir, category, pkg_split[0])) + do_cmd("echangelog 'Dependency update: %s -> %s.'" % (self._old_catpkg, self._new_catpkg)) + do_cmd("%s 'Dependency update: %s -> %s.'" % (self._cvscmd["commit"], self._old_catpkg, self._new_catpkg)) + self.__regen_manifest(path=os.path.join(self._portdir, category, pkg_split[0]), dep=True) + + def __get_reverse_deps(self): + + dep_list = [] + conf_portdir = "/usr/portage" + + def scan_for_dep(arg, dir, files): + + (null, category) = os.path.split(dir) + + for file in files: + if self._old_catpkg not in os.path.join(category, file): + if not os.path.isdir(os.path.join(dir, file)): + try: + fd = open(os.path.join(dir, file), "r") + contents = fd.readlines() + fd.close() + except IOError, e: + error(e) + sys.exit(1) + if self._old_catpkg in contents[0] or self._old_catpkg in contents[1] or self._old_catpkg in contents[12]: + dep_list.append(os.path.join(category, file)) + + print "%s Resolving reverse dependencies..." % green(" *") + + try: + fd = open("/etc/make.conf", "r") + contents = fd.readlines() + fd.close() + except IOError, e: + error(e) + sys.exit(1) + + for line in contents: + if line.startswith("PORTDIR="): + (null, conf_portdir) = line.strip("\"\n").split("=") + break + + os.path.walk(os.path.join(conf_portdir, "metadata/cache"), scan_for_dep, None) + + return dep_list + + def __remove_old_package(self): + + def remove_files(arg, dir, files): + + if os.path.basename(dir) not in self._ignore: + for file in files: + if not os.path.isdir(os.path.join(dir, file)): + print " <<< %s" % (os.path.join(dir.strip("./"), file)) + os.unlink(os.path.join(dir, file)) + do_cmd("%s %s" % (self._cvscmd["remove"], os.path.join(dir, file))) + + print "%s Removing %s from CVS:" % (green(" *"), turquoise(self._old_catpkg)) + os.chdir(os.path.join(self._portdir, self._old_catpkg)) + os.path.walk('.', remove_files , None) + os.chdir("..") + + print "%s Commiting changes..." % green(" *") + if self._options.remove: + explanation = "" + while(1): + print "%s Please provide an explanation for this removal:" % yellow(" *"), + try: + explanation = raw_input("") + explanation = explanation.replace("'", "\\'").replace('"', '\\"') + except KeyboardInterrupt: + print + error("Interrupted by user.") + sys.exit(1) + if explanation != "": + break + do_cmd("""%s "Removed from %s: %s" """ % (self._cvscmd["commit"], self._old_category, explanation)) + else: + do_cmd("%s 'Moved to %s.'" % (self._cvscmd["commit"], self._new_catpkg)) + do_cmd("rm -rf %s" % os.path.join(self._portdir, self._old_catpkg)) + + print "%s Checking for remnant files..." % (green(" *")) + do_cmd(self._cvscmd["update"]) + + if not os.path.exists(os.path.join(self._portdir, self._old_catpkg)): + if not self._action == "REMOVE": + print "%s %s successfully removed from CVS." % (green(" *"), turquoise(self._old_catpkg)) + else: + error("Remnants of %s still remain in CVS." % (turquoise(self._old_catpkg))) + + def __add_new_package(self): + + def add_files(arg, dir, files): + + (null, null, null, dirs) = dir.split("/", 3) + + if os.path.basename(dir) not in self._ignore: + os.chdir(os.path.join(self._portdir, self._new_category)) + if os.path.basename(dir) != self._new_package: + print " >>> %s/" % dirs + os.mkdir(dirs) + do_cmd("%s %s" % (self._cvscmd["add"], dirs)) + for file in files: + if not os.path.isdir(os.path.join(dir, file)): + print " >>> %s" % os.path.join(dirs, file) + do_cmd("cp %s %s" % (os.path.join(dir, file), dirs)) + do_cmd("%s %s" % (self._cvscmd["add"], os.path.join(dirs, file))) + + print "%s Adding %s to CVS:" % (green(" *"), turquoise(self._new_catpkg)) + os.chdir(os.path.join(self._portdir, self._new_category)) + print " >>> %s/" % self._new_package + os.mkdir(self._new_package) + do_cmd("%s %s" % (self._cvscmd["add"], self._new_package)) + os.chdir(self._new_package) + os.path.walk("/tmp/%s/%s" % (__productname__, self._new_package), add_files , None) + os.chdir(os.path.join(self._portdir, self._new_catpkg)) + + print "%s Adding ChangeLog entry..." % green(" *") + do_cmd("echangelog 'Moved from %s to %s.'" % (self._old_catpkg, self._new_catpkg)) + + print "%s Commiting changes..." % green(" *") + do_cmd("%s 'Moved from %s to %s.'" % (self._cvscmd["commit"], self._old_catpkg, self._new_catpkg)) + + print "%s %s successfully added to CVS." % (green(" *"), turquoise(self._new_catpkg)) + + def log_move(self): + + if not self._action == "REMOVE": + + update_files = [] + update_regex = "^[\d]Q-[\d]{4}$" + + p_file_regex = re.compile(update_regex) + + print "%s Logging move:" % (green(" *")) + os.chdir(os.path.join(self._portdir, "profiles/updates")) + do_cmd(self._cvscmd["update"]) + + for file in os.listdir("."): + o_file_regex = p_file_regex.match(file) + if file not in self._ignore and o_file_regex: + (q, y) = file.split("-") + update_files.append("%s-%s" % (y, q)) + + update_files.sort() + (y, q) = update_files[-1].split("-") + upfile = "%s-%s" % (q, y) + print " >>> %s" % upfile + + try: + fd = open(upfile, "a") + fd.write("move %s %s\n" % (self._old_catpkg, self._new_catpkg)) + fd.close() + except IOError, e: + error(e) + sys.exit(1) + + do_cmd("%s 'Moved %s to %s'" % (self._cvscmd["commit"], self._old_catpkg, self._new_catpkg)) + os.chdir(self._portdir) + + def clean_up(self): + + if not self._action == "REMOVE": + print "%s Removing back-up..." % (green(" *")) + do_cmd("rm -rf /tmp/%s/%s" % (__productname__, self._old_package)) + if len(os.listdir("/tmp/%s" % __productname__)) == 0: + do_cmd("rmdir /tmp/%s" % __productname__) + + os.chdir(self._portdir) + +if __name__ == "__main__": + + signal.signal(signal.SIGINT, signal_handler) + + cvscmd = {"remove": "cvs -Qf rm", + "commit": "cvs -Qf commit -m", + "update": "cvs -Qf up -dPC", + "add": "cvs -Qf add"} + + parser = OptionParser(usage="%prog [ option ] [ origin ] [ destination ]", version="%s-%s" % (__productname__, __version__)) + parser.add_option("--usage", action="store_true", dest="usage", default=False, help="Pint usage information") + parser.add_option("-q", "--queue-check", action="store_true", dest="commit_queue", default=False, help="Check the cvs tree for files awaiting commit") + parser.add_option("-u", "--no-cvs-up", action="store_true", dest="cvs_up", default=False, help="Skip running cvs up in the origin and destination categories") + parser.add_option("-c", "--no-countdown", action="store_true", dest="countdown", default=False, help="Skip countdown before performing") + parser.add_option("-R", "--remove", action="store_true", dest="remove", default=False, help="Remove package") + parser.add_option("-F", "--force", action="store_true", dest="force", default=False, help="Force removal of package, ignoring any reverse deps") + (options, args) = parser.parse_args() + + if options.usage: + print_usage() + sys.exit(0) + + if randint(1, 100) == 50: + print "%s I put on my robe and wizard hat..." % green(" *") + + portdir = check_cwd(portage.settings["PORTDIR"].rstrip("/")) + check_repos(portdir) + (oldcatpkg, newcatpkg) = check_args(args, portdir, options, cvscmd) + + if options.commit_queue: + check_commit_queue() + + ThisPackage = CVSAbstraction(portdir, oldcatpkg, newcatpkg, cvscmd, options) + + ThisPackage.perform_action() + ThisPackage.log_move() + ThisPackage.clean_up() + + if options.remove: + print "%s %s successfully removed from CVS." % (green(" *"), turquoise(oldcatpkg)) + else: + print "%s %s successfully moved to %s." % (green(" *"), turquoise(oldcatpkg), yellow(newcatpkg)) + diff --git a/deprecated/etc-update/AUTHORS b/deprecated/etc-update/AUTHORS new file mode 100644 index 0000000..e69de29 diff --git a/deprecated/etc-update/ChangeLog b/deprecated/etc-update/ChangeLog new file mode 100644 index 0000000..e69de29 diff --git a/deprecated/etc-update/Makefile b/deprecated/etc-update/Makefile new file mode 100644 index 0000000..95838ad --- /dev/null +++ b/deprecated/etc-update/Makefile @@ -0,0 +1,20 @@ +# Copyright 2004 Karl Trygve Kalleberg +# Copyright 2004 Gentoo Technologies, Inc. +# Distributed under the terms of the GNU General Public License v2 +# +# $Header$ + +include ../../makedefs.mak + +all: + echo "PAPPLE (vb.) To do what babies do to soup with their spoons." + +dist: + mkdir -p ../../$(distdir)/src/etc-update + cp Makefile AUTHORS README TODO ChangeLog etc-update etc-update.1 ../../$(distdir)/src/etc-update/ + +install: + install -m 0755 etc-update $(bindir)/ + install -d $(docdir)/etc-update + install -m 0644 AUTHORS ChangeLog README $(docdir)/etc-update/ + install -m 0644 etc-update.1 $(mandir)/ diff --git a/deprecated/etc-update/README b/deprecated/etc-update/README new file mode 100644 index 0000000..e69de29 diff --git a/deprecated/etc-update/etc-update b/deprecated/etc-update/etc-update new file mode 100755 index 0000000..f566dff --- /dev/null +++ b/deprecated/etc-update/etc-update @@ -0,0 +1,165 @@ +#! /usr/bin/python +# +# $Header$ +# +# Distributed under the terms of the GNU General Public License v2 +# Copyright (c) 2003 Karl Trygve Kalleberg +# +# Based on previous versions, by +# - Brandon Low +# - Jochem Kossen +# - Leo Lipelis + +from dialog import Dialog +import portage +import time +import re +import os + +__author__ = "Karl Trygve Kalleberg" +__email__ = "karltk@gentoo.org" +__version__ = "0.2.0" +__productname__ = "etc-update" +__description__ = "Interactive config file updater" + +globals = portage.settings.configdict["globals"] + +for i in globals["CONFIG_PROTECT"].split(): + print i + +# list all files in all CONFIG_PROTECT dirs +# list them in the gui +# one-by-one: +# - is update to header only? +# - is the original unmodified from the previous package? (not checkable - duh!) +# - + +class Config: + pass + +def loadConfig(): + cfg = Config() + globals = portage.settings.configdict["globals"] + cfg.config_protect = globals["CONFIG_PROTECT"].split() + return cfg + +def _recurseFiles(path): + files = [] + if os.path.exists(path): + try: + tmpfiles = os.listdir(path) + for i in tmpfiles: + fn = path + "/" + i + if os.path.isdir(fn): + files += _recurseFiles(fn) + elif os.path.isfile(fn): + m = re.search("\._cfg...._",fn) + if m: + files.append(fn) + else: + print "What is this anyway?:", fn + except OSError: + pass + # print "Access denied:", path + + return files + +def findAllFiles(dlg, config): + files = [] + gauge = dlg.gauge(0, + "Processing CONFIG_PROTECT directories...", + 7, + 60, + "Gauge", + sleep=3) + num_dirs = len(config.config_protect) + for i in xrange(num_dirs): + rem = repr(num_dirs - i / num_dirs) + gauge.update(rem, "Directories remaining: %s" % rem) + files += _recurseFiles(config.config_protect[i]) + return files + +def prettifyFiles(files): + rx = re.compile("\._cfg...._") + def strip_cfg(x): + """Remove ._cfg????_ part """ + m = rx.search(x) + if m: + s,e = m.span(0) + return x[:s] + x[e:] + return x + return map(strip_cfg, files) + +def updateFile(dlg, original): + + # Find candidates + + dir = os.path.dirname(original) + filename = os.path.basename(original) + rx = re.compile("\._cfg...._" + filename) + cand = filter(lambda x: rx.search(x), os.listdir(dir)) + + if len(cand) > 1: + + # Add mtimes + for i in xrange(len(cand)): + stamp = time.localtime(os.path.getmtime(dir + "/" + cand[i])) + tstr = time.strftime("%a, %d %b %Y %H:%M:%S", stamp) + cand[i] = cand[i] + " - " + tstr + + + # Show selection + replacement = dlg.menu("Files that need updating", + Dialog.AUTO_SIZE, + list = cand, + showHelp = False, + title="Checklist") + + else: + replacement = cand[0] + + + # Display diff + + dlg.yesno("Would you like to update \n" + \ + "[" + original + "]with\n[" + dir + "/" + replacement + "] ?") + +def displayFiles(dlg, config, files): + + pretty_files = prettifyFiles(files) + + while 1: + result = dlg.menu("Files that need updating", + Dialog.AUTO_SIZE, + list = pretty_files, + showHelp = False, + title="Checklist") + if result == None: + if dlg.ERR_CANCEL: + break + + updateFile(dlg, result) + + if len(pretty_files): + print "!!! Warning: There are still files that require updating." + + +def main(): + dlg = Dialog("etc-update") +# dlg = None + + config = loadConfig() + files = findAllFiles(dlg, config) + displayFiles(dlg, config,files) + + +if __name__ == "__main__": + try: + main() + except KeyboardInterrupt: + print "Operation aborted!" + +# TODO: +# - option for automatically update untouched files +# - show coloured diff +# - proper progress bar diff --git a/deprecated/etc-update/etc-update.1 b/deprecated/etc-update/etc-update.1 new file mode 100644 index 0000000..53477d8 --- /dev/null +++ b/deprecated/etc-update/etc-update.1 @@ -0,0 +1,12 @@ +.TH etc-update "1" "Nov 2003" "gentoolkit" +.SH NAME +etc-update \- Gentoo: Configuration Update Utility +.SH SYNOPSIS +.B etc-update +.SH BUGS +This tool does not yet have a man page. Feel free to submit a bug about it to +http://bugs.gentoo.org +.SH AUTHORS +This informative man page was written by Karl Trygve Kalleberg +. + diff --git a/deprecated/etcat/AUTHORS b/deprecated/etcat/AUTHORS new file mode 100644 index 0000000..5da0b07 --- /dev/null +++ b/deprecated/etcat/AUTHORS @@ -0,0 +1,5 @@ +Maintainer: +Karl Trygve Kalleberg + +Authors: +Alastair Tse (original author) diff --git a/deprecated/etcat/ChangeLog b/deprecated/etcat/ChangeLog new file mode 100644 index 0000000..bdadcb6 --- /dev/null +++ b/deprecated/etcat/ChangeLog @@ -0,0 +1,36 @@ +2004-04-20 Marius Mauch + - fixing -u behavior so it matches equery (bug #47690) + +2004-03-13 Marius Mauch + - grouping version in --version output + +2004-01-23 Marius Mauch + - now catches exceptions thrown by portage + - minor bugfixes + +2004-01-07 Karl Trygve Kalleberg + * Added man page from app-portage/gentoolkit + * Added Makefile + * Added sys.path workaround for Portage >=2.0.50 + +* etcat-0.2.0 (06 May 2003) + 06 May 2003; Alastair Tse + Trying to add a dependency graph feature. kind of works with + some weird hacks parsing the depenency string. probably needs + to use functions in portage to parse it properly. + +* etcat-0.1.4 (27 Apr 2003) + + 27 Apr 2003; Alastair Tse + Added "files", "belongs", "depends" functions. + +*etcat-0.1.3 (24 Apr 2003) + + 24 Apr 2003; Alastair Tse + Fixed bug if ebuild doesn't exist. Added manpage. + +*etcat-0.1.2 (29 Mar 2003) + + 29 Mar 2003; Alastair Tse + Initial commit to gentoolkit. Check source for previous changes + diff --git a/deprecated/etcat/Makefile b/deprecated/etcat/Makefile new file mode 100644 index 0000000..2281646 --- /dev/null +++ b/deprecated/etcat/Makefile @@ -0,0 +1,18 @@ +# Copyright 2004 Karl Trygve Kalleberg +# Copyright 2004 Gentoo Technologies, Inc. +# Distributed under the terms of the GNU General Public License v2 +# +# $Header$ + +include ../../makedefs.mak + +all: + +dist: + mkdir -p ../../$(distdir)/src/etcat + cp Makefile AUTHORS README TODO ChangeLog etcat etcat.1 ../../$(distdir)/src/etcat + +install: + install -d $(docdir)/deprecated/etcat + install -m 0755 etcat $(docdir)/deprecated/etcat/ + install -m 0644 etcat.1 README AUTHORS $(docdir)/deprecated/etcat/ diff --git a/deprecated/etcat/README b/deprecated/etcat/README new file mode 100644 index 0000000..50bd2f3 --- /dev/null +++ b/deprecated/etcat/README @@ -0,0 +1,2 @@ +For more information, this tool was originally hosted on: +http://www.liquidx.net/projects/etcat/ diff --git a/deprecated/etcat/TODO b/deprecated/etcat/TODO new file mode 100644 index 0000000..e69de29 diff --git a/deprecated/etcat/etcat b/deprecated/etcat/etcat new file mode 100755 index 0000000..5137683 --- /dev/null +++ b/deprecated/etcat/etcat @@ -0,0 +1,688 @@ +#!/usr/bin/env python2 +# +# -*- mode: python; -*- +# +# --| Version Information |------------------------------------------ +# +# etcat v0.1.4 (27 Apr 2003) +# +# $Header$ +# +# --| About |-------------------------------------------------------- +# +# etcat is a Portage/Ebuild Information Extractor. Basically, it +# provides higher level convienence functions to the Portage system +# used by Gentoo Linux. +# +# You can use it to quickly find out the recent changes of your +# favourite package, the size of installed packages, the +# available versions for a package and more. +# +# --| License |------------------------------------------------------ +# +# Distributed under the terms of the GNU General Public License v2 +# Copyright (c) 2002 Alastair Tse. +# +# --| Usage |-------------------------------------------------------- +# +# etcat [options] +# +# -b/belongs ) checks what package(s) a file belongs to +# -c/changes ) list the more recent changelog entry +# -d/depends ) list all those that have this in their depends +# -f/files ) list all files that belong to this package +# -g/graph ) graph dependencies +# -s/size ) guesses the size of a installed packaged. +# -u/uses ) list all the use variables used in this package/ebuild +# -v/versions ) list all the versions available for a package +# +# --| TODO |--------------------------------------------------------- +# +# - in ver_cmp: 1.2.10a < 1.2.10, need to fix that +# +# --| Changes |------------------------------------------------------ +# +# * etcat-0.3.1 (10 Oct 2004) [karltk] +# - Fixed changes help examples +# * etcat-0.3.1 (08 Jan 2004) [genone] +# - adding missing python searchpath modification +# - fixing sort order +# * etcat-0.3.0 (12 Jul 2003) [karltk] +# - Refactored interesting stuff into the Gentoolkit module +# * etcat-0.2.0 (13 Jun 2003) +# - Updated "versions" with PORTAGE_OVERLAY detection +# - Added "graph" feature +# * etcat-0.1.5 (30 Apr 2003) +# - Fixed disappearing short opts. Oops. +# * etcat-0.1.4 (27 Apr 2003) +# - Cleaned up command execution code to provide a single place +# to specify functions +# - Added own custom wrapping print code. +# - Added "files" feature +# - Added "depends" feature +# * etcat-0.1.3 (24 Apr 2003) +# - Overhaul of commandline interpreter +# - Added "belongs" feature +# - Reimplemented "uses" to deal with IUSE more cleanly +# and sources use.local.desc +# - Natural Order Listings for version +# * etcat-0.1.2 (29 Mar 2003) +# - Added unstable indicator to complement masked +# - improved use flag listing +# * etcat-0.1.1 (21 Jan 2003) +# - Add package to versions listing even if it's not in +# the portage anymore (21 Jan 2003) +# - Fixed old ehack references (17 Jan 2003) +# * etcat-0.1 (31 Oct 2002) +# Initial Release; +# +# ------------------------------------------------------------------- + + + +import os +import sys +import re +import pprint +import getopt +import glob + +# portage and gentoolkit need special path modifications +sys.path.insert(0, "/usr/lib/portage/pym") +sys.path.insert(0, "/usr/lib/gentoolkit/pym") + +import gentoolkit +from stat import * +try: + from portage.output import * +except ImportError: + from output import * + +__author__ = "Alastair Tse" +__email__ = "liquidx@gentoo.org" +__version__ = "0.3.1" +__productname__ = "etcat" +__description__ = "Portage Information Extractor" + +# .-------------------------------------------------------. +# | Initialise Colour Settings | +# `-------------------------------------------------------' +if (not sys.stdout.isatty()) or (gentoolkit.settings["NOCOLOR"] in ["yes","true"]): + nocolor() + +# "option": ("shortcommand","desc",["example one", "example two"]) +options = { +"belongs": \ +("b","Searches for a package that owns a specified file with an option to restrict the search space.", +["etcat belongs /usr/bin/gimp media-gfx", + "etcat belongs /usr/lib/libjpeg.so media-*", + "etcat belongs /usr/lib/libmpeg.so"]), +"changes": \ +("c","Outputs the changelog entry to screen. It is possible to give a version number along with the package name.", +["etcat changes mozilla", + "etcat changes =mozilla-1.1-r1", + "etcat changes gkrellm$"]), +"depends": \ +("d","Finds all packages that are directly dependent to a regex search string.", +["etcat depends 'gnome-base/libgnome'", + "etcat depends '>=dev-lang/python-2.2'"]), +"files": \ +("f","Lists files that belongs to a package and optionally with version.",[]), +"graph": \ +("g","Graphs Dependencies (NON WORKING)",[]), +"size": \ +("s","Lists the installed size of a package.",[]), +"uses": \ +("u", "Advanced output of USE vars in a package. Tells you flags used by a package at time of installation, flags in current config and flag description.",[]), +"versions": \ +("v","Displays the versions available for a specific package. Colour coded to indicate installation status and displays slot information.", +[turquoise("(I)") + "nstalled", + yellow("(~)") + "Unstable Testing Branch", + red("(M)") + "asked Package"]) +} + +# .-------------------------------------------------------. +# | Small Wrapping Printer with Indent Support | +# `-------------------------------------------------------' + +def wrap_print(string, indent=0, width=74): + line_len = width - indent + str_len = len(string) + lines = [] + + pos = 0 + thisline = "" + while pos < str_len: + # if we still have space stuff the + # character in this line + if len(thisline) < line_len-1: + thisline += string[pos] + pos += 1 + # if we're at the end of the line, + # check if we should hyphenate or + # append + elif len(thisline) == line_len -1: + # end of a text + if pos == str_len -1: + thisline += string[pos] + pos += 1 + # end of a word + elif string[pos] != " " and string[pos+1] == " ": + thisline += string[pos] + pos += 1 + # just a space + elif string[pos] == " ": + thisline += string[pos] + pos += 1 + # start of a word, we start the word on the next line + elif pos>0 and string[pos-1] == " ": + thisline += " " + # needs hyphenating + else: + thisline += "-" + + # append the line + lines.append(thisline) + thisline = "" + + # append last line + if thisline: + lines.append(thisline) + + for line in lines: + print " "*indent + line + +# +-------------------------------------------------------+ +# | Pretty Print Log | +# +-------------------------------------------------------+ +# | Extracts and prints out the log entry corresponding | +# | to a certain revision if given. If not supplied, | +# | prints out the latest/topmost entry | +# `-------------------------------------------------------' + +# output the latest entry in changelog +def output_log(lines, package_ver=""): + # using simple rules that all changelog entries have a "*" + # as the first char + is_log = 0 + is_printed = 0 + + for line in lines: + if package_ver: + start_entry = re.search("^[\s]*\*[\s]*(" + package_ver + ")[\s]+.*(\(.*\))",line) + else: + start_entry = re.search("^[\s]*\*[\s]*(.*)[\s]+.*(\(.*\))",line) + if not is_log and start_entry: + is_printed = 1 + is_log = 1 + print green("*") + " " + white(start_entry.group(1)) + " " + turquoise(start_entry.group(2)) + " :" + elif is_log and re.search("^[\s]*\*[\s]*(.*)[\s]+.*(\(.*\))",line): + break + elif is_log: + print line.rstrip() + else: + pass + + return is_printed + +# .-------------------------------------------------------. +# | Changes Function | +# +-------------------------------------------------------+ +# | Print out the ChangeLog entry for package[-version] | +# `-------------------------------------------------------' + +def changes(query, matches): + if not report_matches(query,matches,installed_only=0): + return + + for pkg in matches: + changelog_file = pkg.get_package_path() + "/ChangeLog" + if os.path.exists(changelog_file): + output_log(open(changelog_file).readlines(), pkg.get_name()+"-"+pkg.get_version()) + else: + print red("Error") + ": No Changelog for " + pkg.get_cpv() + + +# .-------------------------------------------------------. +# | Versions Function | +# +-------------------------------------------------------+ +# | Prints out the available version, masked status and | +# | installed status. | +# `-------------------------------------------------------' + +def versions(query, matches): + # this function should also report masked packages + matches = gentoolkit.find_packages(query, masked=True) + if not report_matches(query,matches): + return + + # sorting result list + matches = gentoolkit.sort_package_list(matches) + + # FIXME: old version printed result of regex search on name, + # so "ant" would return app-emacs/semantic, etc... + + last_cp = "" + + for pkg in matches: + new_cp = pkg.get_category()+"/"+pkg.get_name() + if last_cp != new_cp: + print green("*") + " " + white(new_cp) + " :" + last_cp = new_cp + + state = [] + color = green + unstable = 0 + overlay = "" + + # check if masked + if pkg.is_masked(): + state.append(red("M")) + color = red + else: + state.append(" ") + + # check if in unstable + kwd = pkg.get_env_var("KEYWORDS") + if "~" + gentoolkit.settings["ARCH"] in kwd.split(): + state.append(yellow("~")) + if color != red: + color = yellow + unstable = 1 + else: + state.append(" ") + + # check if installed + if pkg.is_installed(): + state.append(turquoise("I")) + color = turquoise + else: + state.append(" ") + + # check if this is a OVERLAY ebuilds + if pkg.is_overlay(): + overlay = " OVERLAY" + + ver = pkg.get_version() + slot = pkg.get_env_var("SLOT") + print " "*8 + "[" + "".join(state) + "] " + color(ver) + " (" + color(slot) + ")" + overlay + +# .-------------------------------------------------------. +# | List USE flags for a single ebuild, if it's installed | +# +-------------------------------------------------------+ +# | Just uses the new IUSE parameter in ebuilds | +# `-------------------------------------------------------' +def uses(query, matches): + useflags = gentoolkit.settings["USE"].split() + usedesc = {} + uselocaldesc = {} + + # Load global USE flag descriptions + try: + fd = open(gentoolkit.settings["PORTDIR"]+"/profiles/use.desc") + usedesc = {} + for line in fd.readlines(): + if line[0] == "#": + continue + fields = line.split(" - ") + if len(fields) == 2: + usedesc[fields[0].strip()] = fields[1].strip() + except IOError: + pass + + # Load local USE flag descriptions + try: + fd = open(gentoolkit.settings["PORTDIR"]+"/profiles/use.local.desc") + for line in fd.readlines(): + if line[0] == "#": + continue + fields = line.split(" - ") + if len(fields) == 2: + catpkguse = re.search("([a-z]+-[a-z]+/.*):(.*)", fields[0]) + if catpkguse: + if not uselocaldesc.has_key(catpkguse.group(1).strip()): + uselocaldesc[catpkguse.group(1).strip()] = {catpkguse.group(2).strip() : fields[1].strip()} + else: + uselocaldesc[catpkguse.group(1).strip()][catpkguse.group(2).strip()] = fields[1].strip() + except IOError: + pass + + print "[ Colour Code : " + green("set") + " " + red("unset") + " ]" + print "[ Legend : (U) Col 1 - Current USE flags ]" + print "[ : (I) Col 2 - Installed With USE flags ]" + + if filter(gentoolkit.Package.is_installed, matches): + only_installed = True + else: + only_installed = False + + # Iterate through matches, printing a report for each package + for p in matches: + if not p.is_installed() and only_installed: + continue + + bestver = p.get_cpv() + iuse = p.get_env_var("IUSE") + + if iuse: usevar = iuse.split() + else: usevar = [] + + inuse = [] + used = p.get_use_flags().split() + + # store (inuse, inused, flag, desc) + output = [] + + for u in usevar: + inuse = 0 + inused = 0 + try: + desc = usedesc[u] + except KeyError: + try: + desc = uselocaldesc[p.get_category()+"/"+p.get_name()][u] + except KeyError: + desc = "" + + if u in p.get_settings("USE"): inuse = 1 + if u in used: inused = 1 + + output.append((inuse, inused, u, desc)) + + # pretty print + if output: + print + print white(" U I ") + "[ Found these USE variables in : " + white(bestver) + " ]" + maxflag_len = 0 + for inuse, inused, u, desc in output: + if len(u) > maxflag_len: + maxflag_len = len(u) + + for inuse, inused, u, desc in output: + flag = ["-","+"] + colour = [red, green] + if inuse != inused: + print yellow(" %s %s" % (flag[inuse], flag[inused])), + else: + print " %s %s" % (flag[inuse], flag[inused]), + + print colour[inuse](u.ljust(maxflag_len)), + + # print description + if desc: + print ":", desc + else: + print ": unknown" + else: + print "[ No USE flags found for :", white(p.get_cpv()), "]" + + return + +# .-------------------------------------------------------. +# | Graphs the Dependency Tree for a package | +# +-------------------------------------------------------+ +# | Naive graphing of dependencies +# `-------------------------------------------------------' + +def graph(query, matches): + if not report_matches(query, matches): + return + + for pkg in matches: + if not pkg.is_installed(): + continue + rgraph(pkg) + +def rgraph(pkg,level=0,pkgtbl=[],suffix=""): + + cpv=pkg.get_cpv() + + print level*" " + "`-- " + cpv + suffix + pkgtbl.append(cpv) + + for x in pkg.get_runtime_deps(): + suffix="" + cpv=x[2] + pkg=gentoolkit.find_best_match(x[0] + cpv) + if not pkg: + continue + if pkg.get_cpv() in pkgtbl: + continue + if cpv.find("virtual")==0: + suffix+=" (" + cpv + ")" + if len(x[1]): + suffix+=" [ " + "".join(x[1]) + " ]" + pkgtbl=rgraph(pkg,level+1,pkgtbl,suffix) + return pkgtbl + +# .-------------------------------------------------------. +# | Required By Function | +# +-------------------------------------------------------+ +# | Find what packages require a given package name | +# `-------------------------------------------------------' + +def depends(query, matches): + + print "[ Results for search key : " + white(query) + " ]" + + isdepend = gentoolkit.split_package_name(query) + + for pkg in matches: + if pkg.is_installed(): + deps = pkg.get_runtime_deps() + for x in deps: + cpvs=gentoolkit.split_package_name(x[2]) + cat_match=0 + ver_match=0 + name_match=0 + if not isdepend[0] or isdepend[0] == cpvs[0]: + cat_match=1 + if not isdepend[2] or \ + (isdepend[2] == cpvs[2] and isdepend[3] == cpvs[3]): + ver_match=1 + if isdepend[1] == cpvs[1]: + name_match=1 + if cat_match and ver_match and name_match: + print turquoise("*"), white(pkg.get_cpv()), white("[ ") + "".join(x[1]), white("]") + +# .-------------------------------------------------------. +# | Belongs to which package | +# +-------------------------------------------------------+ +# | Finds what package a file belongs to | +# `-------------------------------------------------------' + +def belongs(query,matches): + + q = query.split() + + if len(q) > 1: + item=q[0] + cat=q[1] + fn=lambda x: x.find(cat)==0 + else: + item=q[0] + cat="*" + fn=None + matches = gentoolkit.find_all_installed_packages(fn) + + print "Searching for " + item + " in " + cat + " ..." + + rx = re.compile(item) + + for pkg in matches: + if pkg.get_contents(): + for fn in pkg.get_contents().keys(): + if rx.search(fn): + print pkg.get_cpv() + break # We know this pkg matches, look for any more matches + return + +# .-------------------------------------------------------. +# | Size of all packages matching query | +# +-------------------------------------------------------+ +# | Finds the size of installed packages | +# `-------------------------------------------------------' +def size(query,packages): + packages = gentoolkit.find_packages(query) + if not report_matches(query, packages): + return + + for pkg in packages: + if not pkg.is_installed(): + continue + x=pkg.size() + size=x[0] + files=x[1] + uncounted=x[2] + print turquoise("*") + " " + white(pkg.get_cpv()) + print " Total Files : ".rjust(25) + str(files) + if uncounted: + print " Inaccessible Files : ".rjust(25) + str(uncounted) + print " Total Size : ".rjust(25) + "%.2f KB" % (size/1024.0) + + +def report_matches(query, matches, installed_only=1): + print "[ Results for search key : " + white(query) + " ]" + print "[ Candidate applications found : " + white(str(len(matches))) + " ]" + print + + if installed_only and matches: + print " Only printing found installed programs." + print + elif installed_only: + print "No packages found." + + if matches: + return 1 + else: + return 0 + + +# .-------------------------------------------------------. +# | Files in a package | +# +-------------------------------------------------------+ +# | Lists all the files in a package | +# `-------------------------------------------------------' +def files(query,matches): + if not report_matches(query, matches): + return + + for package in matches: + if not package.is_installed(): + continue + contents = package.get_contents() + + print yellow(" * ") + white(package.get_cpv()) + for x in contents.keys(): + t = contents[x][0] + if t == "obj": + print x + elif t == "sym": + print turquoise(x) + elif t == "dir": + print blue(x) + else: + print x + +# .-------------------------------------------------------. +# | Help Function | +# `-------------------------------------------------------' +def ver(): + print __productname__ + " (" + __version__ + ") - " + __description__ + " - By: " + __author__ + +def help(): + screenwidth = 74 + margin = 2 + margin_desc = 4 + margin_ex = 8 + + ver() + print yellow("NOTICE: ") + "This tool will be phased out at some point in" + print " the future, please use equery instead." + print " Bugs are still fixed, but new features won't be added." + print + print white("Usage: ") + turquoise(__productname__) + " [ " + green("options") + " ] [ " + turquoise("action") + " ] [ " + turquoise("package") + " ]" + print + print turquoise("Actions:") + print + for name,tup in options.items(): + print " "*margin + green(name) + " (" + green("-" + tup[0]) + " short option)" + wrap_print(tup[1],indent=margin_desc) + for example in tup[2]: + print " "*margin_ex + example + print + +# .-------------------------------------------------------. +# | Main Function | +# `-------------------------------------------------------' +def main(): + + action = '' + query = '' + + if len(sys.argv) < 3: + help() + sys.exit(1) + + # delegates the commandline stuff to functions + pointer = 2 + # short/long opts mapping + shortopts = ["-"+x[0] for x in options.values()] + short2long = {} + for k,v in options.items(): + short2long[v[0]] = k + longopts = options.keys() + # loop thru arguments + for arg in sys.argv[1:]: + if arg[0] == "-" and len(arg) == 2 and arg in shortopts: + action = short2long[arg[1]] + query = ' '.join(sys.argv[pointer:]) + break + elif arg in longopts: + action = arg + query = ' '.join(sys.argv[pointer:]) + break + else: + pointer += 1 + + # abort if we don't have an action or query string + if not query or action not in options.keys(): + help() + sys.exit(1) + else: + try: + matches = gentoolkit.find_packages(query) + except KeyError, e: + if e[0].find("Specific key requires operator") == 0: + print red("!!!"), "Invalid syntax: missing operator" + print red("!!!"), "If you want only specific versions please use one of" + print red("!!!"), "the following operators as prefix for the package name:" + print red("!!!"), " > >= = <= <" + print red("!!!"), "Example to only match gcc versions greater or equal 3.2:" + print red("!!!"), " >=sys-devel/gcc-3.2" + else: + print red("!!!"), "Internal portage error, terminating" + if len(e[0]): + print red("!!!"), e + sys.exit(2) + except ValueError, e: + if isinstance(e[0],list): + print red("!!!"), "Ambiguous package name \"%s\"" % query + print red("!!!"), "Please use one of the following long names:" + for p in e[0]: + print red("!!!"), " "+p + else: + print red("!!!"), "Internal portage error, terminating" + if len(e[0]): + print red("!!!"), e[0] + sys.exit(2) + function = globals()[action] + function(query, matches) + +if __name__ == "__main__": + try: + main() + except KeyboardInterrupt: + print "Operation Aborted!" + + diff --git a/deprecated/etcat/etcat.1 b/deprecated/etcat/etcat.1 new file mode 100644 index 0000000..6704f3b --- /dev/null +++ b/deprecated/etcat/etcat.1 @@ -0,0 +1,79 @@ +.TH "etcat" "1" "0.1.4" "Alastair Tse " "Gentoo Administration" +.SH "NAME" +.LP +etcat \- Gentoo: Portage Information Extractor +.SH "SYNTAX" +.LP +etcat [\fIoption\fP|command] <\fIquery|package\fP> + +.SH "DESCRIPTION" +.LP +etcat tries to complement the existing portage related tools but geared specifically for the power user. It enables users and developers to quickly find out information on particular packages without resorting to manually poking the portage tree and portage database. + +.LP +More specifically, it lists the versions available highlighted by their status (stable/testing/masked/install) for a package, lists use flags per package with descriptions, calculates the installed size of a package and also outputs the relevent entries in the changelog related to the package version. + +.LP +It also employes a smarter package query syntax than emerge where examples such as: +.LP .IP +mozilla\-1.1 +.br +mozilla\-1.* +.LP +are accepted. + +.SH "OPTIONS" +.LP +\fB\-b\fR <\fI/path/to/file\fR> [\fIcategory\fR] +.br +\fBbelongs\fR <\fI/path/to/file\fR> [\fIcategory\fR] +.IP +Searches for the package which a file belongs to with an option to restrict a search to a single or multiple category. Wildcards in the category name is accepted to speed up searching. (eg. etcat belongs /usr/lib/libmpeg.so "media\-*") + +.LP +\fB\-c\fR <\fIpackage[\-version]\fR> +.br +\fBchanges\fR <\fIpackage[\-version]\fR> +.IP +Outputs ChangeLog entry for the package and version specified. Uses the latest package version if none specified. + +.LP +\fB\-d\fR <\fIregex expression\fR> +.br +\fBdepends\fR <\fIregex expression\fR> +.IP +Searches through portage for a dependency string satisfying that regular expression. + +.LP +\fB\-f\fR <\fIpackage[\-version]\fR> +.br +\fBfiles\fR <\fIpackage[\-version]\fR> +.IP +Lists all the files installed for this package. + +.LP +\fB\-s\fR <\fIpackage\fR> +.br +\fBsize\fR <\fIpackage\fR> +.IP +Outputs the installed size of the package. + +.LP +\fB\-u\fR <\fIpackage[\-version]\fR> +.br +\fBuses\fR <\fIpackage[\-version]\fR> +.IP +Outputs the USE flags supported by this package and also their installed state and description. + +.LP +\fB\-v\fR <\fIpackage\fR> +.br +\fBversions\fR <\fIpackage\fR> +.IP +Output all the versions for packages that match the \fIpackage\fR name given with indication of whether the packages is stable, masked, unstable or installed. +.SH "SEE ALSO" +.LP +Type \fBetcat\fR for examples and more information +.SH "AUTHORS" +.LP +Alastair Tse diff --git a/deprecated/genpkgindex/Makefile b/deprecated/genpkgindex/Makefile new file mode 100644 index 0000000..9f0ea2c --- /dev/null +++ b/deprecated/genpkgindex/Makefile @@ -0,0 +1,18 @@ +# Copyright 2004 Karl Trygve Kalleberg +# Copyright 2004 Gentoo Technologies, Inc. +# Distributed under the terms of the GNU General Public License v2 +# +# $Header$ + +include ../../makedefs.mak + +all: + echo "ABWONG (AB-wong vb.) To bounce cheerfully on a bed." + +dist: + mkdir -p ../../$(distdir)/src/genpkgindex + cp Makefile genpkgindex genpkgindex.1 ../../$(distdir)/src/genpkgindex/ + +install: + install -m 0755 genpkgindex $(bindir)/ + install -m 0644 genpkgindex.1 $(mandir)/ diff --git a/deprecated/genpkgindex/genpkgindex b/deprecated/genpkgindex/genpkgindex new file mode 100644 index 0000000..c079b83 --- /dev/null +++ b/deprecated/genpkgindex/genpkgindex @@ -0,0 +1,336 @@ +#!/usr/bin/python +# Copyright 2006-2007 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 + + +import os +import stat +import sys +import time +import getopt +from stat import * + +if getattr(__builtins__, "set", None) is None: + from sets import Set as set + +for x in ['CFLAGS','CXXFLAGS', 'LDFLAGS','USE']: + os.environ[x] = '' +del x + +os.environ["USE_EXPAND"] = "-*" + +import portage + +try: + import portage.xpak as xpak + import portage.checksum as portage_checksum + import portage.dep as portage_dep + import portage.util as portage_util + import portage.const as portage_const +except ImportError: + import xpak + import portage_checksum + import portage_dep + import portage_util + import portage_const + +compress = bool(os.environ.get("COMPRESSPKGFILE", '')) +pkgdir = portage.settings["PKGDIR"] +opt_args_short="hqvcP:" +opt_args_long=["help", "quiet", "verbose", "compress", "pkgdir"] +quiet = False +verbose = False + +def usage(): + print portage.output.green("Usage:")+"\t"+portage.output.yellow("genpkgindex")+" -"+portage.output.blue("["+opt_args_short+"]") + print portage.output.white(" Options:")+" --"+" --".join(opt_args_long) + sys.exit(1) + +def update_pkgdir(): + if not os.path.exists(portage.settings["PKGDIR"]+"/All"): + return + + os.chdir(portage.settings["PKGDIR"]+"/All") + for x in os.listdir("."): + pkg = os.path.basename(x) + if pkg[-5:] != ".tbz2": + continue + + mode = os.lstat(pkg)[ST_MODE] + if not S_ISREG(mode): + if S_ISLNK(mode): + if not os.path.exists(os.readlink(x)): + if verbose: + portage.writemsg(portage.output.yellow(" * ")+"Removing broken symlink: "+x+"\n") + os.unlink(x) + continue + tbz2 = xpak.tbz2(pkg) + data = tbz2.getboth() + cat = xpak.getitem(data, "CATEGORY") + cat = cat[:-1] + if not os.path.exists("../"+cat): + os.mkdir("../"+cat) + if os.path.exists("../"+ cat + "/" + pkg): + os.unlink("../"+ cat + "/" + pkg) + os.rename(pkg, "../"+ cat + "/" + pkg) + os.symlink("../"+ cat + "/"+ pkg, pkg) + +def grabpkgnames(dirp): + names = [] + categories = portage.grabfile(portage.settings["PORTDIR"]+"/profiles/categories") + os.chdir(dirp) + for cat in os.listdir('.'): + if cat in categories: + for pkg in os.listdir(cat): + if os.path.basename(pkg).endswith("tbz2"): + names.append(cat+"/"+pkg) + names.sort() + return names + +def cleanxfiles(dirp): + global verbose + # Clean up stale cache files + os.chdir(portage_const.CACHE_PATH+"/xpak") + for pkg in os.listdir('.'): + p = os.path.basename(pkg) + if not p.endswith(".xpak"): + continue + tbz2 = xpak.tbz2(p) + stuff = tbz2.getboth() + cat = xpak.getitem(stuff, "CATEGORY") + if not os.path.exists(dirp + "/" + cat[:-1] + "/" + p[:-5] + ".tbz2"): + # tidy up + if verbose: + portage.writemsg(portage.output.yellow(" * ") + "Stale entry: " + dirp + "/" + cat[:-1] + "/" + p[:-5] + ".tbz2\n") + os.unlink(p) + os.unlink(p[:-5]+".md5") + +def cleanpkgdir(): + if os.path.exists("/usr/bin/eclean"): + os.system("/usr/bin/eclean -d packages") + + +def parseargs(): + global pkgdir + global compress + global verbose + global quiet + + if portage.settings.get("NOCOLOR") not in ("yes","true"): + portage.output.havecolor = 1 + else: + portage.output.havecolor = 0 + + # Parse the cmdline. + try: + opts, args = getopt.getopt(sys.argv[1:], opt_args_short, opt_args_long) + except getopt.GetoptError: + usage() + sys.exit(2) + + for opt, optarg in opts: + if opt in ("-v", "verbose"): + verbose = True + if opt in ("-h", "--help"): + usage() + if opt in ("-c", "--compress"): + compress = True + if opt in ("-q", "--quiet"): + quiet = True + if opt in ("-P", "--pkgdir"): + pkgdir = optarg + + if "cleanpkgdir" in portage.settings["FEATURES"]: + cleanpkgdir() + +def serialize_depset(src, context='and'): + l = [] + if not src: + return '' + if isinstance(src, basestring): + return src + i = iter(src) + for x in i: + if isinstance(x, basestring): + if x != '||': + l.append(x) + continue + x = i.next() + if len(x) == 1: + l.append(serialize_depset(x[0])) + else: + l.append("|| ( %s )" % serialize_depset(x)) + else: + # and block. + if context == 'and': + v = serialize_depset(x, context=context) + if v.strip(): + l.append(v) + else: + v = serialize_depset(x, context='or') + if v.strip(): + l.append("( %s )" % v.strip()) + return ' '.join(l) + +def getallpkgs(): + packages = [] + os.chdir(pkgdir) + for pkg in grabpkgnames(pkgdir): + + st = os.stat(pkg) + + if not os.path.exists(portage_const.CACHE_PATH+"/xpak/"): + os.mkdir(portage_const.CACHE_PATH+"/xpak/") + + fname = portage_const.CACHE_PATH+"/xpak/"+os.path.basename(pkg)[:-5]+".xpak" + + if os.path.exists(fname): + if st.st_mtime != os.stat(fname).st_mtime: + #print "unlinking "+fname + os.unlink(fname) + + if not os.path.exists(fname): + tbz2 = xpak.tbz2(pkg) + xpdata = xpak.xpak_mem(tbz2.get_data()) + fp = open(fname, "w") + fp.write(xpdata+xpak.encodeint(len(xpdata))+"STOP") + fp.close() + + chksum = portage_checksum.perform_md5(pkg) + fp = open(fname[:-5]+".md5", "w") + fp.write(chksum) + fp.close() + + os.utime(fname, (st.st_mtime, st.st_mtime)) + + else: + if os.path.exists(fname[:-5]+".md5"): + chksum = "".join(portage.grabfile(fname[:-5]+".md5")) + else: + chksum = portage_checksum.perform_md5(pkg) + + tbz2 = xpak.tbz2(fname) + + packages.append((pkg, tbz2, chksum, st)) + return packages + +def genpkgindex_header(fp, packages): + import re + profilever = os.path.normpath("///"+os.readlink("/etc/make.profile")) + basepath = os.path.normpath("///"+portage.settings["PORTDIR"]+"/profiles") + if re.match(basepath,profilever): + profilever = profilever[len(basepath)+1:] + else: + profilever = "!"+profilever + del basepath + + timestamp = str(time.time()).split(".")[0] + fp.write("# This file was auto generated by " + os.path.basename(sys.argv[0]) + "\n") + if pkgdir == portage.settings["PKGDIR"]: + fp.write("PROFILE: "+profilever+"\n") + fp.write("PACKAGES: "+str(len(packages)) +"\n") + fp.write("TIMESTAMP: "+timestamp+"\n") + + vmask = [ "AUTOCLEAN", "DISTDIR", "PKGDIR", "PORTDIR" , "PORTAGE_TMPDIR" , "PORTAGE_RSYNC_OPTS" ] + variables = portage_util.grabfile(portage.settings["PORTDIR"]+"/profiles/info_vars") + variables = [v for v in variables if v not in vmask] + variables.sort() + + for var in variables: + if var in portage.settings: + if (len(portage.settings[var])): + fp.write(var+": "+portage.settings[var]+"\n") + else: + fp.write("PACKAGES: "+str(len(packages)) +"\n") + fp.write("TIMESTAMP: "+timestamp+"\n") + fp.write("\n") + +def genpkgindex(packages): + os.chdir(pkgdir) + control_file = ".Packages" + fp = open(control_file, "w") + genpkgindex_header(fp, packages) + + for pkg, tbz2, chksum, st in packages: + stuff = tbz2.getboth() + if not stuff: + print "Not a tbz2: "+str(pkg) + continue + + cat = xpak.getitem(stuff, "CATEGORY") + + use = xpak.getitem(stuff, "USE") + if use is None: + use = '' + iuse = xpak.getitem(stuff, "IUSE") + if iuse is None: + iuse = '' + + s = xpak.getitem(stuff, "DESCRIPTION") + if s is not None: + s = ' '.join(s.split()) + if s: + fp.write("DESC: %s\n" % s) + # drop '.tbz2' + fp.write("CPV: %s/%s\n" % (cat.strip(), os.path.basename(pkg[:-5]))) + s = xpak.getitem(stuff, "SLOT") + if s is not None: + s = ' '.join(s.split()) + if s and s != "0": + fp.write("SLOT: %s\n" % s) + + split_use = use.split() + for name in ("LICENSE", "RDEPEND", "PDEPEND", "PROVIDE"): + item = xpak.getitem(stuff, name) + if item is None: + continue + val = portage_dep.use_reduce(portage_dep.paren_reduce(' '.join(item.split())), uselist=split_use) + if val: + fp.write("%s: %s\n" % (name, serialize_depset(val))) + + # map IUSE->USE and look for matching flags, filter dupes + # if both flags match then this is what matters. + s = set(split_use).intersection(iuse.split()) + if s: + l = list(s) + l.sort() + fp.write("USE: %s\n" % ' '.join(l)) + + fp.write("SIZE: "+ str(st[stat.ST_SIZE]) +"\n") + fp.write("MD5: "+chksum+"\n") + fp.write("\n") + + fp.write("\n") + fp.flush() + fp.close() + + if (compress): + os.system("bzip2 < .Packages > .Packages.bz2") + os.rename(".Packages.bz2", "Packages.bz2") + else: + if os.path.exists("Packages.bz2"): + os.unlink("Packages.bz2") + + os.rename(".Packages", "Packages") + + +def main(): + update_pkgdir() + + parseargs() + + if not quiet: + portage.writemsg(portage.output.green(' * ')+'Update binary package index %s/Packages\n' % pkgdir); + + start = time.time() + packages = getallpkgs() + genpkgindex(packages) + cleanxfiles(pkgdir) + finish = time.time() + + if not quiet: + portage.writemsg(portage.output.green(' * ')+"PKGDIR contains "+ str(len(packages)) + ' packages. (%.01fsec)\n' % (finish - start)); + + +if __name__ == "__main__": + main() diff --git a/deprecated/genpkgindex/genpkgindex.1 b/deprecated/genpkgindex/genpkgindex.1 new file mode 100644 index 0000000..8a3956e --- /dev/null +++ b/deprecated/genpkgindex/genpkgindex.1 @@ -0,0 +1,59 @@ +.TH "genpkgindex" "1" "" "Ned Ludd" "gentoolkit" +.SH "NAME" +.LP +genpkgindex \- Generates package metadata from binary packages for use with programs such a qmerge from portage\-utils +.SH "USAGE" +.LP +genpkgindex [\fI\-\-options\fP] + +.SH "DESCRIPTION" +.LP +Generates package metadata from binary packages for use with programs such a qmerge from portage\-utils +.SH "OPTIONS" +.LP +.TP +\fB\-h, \-\-help\fR + Display help and exit +.TP +\fB\-v, \-\-verbose\fR + Be verbose +.TP +\fB\-q, \-\-quiet\fR + Be quiet +.TP +\fB\-c, \-\-compress\fR + Compresses the generated metadata with bzip2. +.TP +\fB\-P, \-\-pkgdir \fR + Set the base location of the binary packages. The default is normally /usr/portage/packages +.TP + +.SH "ENVIRONMENT VARIABLES" +.LP +.TP +\fBPKGDIR\fP +is the location of binary packages that you can have created with FEATURES=buildpkg, '\-\-buildpkg' or '\-b/\-B' while emerging a package. +.SH "EXAMPLES" +.LP +Typical usage is to simply run: +.LP +genpkgindex +.LP +Alternatively if you want the metadata compressed: +.LP +genpkgindex \-\-compress +.LP +.SH "NOTES" +.LP +When no package directories are directly given to genpkgindex on the command line it will output additional variables that it assumes from the running portage environment. +.LP +When FEATURES=cleanpkgdir is enabled genpkgindex will invoke "/usr/bin/eclean \-d packages" before creating any package metadata. +.LP +genpkgindex intended use is to be run from /etc/portage/bashrc in the $EBUILD_PHASE of "postinst". +.LP +.SH "AUTHORS" +.LP +Ned Ludd +.SH "SEE ALSO" +.LP +emerge(1) qmerge(1) make.conf(5) portage(5) diff --git a/deprecated/gensync/AUTHORS b/deprecated/gensync/AUTHORS new file mode 100644 index 0000000..389c51b --- /dev/null +++ b/deprecated/gensync/AUTHORS @@ -0,0 +1,5 @@ +Maintainer: +Karl Trygve Kalleberg + +Original Author: +Matthew Schick diff --git a/deprecated/gensync/ChangeLog b/deprecated/gensync/ChangeLog new file mode 100644 index 0000000..7ec2b86 --- /dev/null +++ b/deprecated/gensync/ChangeLog @@ -0,0 +1,12 @@ +2004-09-10 Karl Trygve Kalleberg + * Fixed portage import, fixes #45079. + * Added all sources sync patch from Adam Ashley + , fixes #45079. + * Fixed config dir scanning, suggested by burrelln@colorado.edu, + fixes #47390. + * Applied config file parser fix by Mamoru KOMACHI , + fixes #44777. + +2004-02-08 Karl Trygve Kalleberg + * Initial import + diff --git a/deprecated/gensync/Makefile b/deprecated/gensync/Makefile new file mode 100644 index 0000000..d5b879a --- /dev/null +++ b/deprecated/gensync/Makefile @@ -0,0 +1,24 @@ +# Copyright 2004 Karl Trygve Kalleberg +# Copyright 2004 Gentoo Technologies, Inc. +# Distributed under the terms of the GNU General Public License v2 +# +# $Header$ + +include ../../makedefs.mak + +.PHONY: all +all: + +dist: + mkdir -p ../../$(distdir)/src/gensync/ + cp Makefile AUTHORS README TODO ChangeLog \ + gensync gensync.1 gensync.conf \ + bmg-main.syncsource bmg-gnome-current.syncsource \ + ../../$(distdir)/src/gensync/ + +install: all + install -d $(docdir)/deprecated/gensync + install -m 0755 gensync $(docdir)/deprecated/gensync/ + install -m 0644 AUTHORS README TODO ChangeLog $(docdir)/deprecated/gensync/ + install -m 0644 gensync.1 $(docdir)/deprecated/gensync/ + install -m 0644 gensync.conf bmg-main.syncsource bmg-gnome-current.syncsource $(docdir)/deprecated/gensync/ diff --git a/deprecated/gensync/README b/deprecated/gensync/README new file mode 100644 index 0000000..cf54dec --- /dev/null +++ b/deprecated/gensync/README @@ -0,0 +1,16 @@ + +Package : gensync +Version : 0.1.0 +Author : See AUTHORS + +MOTIVATION + +Gensync handles rsyncing to multiple sync sources. + +MECHANICS + +N/A + +IMPROVEMENTS + +N/A diff --git a/deprecated/gensync/TODO b/deprecated/gensync/TODO new file mode 100644 index 0000000..733a959 --- /dev/null +++ b/deprecated/gensync/TODO @@ -0,0 +1,4 @@ +- Add using cvs to sync +- Update portage cache after sync +- Add overlay dirs defined in /etc/conf.d/gensync to /etc/make.conf +- Sync up with Marius on the multiple overlay code diff --git a/deprecated/gensync/bmg-gnome-current.syncsource b/deprecated/gensync/bmg-gnome-current.syncsource new file mode 100644 index 0000000..51dd908 --- /dev/null +++ b/deprecated/gensync/bmg-gnome-current.syncsource @@ -0,0 +1,18 @@ + +# This id must be unique among all the ids in /etc/gensync/*.syncsource +id="bmg-gnome-current" + +# This is a human-readable description of the source +description="BreakMyGentoo GNOME current" + +# The rsync url +rsync="rsync://rsync.breakmygentoo.net/gnome-current" + +# By default, the overlay directory is set to ${base_overlay}/${id}, +# where base_overlay is picked from /etc/gensync/gensync.conf +# +# You may specify a different relative path, such as +overlay="bmg-gnome-current.alternative" +# +# Or an entirely new absolute path (remeber to create the path first) +#overlay="/my/absolute/path" diff --git a/deprecated/gensync/bmg-main.syncsource b/deprecated/gensync/bmg-main.syncsource new file mode 100644 index 0000000..8d74ca2 --- /dev/null +++ b/deprecated/gensync/bmg-main.syncsource @@ -0,0 +1,18 @@ + +# This id must be unique among all the ids in /etc/gensync/*.syncsource +id="bmg-main" + +# This is a human-readable description of the source +description="BreakMyGentoo main tree" + +# The rsync url +rsync="rsync://rsync.breakmygentoo.net/bmg-overlay" + +# By default, the overlay directory is set to ${base_overlay}/${id}, +# where base_overlay is picked from /etc/gensync/gensync.conf +# +# You may specify a different relative path, such as +overlay="bmg-main.alternative" +# +# Or an entirely new absolute path (remeber to create the path first) +#overlay="/my/absolute/path" diff --git a/deprecated/gensync/gensync b/deprecated/gensync/gensync new file mode 100755 index 0000000..52f25ed --- /dev/null +++ b/deprecated/gensync/gensync @@ -0,0 +1,226 @@ +#!/usr/bin/python +# +# Simple program to rsync from various 3rd party ebuild servers. +# +# +# Copyright (c) 2004, Matthew Schick (original author) +# Copyright (c) 2004, Gentoo Technologies, Inc +# Copyright (c) 2004, Karl Trygve Kalleberg +# +# Distributed under the terms of the GNU General Public License v2 + +__author__ = "Matt Schick , Karl Trygve Kalleberg " +__email__ = "karltk@gentoo.org" +__version__ = "0.1.0" +__productname__ = "gensync" +__description__ = "Gentoo Overlay Sync Tool" + + +import sys +import os +import fileinput + +sys.path.insert(0, "/usr/lib/portage/pym") +import portage + +try: + from portage.output import * +except ImportError: + from output import * + +class ConfigDefaults: + def __init__(self): + self.rsync_timeout = 0 + self.base_overlay = "/usr/local/overlays" + self.confdir = '/etc/gensync' + self._init_from_file() + self._setup_rsync() + def _init_from_file(self): + try: + ins = open("/etc/gensync/gensync.conf") + for x in ins.readlines(): + # Skip line if it's a comment or not well-formed + if x.find("=") == -1 or \ + (len(x) and x[0] == "#"): + continue + (attrib, value) = x.split('=') + attrib = attrib.strip().strip('"') + value = value.strip().strip('"') + if attrib == "rsync_timeout": + self.rsync_timeout = value + elif attrib == "base_overlay": + self.base_overlay = value + except: + pass + + def _setup_rsync(self): + if self.rsync_timeout == 0: + try: + self.rsync_timeout = portage.settings["RSYNC_TIMEOUT"] + except: + self.rsync_timeout = 180 + self.rsync_command = "/usr/bin/rsync " + \ + "-rlptDvz --progress " + \ + "--delete --delete-after " + \ + "--timeout=" + str(self.rsync_timeout) + " " \ + "--exclude='distfiles/*' " + \ + "--exclude='local/*' " + \ + "--exclude='packages/*' " + +Config = ConfigDefaults() + +class SyncSource: + """Contains all details about an upstream rsync source.""" + def __init__(self,filename): + self.id = "#unset#" + self.name = "#unset#" + self.url = "#unset#" + self.overlay = "#unset#" + self._init_from_file(filename) + + if self.overlay == "#unset#": + self.overlay = Config.base_overlay + "/" + self.id + elif len(self.overlay) and self.overlay[0] != "/": + self.overlay = Config.base_overlay + "/" + self.overlay + elif len(self.overlay) and self.overlay[0] == "/": + pass + else: + print "Malformed overlay, '" + self.overlay + "'" + sys.exit(-2) + + def _init_from_file(self, filename): + """Loads configuration settings from a .syncsource file.""" + ins = open(filename) + for x in ins.readlines(): + # Skip line if it's a comment or not well-formed + if x.find("=") == -1 or \ + (len(x) and x[0] == "#"): + continue + (attrib, value) = x.split("=") + attrib = attrib.strip().strip('"') + value = value.strip().strip('"') + if attrib == "id": + self.id = value + elif attrib == "description": + self.name = value + elif attrib == "rsync": + self.url = value + elif attrib == "overlay": + self.overlay = value + def perform_sync(self): + """Syncs with upstream source.""" + cmd = Config.rsync_command + self.url +"/* " + self.overlay + exitcode = portage.spawn(cmd, portage.settings, free=1) + + def dump(self,ous=sys.stdout): + ous.write("id =\"%s\"\n" % (self.id) + \ + "name =\"%s\"\n" % (self.name) + \ + "rsync =\"%s\"\n" % (self.url) + \ + "overlay=\"%s\"\n\n" % (self.overlay)) + +class SyncSourceManager: + """Holds information on all known upstream rsync sources.""" + def __init__(self): + self.sources = [] + self._load_source_info() + def _load_source_info(self): + for x in os.listdir(Config.confdir): + if x.rfind(".syncsource") > 0 and \ + x.endswith(".syncsource"): + ss = SyncSource(Config.confdir + "/" + x) + self.sources.append(ss) + def list_sources(self): + for x in self.sources: + x.dump() + def get_sync_source(self, source_id): + for x in self.sources: + if x.id == source_id: + return x + return None + def get_all_sync_sources(self): + return self.sources + +def print_version(): + print __productname__ + "(" + __version__ + ") - " + \ + __description__ + print "Author(s): " + __author__ + +def print_usage(): + print white("Usage: ") + turquoise(__productname__) + \ + yellow(" ") + green("repo-id-1 repo-id-2 ...") + print "where " + yellow("") + " is one of" + print yellow(" -a, --all-sources") + " - sync all know sources" + print yellow(" -l, --list-sources") + " - list known rsync sources" + print yellow(" -C, --no-color") + " - turn off colours" + print yellow(" -h, --help") + " - this help screen" + print yellow(" -V, --version") + " - display version info" + + +def parse_args(cliargs): + + cmd = "sync-sources" + args = [] + options = [] + + for x in cliargs: + if x in ["-V", "--version"]: + cmd = "print-version" + break + elif x in ["-h", "--help"]: + cmd = "print-usage" + break + elif x in ["-C", "--no-color"]: + options.append("nocolor") + break + elif x in ["-l", "--list-sources"]: + cmd = "list-sources" + elif x in ["-a", "--all-sources"]: + cmd = "all-sources" + else: + args.append(x) + return (cmd, args, options) + +def main(): + + # Setup colors, as per system defaults + if (not sys.stdout.isatty()) or \ + (portage.settings["NOCOLOR"] in ["yes","true"]): + nocolor() + + # Parse arguments + (cmd, args, options) = parse_args(sys.argv[1:]) + + # Turn off color, if specified by cmdline switch + if "nocolor" in options: + nocolor() + + # Initialise sync source manager + ssmgr = SyncSourceManager() + + # Perform selected command + if cmd == "list-sources": + ssmgr.list_sources() + elif cmd == "print-version": + print_version() + elif cmd == "print-usage": + print_usage() + elif cmd == "sync-sources": + for x in args: + repo = ssmgr.get_sync_source(x) + if repo: + print "Syncing '%s' into '%s'" % \ + (repo.id, repo.overlay) + repo.perform_sync() + elif cmd == "all-sources": + for repo in ssmgr.get_all_sync_sources(): + print "Syncing '%s' into '%s'" % \ + (repo.id, repo.overlay) + repo.perform_sync() + else: + print red("Unknown command '" + cmd + "'") + +if __name__ == "__main__": + try: + main() + except KeyboardInterrupt: + print "Operation aborted by user keypress!" diff --git a/deprecated/gensync/gensync.1 b/deprecated/gensync/gensync.1 new file mode 100644 index 0000000..17d85fc --- /dev/null +++ b/deprecated/gensync/gensync.1 @@ -0,0 +1,75 @@ +.TH gensync 1 "0.1.0" "Gentoolkit" "Gentoo Administration" +.SH "NAME" +.LP +gensync \- Gentoo: Overlay Sync Tool +.SH "SYNTAX" +.LP +gensync [\fIoption\fP] <\fIrepo-id-1 repo-id-2 ...\fP> + +.SH "DESCRIPTION" + +.LP + +\fIgensync\fR synchronises your machine against an upstream repository +of ebuild files, called a sync source. Normally, Portage will only +synchronise against the main Portage tree maintained by the Gentoo +project. However, there exist development trees with auxiliary ebuild +files that may occasionally be of interest to the adventurous power +user, such as the \fIbreakmygentoo.net\fR sync source. + +This tool can be used to synchronise against these alternative sync +sources. + +.SH "OPTIONS" +.LP +\fB\-l\fR +.br +\fB--list-sources\fB +.IP +List available sync sources known to \fIgensync\fR. + +.LP +\fB\-V\fR +.br +\fB--version\fB +.IP +Display version information and exit. + +.LP +\fB\-C\fR +.br +\fB--no-color\fB +.IP +Turn off colors. + +.LP +\fB\-h\fR +.br +\fB\--help\fR +.IP +Display help. + +.SH "CONFIGURATION FILES" +.LP +\fB/etc/gensync/gensync.conf\fR +.IP +The main configuration file, commented and self-explanatory + +.LP +\fB/etc/gensync/*.syncsource\fR +.IP +Per-sync source configuration files, describing the sync source to +\fIgensync\fR. + + +.SH "SEE ALSO" +.LP +The rest of the utilities in \fIapp-portage/gentoolkit-dev\fR, such as +\fIechangelog\fR, \fIebump\fR and \fIego\fR. + +.SH "AUTHORS" +.LP +Matthew Schick (original author) +.br +Karl Trygve Kalleberg + diff --git a/deprecated/gensync/gensync.conf b/deprecated/gensync/gensync.conf new file mode 100644 index 0000000..389e020 --- /dev/null +++ b/deprecated/gensync/gensync.conf @@ -0,0 +1,8 @@ + +# By default, we ask Portage about the preferred timeout +#rsync_timeout = 180 + +# Normally, each sync source will be placed under +# ${base_overlay}/${syncsource-id}, where the 'syncsource-id' is a unique +# identifier, specified inside the individual .syncsource file +base_overlay = /usr/local/overlays diff --git a/deprecated/lintool/AUTHORS b/deprecated/lintool/AUTHORS new file mode 100644 index 0000000..fe436cb --- /dev/null +++ b/deprecated/lintool/AUTHORS @@ -0,0 +1 @@ +Karl Trygve Kalleberg diff --git a/deprecated/lintool/COPYING b/deprecated/lintool/COPYING new file mode 100644 index 0000000..60549be --- /dev/null +++ b/deprecated/lintool/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/deprecated/lintool/ChangeLog b/deprecated/lintool/ChangeLog new file mode 100644 index 0000000..0e8c1e9 --- /dev/null +++ b/deprecated/lintool/ChangeLog @@ -0,0 +1,71 @@ +2004-02-18 Karl Trygve Kalleberg + * Moved from separate CVS module to be part of gentoolkit-dev + +2002-10-31 Karl Trygve Kalleberg + * Fixed \$Header$ comment + * Fixed off-by-one in line numbering + +2002-10-30 Karl Trygve Kalleberg + * Now defaults to showing all details + * Added --no-details + * Better LICENSE parsing + * Better references to policy. + * Line numbers for whitespace testing. + * Released 0.2.4 + +2002-08-12 Karl Trygve Kalleberg + * Added more header tests + * Added initial tests for SLOT, KEYWORD and LICENSE + +2002-08-10 Karl Trygve Kalleberg + * Spurious space checker works again. + * Added Makefile, COPYING, README, AUTHORS, NEWS + +2002-07-22 Karl Trygve Kalleberg + * Changed A=${P}.tar.gz check to ^A=.*, as per Seemant's suggestion. + +2002-07-17 Karl Trygve Kalleberg + * Added TestLicense to ebuild.py + * Added --aux-license-dir= + * Added MunchieFormatter + * Added --formatter= + +2002-07-10 Karl Trygve Kalleberg + * Refactored; split tests into changelog, digest and ebuild-specific + * Added TestSyntax test to digest.py + * Added TestHeaders, TestConstructPresence, TestIndentation to + changelog.py + +2002-05-15 Karl Trygve Kalleberg + + * Fixed test for Author: and Maintainer: to warn about their + deprecation and recommend the use of ChangeLog instead. + * Added (E) and (W) prefixes to messages printed by --show-details + * Added --tests=- to allow turning off a + particular test easily. + * Added statistics output at the bottom. + * Updated man page to reflect new option feature. + * Fixed the --show-details, --show-separate annoyance. + * Fixed use flags parsing to disregard some false positives. + +2002-05-13 Karl Trygve Kalleberg + * Fixed --list-tests which was incorrectly --listTests + +2002-04-30 Karl Trygve Kalleberg + * Added 's cleanups + * Improved error reporting; now separates into errors and + warnings. + * Improved TestSpaces to check for non-conformant + line-continuations. + * Added TestUseFlags that checks that an ebuild only uses + sanctioned use flags (read from /usr/portage/profiles/use.desc) + * Added SLOT= to list desired env vars (warns if missing) + * Added LICENSE= to list of required env vars (errors if missing) + * Improved error messages + * Added --tests= option to allow the user to specify which tests + to run + * Added --list-tests option that lists available tests + * Updated man page. + +2002-03-22 Karl Trygve Kalleberg + * Added this ChangeLog diff --git a/deprecated/lintool/NEWS b/deprecated/lintool/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/deprecated/lintool/README b/deprecated/lintool/README new file mode 100644 index 0000000..1494aad --- /dev/null +++ b/deprecated/lintool/README @@ -0,0 +1,23 @@ + +Package: Lintool +Version: 0.1.3 +Author : Karl Trygve Kalleberg + + +MOTIVATION + +Lintool is a "lint" utility for the Gentoo Linux distribution. It is a +tool that tests ebuilds, changelogs and package digests for +well-formedness. It's intended to aid Gentoo Linux developers avoid most +common mistakes when packaging software for Gentoo. + +MECHANICS + +To check an ebuild, do lintool --ebuild +To check a ChangeLog, do lintool --changelog +To check a package digest, do lintoo --digest + +IMPROVEMENTS + +Any suggestions for improvements should be sent to karltk@gentoo.org, or +added as a bug assigned to me. diff --git a/deprecated/lintool/lintool.1 b/deprecated/lintool/lintool.1 new file mode 100644 index 0000000..11883e8 --- /dev/null +++ b/deprecated/lintool/lintool.1 @@ -0,0 +1,41 @@ +.TH lintool "1" "March 2002" "gentoolkit 0.1.3" +.SH NAME +lintool \- manual page for the lintool program, a program that checks the +santity of ebuild scripts. +.SH SYNOPSIS +.B lintool +\fI\fR \fIebuilds...\fR +.SH DESCRIPTION +Lintool checks if a set of +.I ebuilds +conforms to the ebuild style guide. This is not +(yet) an exhaustive test, so your ebuild might be broken even if lintool +thinks it's okay. +.PP +.SH OPTIONS +.TP +\fB--no-summary\fI +Turn off total summary for all tests run on all ebuilds. +.TP +\fB--show-separate\fI +Show short summary of tests for each ebuild checked. +.TP +\fB--show-details\fI +Show full details of tests for each ebuild checked +.TP +\fB--tests=test1,test2,..\fI +Run only the tests specified to this option. Default is to run all +tests. One can turn off a particular test by pretending it with minus (e.g. +.I --tests=-TestUseFlags,-TestSpaces +). A list of tests can be obtained from +.I --list-tests +.TP +\fB--list-tests\fI +List available tests. +.SH AUTHORS +Karl Trygve Kalleberg , 2002 +.SH "SEE ALSO" +ebuild(5) +.TP +The \fI/usr/sbin/lintool\fR script. + diff --git a/deprecated/lintool/lintool.py b/deprecated/lintool/lintool.py new file mode 100755 index 0000000..721c744 --- /dev/null +++ b/deprecated/lintool/lintool.py @@ -0,0 +1,320 @@ +#! /usr/bin/python +# +# Copyright 2002 Gentoo Technologies, Inc +# Distributed under the terms of the GNU General Public License v2.0 +# Author Karl Trygve Kalleberg +# +# About: +# lintool aims to check the stylistic and syntactical correctness for +# ebuilds, changelogs and digest files for the Gentoo packaging system. +# +# TODO +# +# - Make HTMLFormatter +# + +VERSION="0.2.4" + +import sys +import getopt + +from lintool import ebuild, changelog, digest + +class TextFormatter: + def section(self, s): + print "\n" + "-"*79 + print " " + s + "\n" + def bullet(self, s): + print "* " + s + def sub(self, s): + print "- " + s + def subwarn(self, s): + print "- (W) " + s + def suberr(self, s): + print "- (E) " + s + def subsub(self, s): + print " |" + s + def subsubwarn(self, s): + print " (W) |" + s + def subsuberr(self, s): + print " (E) |" + s + def line(self,s): + print s + def div(self, left, right): + l = len(left) + r = len(right) + return left + " " * (78-l-r) + right + +class MunchieFormatter: + def section(self, s): + print "[lintool] " + "-" * (78 - len("[lintool] ")) + print "[lintool] " + s + "\n" + def bullet(self, s): + print "[lintool] * " + s + def sub(self, s): + print "[lintool] - " + s + def subwarn(self, s): + print "[lintool] - (W) " + s + def suberr(self, s): + print "[lintool] - (E) " + s + def subsub(self, s): + print "[lintool] |" + s + def subsubwarn(self, s): + print "[lintool] (W) |" + s + def subsuberr(self, s): + print "[lintool] (E) |" + s + def line(self,s): + print "[lintool] " + s + def div(self, left, right): + l = len("[lintool] " + left) + r = len(right) + return left + " " * (78-l-r) + right + +formatters = { "text" : TextFormatter(), "munchie" : MunchieFormatter() } + +def extractFilename(path): + return path + +def runTests(tests,results,ins): + for j in tests: + j.reset() + + ln = 1 + for i in ins.readlines(): + for j in tests: + j.checkLine(i, ln) + ln += 1 + + hasWarning = 0 + hasError = 0 + for j in xrange(len(tests)): + if tests[j].hasErrors(): + results[j][0] += 1 + hasError = 1 + if tests[j].hasWarnings(): + results[j][1] += 1 + hasWarning = 1 + return (hasError, hasWarning) + +def showStatus(options,tests,formatter,file): + if options['showDetails'] or options['showSeparate']: + formatter.section("Status for " + file) + for j in tests: + if options['showSeparate'] or options['showDetails']: + l = len(j.getDesc()) + formatter.bullet(formatter.div(j.getDesc(), ": " + j.getStatus())) + if options['showDetails']: + j.report() + elif options['showShort']: + allOK = 1 + for j in tests: + if j.hasErrors(): + allOK = 0 + break + if allOK: + formatter.div(file, ": OK") + else: + formatter.div(file, ": Not OK") + # else fall through the bottom + +def usage(opts): + print sys.argv[0], "[options] ebuild [ebuild ebuild ... ]" + print + + if opts: + print "Where [options] include:" + for (short,long_,desc) in opts: + short_ = '' + for s in short: + short_ = short_ + '-' + s + ',' + long_ = '--' + long_ + opt = short_ + long_ + opt = opt.rjust(18) + print opt + ' ' + desc + print + +def parse_opts(argv): + options = { 'showSeparate': 0, + 'showTotal': 1, + 'showDetails': 1, + 'showShort': 1, + 'listTests': 0, + 'desiredTests': 0, + 'testMode' : "ebuild", + 'licenseDirs' : [ "/usr/portage/licenses" ], + 'formatter' : 'text' + } + + opts = (('', 'show-separate', + 'Show short summary of tests for each ebuild checked'), + + ('v', 'version', + 'Show program version'), + + ('', 'no-summary', + 'Do not show total summary'), + + ('', 'no-details', + 'Do not show full details of tests for each ebuild checked'), + + ('', 'ebuild', + 'Files to check are ebuilds'), + + ('', 'changelog', + 'Files to check are changelogs'), + + ('', 'digest', + 'Files to check are digests'), + + ('', 'tests=', + 'Comma-separated list of tests to run'), + + ('', 'list-tests', + 'List available tests'), + + ('', 'from-file=', + 'Read ebuilds from '), + + ('', 'formatter=', + "Use 'text' (default) or 'munchie' formatter"), + + ('', 'aux-license-dir=', + 'Add to directories to search for licenses'), + + ('?h', 'help', + 'Show this help'), + ) + + short_options = '' + long_options = [] + for (short,long_,desc) in opts: + short_options = short_options + short + if '=' in long_: + long_ = long_.split('=', 1)[0] + '=' + long_options.append(long_) + + try: + (option_list,args) = getopt.getopt(sys.argv[1:], short_options, long_options) + except getopt.GetoptError, details: + print 'Error parsing command line:',str(details) + sys.exit(1) + + for (option,value) in option_list: + if option in [ '--no-details' ]: + options['showShort'] = 1 + options['showDetails'] = 0 + elif option in [ '--show-separate' ]: + options['showShort'] = 0 + options['showSeparate'] = 1 + elif option in [ '--no-summary']: + options['showTotal'] = 0 + elif option in [ '--from-file' ]: + lines = open(value, 'r').readlines() + lines = [o.strip() for o in lines] + args = lines + args + elif option in [ '--tests' ]: + options['desiredTests'] = value.split(",") + elif option in [ '--formatter' ]: + options['formatter'] = value + elif option in [ '--list-tests' ]: + options['listTests'] = 1 + elif option in [ '--ebuild' ]: + options['testMode'] = 'ebuild' + elif option in [ '--changelog' ]: + options['testMode'] = 'changelog' + elif option in [ '--digest' ]: + options['testMode'] = 'digest' + elif option in [ '--aux-license-dir' ]: + options['licenseDirs'].append(value) + elif option in [ '-v', '--version' ]: + print "Lintool " + VERSION + sys.exit(0) + elif option in [ '-h', '-?', '--help' ]: + usage(opts) + sys.exit(0) + else: + # shouldn't ever happen. better to be safe + print "Unknown option - '%s'!" % (option) + sys.exit(1) + + return (options,args) + +def main(): + (options,args) = parse_opts(sys.argv[1:]) + + formatter = formatters[options['formatter']] + + # Get test suite for given mode + if options['testMode'] == "ebuild": + available_tests = ebuild.getTests(formatter, options) + elif options['testMode'] == "changelog": + available_tests = changelog.getTests(formatter, options) + elif options['testMode'] == "digest": + available_tests = digest.getTests(formatter, options) + + # List available tests, if that was the users request + if options['listTests']: + maxlen = 0 + for i in available_tests: + maxlen = max(len(i.__class__.__name__), maxlen) + for i in available_tests: + n = i.__class__.__name__ + print n + " " * (maxlen - len(n)) + " - " + i.getDesc() + + # Quit with short usage string, if no params given + if len(args) == 0: + usage(None) + sys.exit(1) + + # Create final list of tests to run + tests = [] + notTests = [] + if options['desiredTests']: + for i in options['desiredTests']: + for j in available_tests: + if len(i) and i[0] == "-": + notTests.append(i[1:]) + if j.__class__.__name__ == i: + tests.append(j) + else: + tests = available_tests + + if len(notTests): + for i in available_tests: + if i.__class__.__name__ not in notTests: + tests.append(i) + + results = [[0, 0] for x in range(len(tests))] + + # Set up for test run + numFiles = 0 + totalErrors = 0 + totalWarnings = 0 + + # Iterate through all files given as arguments, testing each file + # against the final list of tests + for i in args: + fn = extractFilename(i) + ins = open(i, "r") + numFiles += 1 + (hasError, hasWarning) = runTests(tests,results,ins) + totalErrors += hasError + totalWarnings += hasWarning + showStatus(options,tests,formatter,fn) + + # Show totals, if options allow it + if options['showTotal']: + formatter.section(formatter.div("Summary for all " + str(numFiles) + " " + options['testMode'] + "(s) checked", "#errors/warns")) + for i in xrange(len(tests)): + l = len(tests[i].getDesc()) + formatter.line(formatter.div(tests[i].getDesc(), ": %3d / %3d" % (results[i][0], results[i][1]))) + formatter.line(formatter.div("Total number of ebuilds with errors", \ + "%3d (%3d%%)" % (totalErrors, totalErrors*100/numFiles))) + formatter.line(formatter.div("Total number of ebuilds with warnings", \ + "%3d (%3d%%)" % (totalWarnings, totalWarnings*100/numFiles))) + if totalErrors: + sys.exit(1) + +if __name__ == "__main__": + main() + diff --git a/deprecated/lintool/lintool/__init__.py b/deprecated/lintool/lintool/__init__.py new file mode 100644 index 0000000..4d2e3a6 --- /dev/null +++ b/deprecated/lintool/lintool/__init__.py @@ -0,0 +1,3 @@ +import ebuild +import changelog +import digest diff --git a/deprecated/lintool/lintool/changelog.py b/deprecated/lintool/lintool/changelog.py new file mode 100644 index 0000000..1dad779 --- /dev/null +++ b/deprecated/lintool/lintool/changelog.py @@ -0,0 +1,105 @@ +# Copyright 2002 Gentoo Technologies, Inc +# Distributed under the terms of the GNU General Public License v2.0 +# Author Karl Trygve Kalleberg + +from test import Test, Regex +import re + +class TestHeaders(Test): + def __init__(self, formatter,options): + Test.__init__(self,formatter,options) + self.desc = "Testing for malformed headers" + self.re = [ (1, # append result of regex match + re.compile("^(# Copyright 1999-(2000|2001).*)"), + "Suspect copyright year"), + (1, + re.compile("^(# /home.*)"), + "Suspect path in header"), + (0, # don't append result of regex match + re.compile("^(# Author.*)"), + "Use of Author field in the header is deprecated. Put name in ChangeLog"), + (0, + re.compile("^(# Maintainer.*)"), + "Use of Maintainer field in the header is deprecated. Put name in ChangeLog"), + (1, + re.compile("^(# /space.*)"), + "Suspect path in header")] + + def checkLine(self, s, ln): + for i in self.re: + k = i[1].match(s) + if k and i[0]: + self.warnings.append(i[2] + ": " + k.groups()[0] ) + elif k and not i[0]: + self.warnings.append(i[2]) + + def report(self): + if len(self.warnings): + self.formatter.subwarn("Has illegal or suspect headers:") + for i in self.warnings: + self.formatter.subsub(i) + +class TestConstructPresence(Test): + + def __init__(self, formatter,options): + Test.__init__(self,formatter,options) + self.desc = "Testing for presence of required constructs" + self.required = [ ["# ChangeLog for " + Regex.category + "/" + Regex.PN, + None, + None, + "proper ChangeLog line" + ], + + ["\*" + Regex.P + " \([0-9]+ [A-Z][a-z][a-z] 2002\).*", + None, + None, + "proper release entry on the form *package-1.0.0 (01 Apr 2000)" + ], + + [" [0-9]+ [A-Z][a-z][a-z] 2002; .* <.*@.*> .*:", + None, + None, + "proper changelog entry" + ] + ] + + for i in self.required: + i[1] = re.compile("^(" + i[0] + ")") + + def checkLine(self, s, ln): + for i in self.required: + k = i[1].match(s) + if k: + i[2] = 1 + + def report(self): + for i in self.required: + if not i[2]: + self.formatter.suberr("Missing " + i[3]) + + def hasErrors(self): + for i in self.required: + if not i[2]: + return 1 + +class TestIndentation(Test): + + def __init__(self, formatter,options): + Test.__init__(self,formatter,options) + self.desc = "Testing for proper indentation" + self.re = re.compile("^( |[#*].|\n).*") + + def checkLine(self, s, ln): + k = self.re.match(s) + if not k: + self.errors.append(s) + + def report(self): + for i in self.errors: + print i.replace(' ','%') + +def getTests(formatter,options): + return [ TestHeaders(formatter,options), + TestConstructPresence(formatter,options), + TestIndentation(formatter,options) + ] diff --git a/deprecated/lintool/lintool/digest.py b/deprecated/lintool/lintool/digest.py new file mode 100644 index 0000000..5f174ae --- /dev/null +++ b/deprecated/lintool/lintool/digest.py @@ -0,0 +1,28 @@ +# Copyright 2002 Gentoo Technologies, Inc +# Distributed under the terms of the GNU General Public License v2.0 +# Author Karl Trygve Kalleberg + +from test import Test +import re + +class TestSyntax(Test): + + def __init__(self,formatter,options): + Test.__init__(self,formatter,options) + self.desc = "Testing for correct syntax" + self.re = [ re.compile("^(MD5 [a-z0-9]+ [a-zA-Z0-9_+.-]+ [0-9]+)") ] + self.errors = [] + + def checkLine(self, s, ln): + for i in self.re: + k = i.match(s) + if not k: + self.errors.append("Invalid line in digest\n |" + s) + + def report(self): + for i in self.errors: + self.formatter.suberr(i) + + +def getTests(formatter,options): + return [ TestSyntax(formatter,options) ] diff --git a/deprecated/lintool/lintool/ebuild.py b/deprecated/lintool/lintool/ebuild.py new file mode 100644 index 0000000..c8df0a2 --- /dev/null +++ b/deprecated/lintool/lintool/ebuild.py @@ -0,0 +1,349 @@ +# Copyright 2002 Gentoo Technologies, Inc +# Distributed under the terms of the GNU General Public License v2.0 +# Author Karl Trygve Kalleberg + +from test import Test +import re +import os +import os.path + +class TestSpaces(Test): + + def __init__(self, formatter, options): + Test.__init__(self, formatter, options) + self.desc = "Testing for correct formatting" + self.re_spaces = [ re.compile("^([ ][ ]*)([a-zA-Z\.].*)"), + re.compile("(.*)([ \t]+)\n") ] + self.re_backslash = re.compile("([^#]*\S)((\s\s+|\t))\\\\") + self.reset() + + def checkLine(self, s, ln): + for r in self.re_spaces: + k = r.match(s) + if k: + spcs = k.groups()[1] + rest = k.groups()[0] + self.spaces.append((ln, spcs.replace(" ", "%").replace("\t","%") + rest)) + else: + k = self.re_backslash.match(s) + if k: + head = k.group(1) + spcs = k.group(2) + tail = "\\" + self.backslashes.append((ln, head + len(spcs) * "%" + tail)) + + def hasErrors(self): + return 0 + def hasWarnings(self): + return len(self.spaces) + len(self.backslashes) + + def reset(self): + self.spaces = [] + self.backslashes = [] + + def report(self): + if len(self.spaces): + self.formatter.subwarn("Has illegal space characters (marked by %):") + for i in self.spaces: + self.formatter.subsub("[line " + str(i[0]) + "]:" + i[1]) + if len(self.backslashes): + self.formatter.subwarn("Has illegal white space (marked by %), only one space character allowed:") + for i in self.backslashes: + self.formatter.subsub("[line " + str(i[0]) + "]:" + i[1]) + +class TestHeaders(Test): + + def __init__(self, formatter, options): + Test.__init__(self,formatter, options) + self.desc = "Testing for malformed headers" + self.want = [ [ 0, # count + re.compile("^(# Copyright .*2002.*)"), + "Copyright statement" ], + [ 0, # count + re.compile("^(# " + "\$" + "Header:.*" + "\$)"), # Don't want CVS to fix this + "$" + "Header:" + "$" ], # Don't want CVS to fix this either + [ 0, # count + re.compile("^(# Distributed under the terms of the GNU General Public License.*)"), + "GPL license" ] ] + self.dontwant = [ (1, # append result of regex match + re.compile("^(# Copyright 1999-(2000|2001).*)"), + "Suspect copyright year"), + (1, + re.compile("^(# /home.*)"), + "Suspect path in header"), + (0, # don't append result of regex match + re.compile("^(# Author.*)"), + "Use of Author field in the header is deprecated. Put name in ChangeLog"), + (0, + re.compile("^(# Maintainer.*)"), + "Use of Maintainer field in the header is deprecated. Put name in ChangeLog"), + (1, + re.compile("^(# /space.*)"), + "Suspect path in header")] + + def reset(self): + for i in self.want: + i[0] = 0 + self.errors = [] + self.warnings = [] + + def hasErrors(self): + num_error = 0 + for i in self.want: + if i[0] == 0: + num_error += 1 + return num_error + + def checkLine(self, s, ln): + for i in self.dontwant: + k = i[1].match(s) + if k and i[0]: + self.warnings.append(i[2] + ": " + k.groups()[0] ) + elif k and not i[0]: + self.warnings.append(i[2]) + for i in self.want: + k = i[1].match(s) + if k: + i[0] += 1 + + def report(self): + illegal_headers = len(self.warnings) + for i in self.want: + if i[0] == 0: + illegal_headers += 1 + if illegal_headers: + self.formatter.subwarn("Has illegal or suspect headers:") + for i in self.warnings: + self.formatter.subwarn(i) + for i in self.want: + if i[0] == 0: + self.formatter.suberr("Missing " + i[2]) + +class TestTry(Test): + + def __init__(self,formatter, options): + Test.__init__(self,formatter, options) + self.desc = "Testing for occurence of deprecated try" + self.re = [ re.compile("^([ \t][ \t]*try.*)"), + re.compile("(.*=.* try .*)") ] + + def checkLine(self, s, ln): + for i in self.re: + k = i.match(s) + if k: + self.errors.append(k.groups()[0]) + + def report(self): + if len(self.errors): + self.formatter.suberr("Uses try, which is deprecated") + for i in self.errors: + self.formatter.subsub(i) + +class TestA(Test): + + def __init__(self, formatter, options): + Test.__init__(self,formatter, options) + self.desc = "Testing for superfluous A=${P}.tar.gz" + self.re = re.compile("(^A=.*)") + + def checkLine(self, s, ln): + k = self.re.match(s) + if k: + self.errors.append(k.groups()[0]) + + def report(self): + if len(self.errors): + self.formatter.suberr("Contains superfluous " + self.errors[0]) + +class TestDepend(Test): + + def __init__(self, formatter, options): + Test.__init__(self,formatter, options) + self.desc = "Testing for empty DEPEND" + self.re = re.compile("DEPEND=\"\"") + + def checkLine(self, s, ln): + k = self.re.match(s) + if k: + self.warnings.append("") + + def report(self): + if len(self.warnings): + self.formatter.subwarn("DEPEND is suspiciously empty") + +class TestHomepage(Test): + + def __init__(self, formatter,options): + Test.__init__(self,formatter,options) + self.desc = "Testing for empty HOMEPAGE" + self.re = re.compile("HOMEPAGE=\"\"") + + def checkLine(self, s, ln): + k = self.re.match(s) + if k: + self.warnings.append("") + + def report(self): + if len(self.warnings): + self.formatter.subwarn("Is HOMEPAGE really supposed to be empty ?") + +class TestDescription(Test): + + def __init__(self, formatter, options): + Test.__init__(self,formatter, options) + self.desc = "Testing for empty DESCRIPTION" + self.re = re.compile("DESCRIPTION=\"\"") + + def checkLine(self, s, ln): + k = self.re.match(s) + if k: + self.errors.append("") + + def report(self): + if len(self.errors): + self.formatter.suberr("DESCRIPTION must not be empty") + +class TestEnvVarPresence(Test): + + def __init__(self, formatter, options): + Test.__init__(self,formatter, options) + self.desc = "Testing for presence of env vars" + self.re = [] + self.found = [] + self.required = [ ("SRC_URI", "See 2.4"), + ("DESCRIPTION", "See policy, 2.8"), + ("HOMEPAGE", "See policy, 2.8"), + ("DEPEND", "See policy, 2.2"), + ("LICENSE", "See policy, 2.6"), + ("SLOT", "See policy, 2.5"), + ("KEYWORDS", "See policy, 2.3"), + ("IUSE", "See policy, 2.7") + ] + self.desired = [ ("RDEPEND", "Is RDEPEND == DEPEND ? See policy, 2.2") ] + + + for i in self.required: + self.re.append(re.compile("^(" + i[0] + ")=")) + for i in self.desired: + self.re.append(re.compile("^(" + i[0] + ")=")) + + def checkLine(self, s, ln): + for i in self.re: + k = i.match(s) + if k: + self.found.append(k.group(1)) + + def report(self): + for i in self.required: + if i[0] not in self.found: + self.formatter.suberr("Missing " + i[0] + ". " + i[1]) + for i in self.desired: + if i[0] not in self.found: + self.formatter.subwarn("Missing " + i[0] + ". " + i[1]) + + def hasWarnings(self): + for i in self.desired: + if i[0] not in self.found: + return 1 + + def hasErrors(self): + for i in self.required: + if i[0] not in self.found: + return 1 + +class TestLicense(Test): + def __init__(self, formatter, options): + Test.__init__(self,formatter, options) + self.desc = "Testing for proper LICENSE" + self.re = re.compile("^LICENSE=\"(.*)\"") + self.license_dirs = options['licenseDirs'] + self.licenses = self.loadLicenses() + + def loadLicenses(self): + licenses = [] + for i in self.license_dirs: + try: + candidates = os.listdir(i) + except: + self.formatter.line("!!! License directory '" + i + "' does not exist") + continue + for j in candidates: + if os.path.isfile(i + "/" + j): + licenses.append(j) + return licenses + + def checkLine(self, s, ln): + k = self.re.match(s) + if k: + print k.group(1) + licenses = k.group(1).split(" ") + for i in licenses: + if i not in self.licenses: + self.errors.append("License '" + i + "' not known") + + def report(self): + for i in self.errors: + self.formatter.suberr(i) + +class TestUseFlags(Test): + def __init__(self, formatter, options): + Test.__init__(self,formatter, options) + self.desc = "Testing for sane USE flag usage" + self.re = re.compile("[^#]*use ([a-z0-9\+]+).*") + self.useflags = self.loadUseFlags() + + def loadUseFlags(self): + ins = open("/usr/portage/profiles/use.desc") + rex = re.compile("^([a-z0-9]+)[ \t]+-.*"); + useflags = [] + for i in ins.readlines(): + k = rex.match(i) + if k: + useflags.append(k.group(1)) + return useflags + + def checkLine(self, s, ln): + k = self.re.match(s) + if k: + flag = k.group(1) + if flag not in self.useflags: + l = k.start(1) + # We want to try and figure pretty exactly if we've hit a real instnce + # of the use command or just some random mumbling inside a string + numApostrophes = 0 + numBackticks = 0 + numTicks = 0 + for i in xrange(l,0,-1): + if s[i] == '\"' and (i == 0 or (i > 0 and s[i-1] != '\\')): + numApostrophes += 1 + if s[i] == '\'' and (i == 0 or (i > 0 and s[i-1] != '\\')): + numTicks += 1 + if s[i] == '`' and (i == 0 or (i > 0 and s[i-1] != '\\')): + numBackticks += 1 + + if numApostrophes % 2 == 0: + foundError = 1 + elif numBackticks % 2 and numTicks % 2 == 0: + foundError = 1 + else: + foundError = 0 + + if foundError: + self.errors.append("Unknown USE flag '" + flag + "'") + + def report(self): + for i in self.errors: + self.formatter.suberr(i) + + +def getTests(formatter,options): + return [ TestSpaces(formatter,options), + TestHeaders(formatter,options), + TestTry(formatter,options), + TestA(formatter,options), + TestDepend(formatter,options), + TestHomepage(formatter,options), + TestDescription(formatter,options), + TestEnvVarPresence(formatter,options), + TestUseFlags(formatter,options), + TestLicense(formatter,options) ] diff --git a/deprecated/lintool/lintool/test.py b/deprecated/lintool/lintool/test.py new file mode 100644 index 0000000..0cc56ff --- /dev/null +++ b/deprecated/lintool/lintool/test.py @@ -0,0 +1,30 @@ +# Copyright 2002 Gentoo Technologies, Inc +# Distributed under the terms of the GNU General Public License v2.0 +# Author Karl Trygve Kalleberg + +class Test: + def __init__(self, formatter,options=None): + self.formatter = formatter + self.errors = [] + self.warnings = [] + def reset(self): + self.errors = [] + self.warnings = [] + def hasWarnings(self): + return len(self.warnings) + def hasErrors(self): + return len(self.errors) + def getDesc(self): + return self.desc + def getStatus(self): + if self.hasErrors(): + return "failed" + else: + return "passed" + +class Regex: + PN = "[a-zA-Z_.-]+" + PV = "[a-z0-9A-Z_.-]+" + P = PN + "-" + PV + "(-r[0-9]+)?" + category = "[a-z0-9]+-[a-z0-9]+" + full = category + "/" + P diff --git a/deprecated/moo/AUTHORS b/deprecated/moo/AUTHORS new file mode 100644 index 0000000..fe436cb --- /dev/null +++ b/deprecated/moo/AUTHORS @@ -0,0 +1 @@ +Karl Trygve Kalleberg diff --git a/deprecated/moo/README b/deprecated/moo/README new file mode 100644 index 0000000..e69de29 diff --git a/deprecated/moo/TODO b/deprecated/moo/TODO new file mode 100644 index 0000000..e69de29 diff --git a/deprecated/moo/moo b/deprecated/moo/moo new file mode 100755 index 0000000..828df08 --- /dev/null +++ b/deprecated/moo/moo @@ -0,0 +1,244 @@ +#! /usr/bin/env python2.2 + +import os +import sys +import time +import signal + +CONFDIR="/tmp/moo" + +class Config: + pass + +def die(code, msg): + sys.stdout.write(msg + "\n") + sys.edit(code) + +def printUsage(): + print "Usage: moo [command] \n" + \ + "Where [command] is one of:\n" + \ + "scan - scan for available networks\n" + \ + "list - list available profiles\n"+ \ + "select - select a particular profile\n" + +def scanNetworks(): + pass + +def runCmd(cmd): + if Config.verbosity > 5: + print "Executing \"" + cmd + "\"" + v = os.system(cmd) + if Config.verbosity > 5: + print "Result: " + str(v) + return v + +class ProfileHandler: + def __init__(self): + self.profiles = {} + self._loadProfiles() + def _loadProfiles(self): + for x in os.listdir(CONFDIR+"/profiles"): + if x[-1] != "~" and x[0] != ".": + self.profiles[x] = Profile(CONFDIR+"/profiles/"+x) + def listProfiles(self,detailed=0): + for x in self.profiles.keys(): + if detailed: + print x + ":" + self.profiles[x].dump() + else: + print x + " [" + self.profiles[x].description + "]" + def getProfileNames(self): + return self.profiles.keys() + def getProfile(self,name): + return self.profiles[name] + + +class Profile: + def __init__(self, filename): + self._loadFromFile(filename) + def _loadFromFile(self,filename): + self.desc = "" + self.ifaceName = "" + self.ip = "" + self.broadcast = "" + self.gateway = "" + self.exclusive = "no" + self.netmask = "" + self.nameserver = "" + + ins = open(filename) + for s in ins.readlines(): + for x in ["description","ifaceName","ip","broadcast", + "gateway","exclusive","nameserver","wepkey"]: + if s.find(x+"=") == 0: + val=s.replace(x+"=","").strip() + self.__dict__[x] = val + def dump(self): + print "description = " + self.description + "\n" + \ + "iface = " + self.ifaceName + "\n" + \ + "ip = " + self.ip + "\n" + \ + "broadcast = " + self.broadcast + "\n" + \ + "gateway = " + self.gateway + "\n" + \ + "gateway = " + self.nameserver + "\n" + \ + "exclusive = " + self.exclusive + "\n" + +class Interface: + def __init__(self, name): + self.name = name + self.netmask = "" + self.broadcast = "" + self.ip = "" + self.gateway = "" + self.nameserver = "" + self.wepkey = "" + self._loadIPV4Info() + def _loadIPV4Info(self): + pass + def getNameserver(self): + return self.nameserver + def getNetmask(self): + return self.netmask + def getName(self): + return self.name + def getBroadcast(self): + return self.broadcast + def getWEPKey(self): + return self.wepkey + def getGateway(self): + return self.gateway + def setNameserver(self,nameserver): + self.nameserver = nameserver + def setIP(self, ip): + self.ip = ip + def setWEPKey(self,key): + self.wepkey = key + def setGateway(self,gw): + self.gateway = gw + def setBroadcast(self,broadcast): + self.broadcast = broadcast + def setNetmask(self,netmask): + self.netmask = netmask + def runDHCP(self): + runCmd("dhcpcd " + self.name) + def down(self): + runCmd("ifconfig " + self.name + " down") + pidFile = "/var/run/dhcpcd-" + self.name + ".pid" + if os.path.exists(pidFile): + ins = open(pidFile) + pid = int(ins.readline()) + os.kill(pid,signal.SIGTERM) + time.sleep(1) + def up(self): + options = "" + + if self.wepkey: + if runCmd("iwconfig eth1 key " + self.wepkey): + die(4, "Failed to set WEP key for " + self.name) + + if self.ip: + options += self.ip + " " + if self.broadcast: + options += "broadcast " + self.broadcast + " " + if self.netmask: + options += "netmask " + self.netmask + " " + + if runCmd("ifconfig " + self.name + " " + options + " up"): + die(2, "Failed to bring up " + self.name) + + if self.gateway: + if runCmd("route add default gw " + self.gateway + " " + self.name): + die(3, "Failed to set default gateway for " + self.name) + + if self.nameserver: + if Config.verbosity > 5: + print("Using nameserver " + self.nameserver) + try: + ous = open("/etc/resolv.conf","w") + ous.write("nameserver " + self.nameserver) + ous.close() + except OSError: + die("Failed to set nameserver") + if Config.verbosity > 3: + print "Brough interface " + self.name + " up" + +class InterfaceHandler: + def __init__(self): + self.ifaces = {} + self._loadAllInterfaces() + def _loadAllInterfaces(self): + ins=open("/proc/net/dev") + for line in ins.readlines(): + tokens = line.split(":") + if len(tokens) > 1: + ifaceName = tokens[0].strip() + iface = Interface(ifaceName) + self.ifaces[ifaceName] = iface + def getInterface(self,ifaceName): + return self.ifaces[ifaceName] + def downAll(self): + for x in self.ifaces.values(): + if x.getName() != "lo": + x.down() + +class Moo: + def __init__(self): + self.profileHandler = ProfileHandler() + self.ifaceHandler = InterfaceHandler() + + def selectProfile(self,profile): + prof = self.profileHandler.getProfile(profile) + + if prof.exclusive == "yes": + self.ifaceHandler.downAll() + + iface = self.ifaceHandler.getInterface(prof.ifaceName) + + if prof.ip == "dhcp": + iface.runDHCP() + else: + iface.setIP(prof.ip) + iface.setBroadcast(prof.broadcast) + iface.setNetmask(prof.netmask) + iface.setGateway(prof.gateway) + iface.setNameserver(prof.nameserver) + iface.up() + + def listProfiles(self,detailed=0): + self.profileHandler.listProfiles(detailed) + +def initConfig(): + Config.verbosity = 3 + +def main(): + + initConfig() + + if len(sys.argv) < 2: + printUsage() + sys.exit(1) + + moo = Moo() + + for i in xrange(len(sys.argv)): + if sys.argv[i] == "list": + detailed = 0 + for x in sys.argv[i:]: + if x == "--detailed": + detailed = 1 + moo.listProfiles(detailed) + + elif sys.argv[i] == "select": + moo.selectProfile(sys.argv[2]) + +if __name__ == "__main__": + main() + + +# TODO +# - automatically create profile +# - specify wireless network name +# - specify wep key +# - specify access point +# - specify pre_run/post_run commands +# - with parameters +# diff --git a/deprecated/moo/moo.1 b/deprecated/moo/moo.1 new file mode 100644 index 0000000..534aa0c --- /dev/null +++ b/deprecated/moo/moo.1 @@ -0,0 +1,12 @@ +.TH moo "1" "Nov 2003" "gentoolkit" +.SH NAME +moo \- Gentoo: Configuration Update Utility +.SH SYNOPSIS +.B moo +.SH BUGS +This tool does not yet have a man page. Feel free to submit a bug about it to +http://bugs.gentoo.org +.SH AUTHORS +This informative man page was written by Karl Trygve Kalleberg +. + diff --git a/deprecated/old-scripts/Makefile b/deprecated/old-scripts/Makefile new file mode 100644 index 0000000..8f61cb5 --- /dev/null +++ b/deprecated/old-scripts/Makefile @@ -0,0 +1,32 @@ +# Copyright 2004 Karl Trygve Kalleberg +# Copyright 2004 Gentoo Technologies, Inc. +# Distributed under the terms of the GNU General Public License v2 +# +# $Header$ + +include ../../makedefs.mak + +all: + echo "BOTOLPHS Huge benign tumors which archdeacons and old chemistry teachers affect to wear on the sides of their noses." + +dist: + mkdir -p ../../$(distdir)/src/old-scripts/ + cp Makefile ../../$(distdir)/src/old-scripts/ + cp dep-clean dep-clean.1 ../../$(distdir)/src/old-scripts/ + cp pkg-clean pkg-clean.1 ../../$(distdir)/src/old-scripts/ + cp ewhich ewhich.1 ../../$(distdir)/src/old-scripts/ + cp mkebuild mkebuild.1 ../../$(distdir)/src/old-scripts/ + cp pkg-size pkg-size.1 ../../$(distdir)/src/old-scripts/ + +install: + install -m 0755 dep-clean $(bindir)/ + install -m 0755 pkg-clean $(sbindir)/ + install -m 0755 ewhich $(bindir)/ + install -m 0755 mkebuild $(sbindir)/ + install -m 0755 pkg-size $(bindir)/ + + install -m 0644 dep-clean.1 $(mandir)/ + install -m 0644 pkg-clean.1 $(mandir)/ + install -m 0644 ewhich.1 $(mandir)/ + install -m 0644 mkebuild.1 $(mandir)/ + install -m 0644 pkg-size.1 $(mandir)/ diff --git a/deprecated/old-scripts/dep-clean b/deprecated/old-scripts/dep-clean new file mode 100644 index 0000000..89c6364 --- /dev/null +++ b/deprecated/old-scripts/dep-clean @@ -0,0 +1,272 @@ +#!/bin/bash +#Shows unrequired packages and missing dependencies. +#Author/Maintainer: Brandon Low +#Author: Jerry Haltom + +echo +echo -e "\x1b[31;01m!!! As of Gentoolkit 0.2.0, this tool is deprecated." +echo -e "!!!\x1b[0;0m Please refer to 'emerge clean' and 'emerge depclean' for replacements." +echo + +PROG=`basename ${0}` + +tmp="/tmp/$$" + +#Get PORTDIR and PORTDIR_OVERLAY from portage +PORTDIR_OVERLAY="$(/usr/lib/portage/bin/portageq portdir_overlay)" +PORTDIR="$(/usr/lib/portage/bin/portageq portdir)" + +rm -rf ${tmp} > /dev/null 2>&1 +mkdir ${tmp} > /dev/null 2>&1 + +declare -i i + +set -- `getopt -n ${PROG} -o N,R,U,I,v,q,C,h -l needed,removed,unneeded,interactive,verbose,quiet,nocolor,help -- ${*/ --/};[ $? != 0 ] && echo "y"` + +while [ ${#} -gt 0 ] +do + a=${1} + shift + case "${a}" in + + -I|--interactive) + interactive=y + ;; + + -N|--needed) + needed=y + ;; + + -U|--unneeded) + unneeded=y + ;; + + -R|--removed) + removed=y + ;; + + -v|--verbose) + verb=y + ;; + + -q|--quiet) + quiet=y + ;; + + -C|--nocolor) + nocolor=y + ;; + + -h|--help) + usage=y + ;; + + --) + [ ${1} ] && usage=y && broke=y + break + ;; + + *) + usage=y + broke=y + echo "FIXME - OPTION PARSING - ${a}" + break + ;; + + esac +done + +if [ ! ${needed} ] && [ ! ${unneeded} ] && [ ! ${removed} ]; then + needed=y + unneeded=y + removed=y +fi + +#Set up colors +if [ ! "${nocolor}" ]; then + NO="\x1b[0;0m" + BR="\x1b[0;01m" + CY="\x1b[36;01m" + GR="\x1b[32;01m" + RD="\x1b[31;01m" + YL="\x1b[33;01m" + BL="\x1b[34;01m" +elif [ ${quiet} ] && ( + ( [ ${needed} ] && [ ${unneeded} ] ) || + ( [ ${unneeded} ] && [ ${removed} ] ) || + ( [ ${removed} ] && [ ${needed} ] ) + ); then + NEED=" N" + UNNE=" U" + REMO=" R" +fi + +if [ ${usage} ]; then + echo -e "${BR}GenToolKit's Dependency Checker! +${NO}Displays packages that are installed but which none +of the packages in world or system depend on, and +displays packages which are depended on by world or +system, but are not currently installed. + +${BR}USAGE: + ${BL}${PROG}${YL} [${NO}options${YL}]${NO} + ${BL}${PROG}${GR} --help${NO} + +${BR}OPTIONS: + ${GR}-U, --unneeded${NO} display unneeded packages that are installed (${GR}green${NO}) + ${GR}-N, --needed${NO} display needed packages that are not installed (${RD}red${NO}) + ${GR}-R, --removed${NO} display installed packages not in portage (${YL}yellow${NO}) + + ${GR}-I, --interactive${NO} interactively modify world file before proceeding + ${GR}-C, --nocolor${NO} output without color, if necessary, package types are + noted with ${GR}U, N${NO} and ${GR}R${NO} respectively + ${GR}-v, --verbose${NO} be more verbose + ${GR}-q, --quiet${NO} be quiet (just output the packages, no extra info) + +${BR}NOTES: + ${GR}*${NO} If this script is run on a system that is not up-to-date or which hasn't + been cleaned (with '${BL}emerge -c${NO}') recently, the output may be deceptive. + ${GR}*${NO} If the same package name appears in all three categories, then it is + definitely time to update that package and then run '${BL}emerge -c${NO}'. + ${GR}*${NO} The ${GR}-U, -N${NO} and ${GR}-R${NO} options may be combined, defaults to ${GR}-UNR${NO}" + rm -rf ${tmp} > /dev/null 2>&1 + [ ${broke} ] && exit 1 || exit 0 +fi + +X="\([^/]*\)" + +#Retrieve currently merged packages. +if [ ${verb} ];then + echo -e "${CY}Retrieving currently merged packages.${NO}" +fi +find /var/db/pkg/ -name '*.ebuild' | \ + sed -e "s:/var/db/pkg/::" \ + -e "s:${X}/${X}/${X}:\1/\2:" | \ + sort -u >> ${tmp}/current + +if [ ${verb} ]; then + echo -e "${CY}"`cat ${tmp}/current | wc -l` "currently merged packages.${NO}" + echo -e +fi + +#Retrieve system packages and add to image. +if [ ${verb} ];then + echo -e "${CY}Retrieving system packages.${NO}" +fi +emerge system -ep | \ + sed -e "/ebuild/s:^.*] \([^ ]*\) *:\1:p;d" | \ + sort -u \ + > ${tmp}/system + +if [ ${verb} ]; then + echo -e "${CY}"`cat ${tmp}/system | wc -l 2> /dev/null` "packages contained in system.${NO}" + echo -e + echo -e "${CY}Preparing world file.${NO}" +fi + +#Create local copy of world and ask user to verify it. +cp /var/cache/edb/world ${tmp}/world + +if [ ${interactive} ]; then + ${EDITOR} ${tmp}/world +fi + +#Retrieve world packages and dependencies and add to image. +if [ ${verb} ]; then + echo -e + echo -e "${CY}Preparing list of installed world packages.${NO}" + echo -e +fi + +cat ${tmp}/current | grep -f ${tmp}/world | sort > ${tmp}/world.inst +find ${PORTDIR} ${PORTDIR_OVERLAY} -iname '*.ebuild' | \ + awk -F'/' '{printf("%s/%s\n", $(NF-2), $NF)}' | \ + sed -e 's:\.ebuild::' > ${tmp}/ebuilds +grep -xf ${tmp}/world.inst ${tmp}/ebuilds >> ${tmp}/world.new + +if [ ${verb} ]; then + echo -e "${CY}"`cat ${tmp}/ebuilds | wc -l`"\tebuilds available.${NO}" + echo -e "${CY}"`cat ${tmp}/world.new | wc -l`"\tpackages contained in final world file.${NO}" + echo -e + echo -e "${CY}List prepared, checking dependencies with emerge -ep${NO}" +fi + +sort ${tmp}/world.new |sed -e 's:^:\\\=:' | uniq | xargs emerge -ep | \ + tee ${tmp}/log | sed -e '/ebuild/s:^.*] \([^ ]*\) *$:\1:p;d' > ${tmp}/image.unsorted + +depends=`cat ${tmp}/image.unsorted|wc -l` + +if [ ${depends} -lt "2" ]; then + echo -e "${RD}There appears to be an unresolved dependency in your world file." + echo -e "Please check for masking errors or other world file issues," + echo -e "and then try again." + echo -e + echo -e "The following is the emerge output for your reference:${NO}" + cat ${tmp}/log + rm -rf ${tmp} > /dev/null 2>&1 + exit 1 +fi + +cat ${tmp}/system >> ${tmp}/image.unsorted + +#Cleanup image +sort -u ${tmp}/image.unsorted > ${tmp}/image + +if [ ${verb} ];then + echo -e "${CY}"`cat ${tmp}/image | wc -l` "packages contained in final image.${NO}" + echo -e +fi + +#Determine packages that exist in current but not in image. +#These packages are safe to clean up. +if [ ${unneeded} ]; then + if [ ! ${quiet} ]; then + echo -e "${CY}These packages have no other packages depending on them.${NO}" + fi + + grep -vxf ${tmp}/image ${tmp}/current > ${tmp}/unneeded + for line in `cat ${tmp}/unneeded`;do + echo -e "${GR}${line}${CY}${UNNE}${NO}" + done + + if [ ! ${quiet} ];then + echo -e "${CY}Total of"`cat ${tmp}/unneeded|wc -l` "unneeded packages.${NO}" + fi +fi + +#Determine packages that exist in image but not in current. +#These packages should be added. +if [ ${needed} ]; then + if [ ! ${quiet} ];then + echo -e + echo -e "${CY}These packages are depended upon but are not present on the system.${NO}" + fi + + grep -vxf ${tmp}/current ${tmp}/image > ${tmp}/needed + for line in `cat ${tmp}/needed`;do + echo -e "${RD}${line}${CY}${NEED}${NO}" + done + + if [ ! ${quiet} ];then + echo -e "${CY}Total of"`cat ${tmp}/needed|wc -l` "needed packages.${NO}" + fi +fi + +#Determine packages that are installed but not currently in portage +if [ ${removed} ]; then + if [ ! ${quiet} ];then + echo -e + echo -e "${CY}These packages are installed but not in the portage tree.${NO}" + fi + grep -xf ${tmp}/current ${tmp}/ebuilds > ${tmp}/hascurrent + grep -vxf ${tmp}/hascurrent ${tmp}/current > ${tmp}/removed + for line in `cat ${tmp}/removed`;do + echo -e "${YL}${line}${CY}${REMO}${NO}" + done + + if [ ! ${quiet} ];then + echo -e "${CY}Total of"`cat ${tmp}/removed|wc -l` "removed packages.${NO}" + fi +fi + +rm -rf ${tmp} > /dev/null 2>&1 diff --git a/deprecated/old-scripts/dep-clean.1 b/deprecated/old-scripts/dep-clean.1 new file mode 100644 index 0000000..9747ce4 --- /dev/null +++ b/deprecated/old-scripts/dep-clean.1 @@ -0,0 +1,190 @@ +.\" Automatically generated by Pod::Man version 1.15 +.\" Thu Jul 18 15:59:55 2002 +.\" +.\" Standard preamble: +.\" ====================================================================== +.de Sh \" Subsection heading +.br +.if t .Sp +.ne 5 +.PP +\fB\\$1\fR +.PP +.. +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Ip \" List item +.br +.ie \\n(.$>=3 .ne \\$3 +.el .ne 3 +.IP "\\$1" \\$2 +.. +.de Vb \" Begin verbatim text +.ft CW +.nf +.ne \\$1 +.. +.de Ve \" End verbatim text +.ft R + +.fi +.. +.\" Set up some character translations and predefined strings. \*(-- will +.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +.\" double quote, and \*(R" will give a right double quote. | will give a +.\" real vertical bar. \*(C+ will give a nicer C++. Capital omega is used +.\" to do unbreakable dashes and therefore won't be available. \*(C` and +.\" \*(C' expand to `' in nroff, nothing in troff, for use with C<> +.tr \(*W-|\(bv\*(Tr +.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +.ie n \{\ +. ds -- \(*W- +. ds PI pi +. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +. ds L" "" +. ds R" "" +. ds C` "" +. ds C' "" +'br\} +.el\{\ +. ds -- \|\(em\| +. ds PI \(*p +. ds L" `` +. ds R" '' +'br\} +.\" +.\" If the F register is turned on, we'll generate index entries on stderr +.\" for titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and +.\" index entries marked with X<> in POD. Of course, you'll have to process +.\" the output yourself in some meaningful fashion. +.if \nF \{\ +. de IX +. tm Index:\\$1\t\\n%\t"\\$2" +.. +. nr % 0 +. rr F +.\} +.\" +.\" For nroff, turn off justification. Always turn off hyphenation; it +.\" makes way too many mistakes in technical documents. +.hy 0 +.if n .na +.\" +.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +.\" Fear. Run. Save yourself. No user-serviceable parts. +.bd B 3 +. \" fudge factors for nroff and troff +.if n \{\ +. ds #H 0 +. ds #V .8m +. ds #F .3m +. ds #[ \f1 +. ds #] \fP +.\} +.if t \{\ +. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +. ds #V .6m +. ds #F 0 +. ds #[ \& +. ds #] \& +.\} +. \" simple accents for nroff and troff +.if n \{\ +. ds ' \& +. ds ` \& +. ds ^ \& +. ds , \& +. ds ~ ~ +. ds / +.\} +.if t \{\ +. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +.\} +. \" troff and (daisy-wheel) nroff accents +.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +.ds ae a\h'-(\w'a'u*4/10)'e +.ds Ae A\h'-(\w'A'u*4/10)'E +. \" corrections for vroff +.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +. \" for low resolution devices (crt and lpr) +.if \n(.H>23 .if \n(.V>19 \ +\{\ +. ds : e +. ds 8 ss +. ds o a +. ds d- d\h'-1'\(ga +. ds D- D\h'-1'\(hy +. ds th \o'bp' +. ds Th \o'LP' +. ds ae ae +. ds Ae AE +.\} +.rm #[ #] #H #V #F C +.\" ====================================================================== +.\" +.IX Title "DEP-CLEAN 1" +.TH DEP-CLEAN 1 "Copyright 2002 Gentoo Technologies, Inc." "2002-07-18" "GenToolKit's Dependency Checker!" +.UC +.SH "NAME" +dep-clean \- Gentoo: Shows unrequired packages and missing dependencies. +.SH "SYNOPSIS" +.IX Header "SYNOPSIS" +.Vb 1 +\& dep-clean [-RUNICv] +.Ve +.SH "DESCRIPTION" +.IX Header "DESCRIPTION" +dep-clean displays extraneous, missing or extra packages. Extra packages are those in which are not a part of the portage tree (/usr/portage). It does \s-1NOT\s0 modify the system in any way. +.SH "OPTIONS" +.IX Header "OPTIONS" +.Ip "\-N, \-\-needed" 4 +.IX Item "-N, --needed" +Display needed packages that are not installed. (red) (default) +.Ip "\-R, \-\-removed" 4 +.IX Item "-R, --removed" +Display installed packages not in portage. (yellow) (default) +.Ip "\-U, \-\-unneeded" 4 +.IX Item "-U, --unneeded" +Display unneeded packages that are installed. (green) (default) +.Ip "\-I, \-\-interactive" 4 +.IX Item "-I, --interactive" +Interactively modify world file before proceeding. +.Ip "\-C, \-\-nocolor" 4 +.IX Item "-C, --nocolor" +Output without color. Package types will be noted with R, U and N. +.Ip "\-v, \-\-verbose" 4 +.IX Item "-v, --verbose" +Be more verbose. +.Ip "\-q, \-\-quiet" 4 +.IX Item "-q, --quiet" +Be quiet (display only packages). +.SH "NOTES" +.IX Header "NOTES" +.Ip "" 4 +If this script is run on a system that is not up-to-date or which hasn't been cleaned (with 'emerge \-c') recently, the output may be deceptive. +.Ip "" 4 +If the same package name appears in all three categories, then it is definitely time to update that package and then run 'emerge \-c'. +.Ip "" 4 +The \-U, \-N and \-R options may be combined, default is \-UNR +.SH "AUTHORS" +.IX Header "AUTHORS" +Jerry Haltom (dep-clean) +.br +Brandon Low (dep-clean) +.PP +Paul Belt (man page) diff --git a/deprecated/old-scripts/ewhich b/deprecated/old-scripts/ewhich new file mode 100755 index 0000000..345ec34 --- /dev/null +++ b/deprecated/old-scripts/ewhich @@ -0,0 +1,44 @@ +#!/usr/bin/python +# Copyright 1999-2003 Gentoo Technologies, Inc. +# Distributed under the terms of the GNU General Public License v2 +# $Header$ +# +# Author: Marius Mauch +# +# ewhich is a tool to get the ebuild filename for a given package name + +import portage,sys,os +from output import * + +sys.stderr.write("\n" + red("!!!") + " As of Gentoolkit 0.2.0 this tool is deprecated\n") +sys.stderr.write(red("!!!") + " Refer to 'equery which' for a replacement\n\n") + +def print_help(): + print + print fuscia(os.path.basename(sys.argv[0])), "is a tool to get the filename of the ebuild for a given package" + print ' '*len(os.path.basename(sys.argv[0])), "that would be used by portage with the current configuration" + print + print yellow("Syntax:"), os.path.basename(sys.argv[0]), teal("") + print + print teal(""), "is either a simple package name (like "+green("xfree")+")," + print " a package name with category (like "+green("x11-base/xfree")+")" + print " or a DEPEND style atom as defined in ebuild(5) (like "+green(">=x11-base/xfree-4.3.0")+")" + print + +if len(sys.argv) <= 1 or sys.argv[1] == "-h" or sys.argv[1] == "--help": + print_help() + sys.exit(0) + +p = portage.db[portage.root]["porttree"].dbapi.xmatch("bestmatch-visible", sys.argv[1]) +if len(p) <= 1: + print + print red("*"), "\""+sys.argv[1]+"\" is not a valid package name or a masked package" + print + sys.exit(1) +pv = portage.catpkgsplit(p) +ebuild = "/"+pv[0]+"/"+pv[1]+"/"+p.split("/")[1]+".ebuild" +for ov in portage.settings["PORTDIR_OVERLAY"].split(): + if os.path.exists(ov+ebuild): + print os.path.normpath(ov+ebuild) + sys.exit(0) +print os.path.normpath(portage.settings["PORTDIR"]+ebuild) diff --git a/deprecated/old-scripts/ewhich.1 b/deprecated/old-scripts/ewhich.1 new file mode 100644 index 0000000..4bc5459 --- /dev/null +++ b/deprecated/old-scripts/ewhich.1 @@ -0,0 +1,24 @@ +.TH ewhich 1 "October 19, 2003" "ewhich" + +.SH NAME +ewhich \- Gentoo: program for resolving ebuild names + +.SH SYNOPSIS +.B ewhich +[ -h | --help ] + +.SH DESCRIPTION +.B ewhich +is a little tool to find the actual ebuild file for a given package name. +It can use simple package names (like xfree), package names with category +(like x11-base/xfree) or DEPEND atoms (like >=x11-base/xfree-4.3.0). + +.SH BUGS +.B ewhich +No known bugs + +.SH SEE ALSO +emerge(1), make.conf(5), ebuild(5) + +.SH AUTHOR +Marius Mauch diff --git a/deprecated/old-scripts/mkebuild b/deprecated/old-scripts/mkebuild new file mode 100644 index 0000000..9ee0ce1 --- /dev/null +++ b/deprecated/old-scripts/mkebuild @@ -0,0 +1,216 @@ +#!/bin/bash + +# Copyright (c) 2002 +# John Stalker +# Department of Mathematics +# Princeton University + +echo +echo -e "\x1b[31;01m!!! As of Gentoolkit 0.2.0, this tool is deprecated" +echo -e "!!!\x1b[0;0m Refer to app-portage/ebuilder for a replacement." +echo + +CONFIG_FILE=${HOME}/.mkebuild +if [ -e $CONFIG_FILE ] +then + source $CONFIG_FILE +else + echo This appears to be the first time you have used mkebuild. + echo I am going to make some guesses. If any of these are wrong + echo you should edit the file ${CONFIG_FILE}. + echo + MY_NAME=`awk -F":" '/^'${USER}:'/ { print $5 }' /etc/passwd` + echo Your name is ${MY_NAME}. + echo 'MY_NAME="'${MY_NAME}'"' >${CONFIG_FILE} + COPYRIGHT="Gentoo Technologies, Inc." + echo You wish to asign copyright to ${COPYRIGHT} + echo 'COPYRIGHT="'${COPYRIGHT}'"' >>${CONFIG_FILE} + MY_EMAIL=${USER}"@"${HOSTNAME} + echo Your email address is ${MY_EMAIL}. + echo 'MY_EMAIL='${MY_EMAIL} >>$CONFIG_FILE + LICENSE="the GNU General Public License, v2" + echo Your preferred license is ${LICENSE}. + echo 'LICENSE="'${LICENSE}'"' >>${CONFIG_FILE} + LOCAL_SOURCE=${HOME} + echo You download sources to ${LOCAL_SOURCE}. + echo LOCAL_SOURCE=${LOCAL_SOURCE} >>${CONFIG_FILE} + BUILD_DIRECTORY=${HOME} + echo You build packages in ${BUILD_DIRECTORY}. + echo 'BUILD_DIRECTORY='${BUILD_DIRECTORY} >>${CONFIG_FILE} + echo +fi +FILE_NAME=`basename $1` +SOURCE_LOCATION=`dirname $1` +PACKAGE_NAME=${FILE_NAME%.*} +FILE_EXTENSION=${FILE_NAME##*.} +if [ "${PACKAGE_NAME##*.}" = "tar" ] +then + FILE_EXTENSION=tar.${FILE_EXTENSION} + PACKAGE_NAME=${PACKAGE_NAME%.tar} +fi +EBUILD_FILE=${PWD}/${PACKAGE_NAME}.ebuild +echo "# Copyright" `date +"%Y"` ${COPYRIGHT} >${EBUILD_FILE} +echo "# Distributed under the terms of" ${LICENSE} >>${EBUILD_FILE} +#echo "# Author" ${MY_NAME} '<'${MY_EMAIL}'>' >>${EBUILD_FILE} +echo "# \$Header$" >>${EBUILD_FILE} +echo >>${EBUILD_FILE} +echo 'DESCRIPTION=""' >>${EBUILD_FILE} +echo 'SRC_URI="'${SOURCE_LOCATION}'/${P}.'${FILE_EXTENSION}'"' >>${EBUILD_FILE} +echo 'HOMEPAGE="'${SOURCE_LOCATION}'/"' >>${EBUILD_FILE} +echo 'LICENSE=""' >>${EBUILD_FILE} +echo 'SLOT="0"' >>${EBUILD_FILE} +echo 'KEYWORDS="~x86"' >>${EBUILD_FILE} +echo 'IUSE=""' >>${EBUILD_FILE} +echo >>${EBUILD_FILE} +echo 'DEPEND=""' >>${EBUILD_FILE} +echo >>${EBUILD_FILE} +echo '#RDEPEND=""' >>${EBUILD_FILE} +echo 'S=${WORKDIR}/${P}' >>${EBUILD_FILE} +echo >>${EBUILD_FILE} +echo 'src_unpack() {' >>${EBUILD_FILE} +echo >>${EBUILD_FILE} +echo -e "\t"'unpack ${A}' >>${EBUILD_FILE} +echo -e "\t"'cd ${S}' >>${EBUILD_FILE} +echo >>${EBUILD_FILE} +echo '}' >>${EBUILD_FILE} +if [ -e ${LOCAL_SOURCE}/${FILE_NAME} ] +then + echo I am assuming that $1 really + echo exists and that ${LOCAL_SOURCE}/${FILE_NAME} + echo is a faithful copy. +else + echo I didn\'t find ${LOCAL_SOURCE}/${FILE_NAME} so I will fetch + echo $1. + cd ${LOCAL_SOURCE} + wget $1 +fi +if [ -e ${BUILD_DIRECTORY}/${PACKAGE_NAME} ] +then + echo + echo I am assuming that ${BUILD_DIRECTORY}/${PACKAGE_NAME} \ + is the unpacked + echo version of ${LOCAL_SOURCE}/${FILE_NAME}. +else + cd ${BUILD_DIRECTORY} + if [ $? -ne 0 ] + then + echo + echo I was unable to enter the directory ${BUILD_DIRECTORY}. + exit 1 + fi + case "${FILE_EXTENSION}" in + tar.gz|tgz) + tar xzf ${LOCAL_SOURCE}/${FILE_NAME} + ;; + tar.bz2|tbz2) + tar xjf ${LOCAL_SOURCE}/${FILE_NAME} + ;; + tar.Z|tar.z) + unzip ${LOCAL_SOURCE}/${FILE_NAME} + tar xf ${PACKAGE_NAME}.tar + ;; + *) + echo + echo I can\'t figure out how to uncompress + echo ${LOCAL_SOURCE}/${FILE_NAME} + exit 1 + esac + if [ $? -ne 0 ] + then + echo + echo I was unable to uncompress ${LOCAL_SOURCE}/${FILE_NAME}. + exit 1 + fi +fi +cd ${BUILD_DIRECTORY}/${PACKAGE_NAME} +if [ $? -ne 0 ] +then + echo + echo I could not change directory to ${BUILD_DIRECTORY}/${PACKAGE_NAME} + exit 1 +fi +echo +echo You might want to look at the following files for configuration and +echo dependency information: +find ${PWD} -name README -print +find ${PWD} -name README.txt -print +find ${PWD} -name INSTALL -print +find ${PWD} -name INSTALL.txt -print +find ${PWD} -name Changes -print +find ${PWD} -name CHANGES.txt -print +find ${PWD} -name FAQ.txt +find ${PWD} -name ChangeLog -print +find ${PWD} -name NEWS -print +echo >>${EBUILD_FILE} +echo 'src_compile() {' >>${EBUILD_FILE} +echo >>${EBUILD_FILE} +echo +if [ -e Imakefile ] +then + echo I found an Imakefile. I am assuming that we should use xmkmf. + echo I don\'t really understand xmkmf so you will have to configure + echo things on your own. + echo + echo -e "\t"'xmkmf || die' >>${EBUILD_FILE} + echo -e "\tmake Makefiles" >>${EBUILD_FILE} + echo -e "\tmake includes" >>${EBUILD_FILE} + echo -e "\tmake depend" >>${EBUILD_FILES} +elif [ -e configure ] +then + echo I found a configure file. I am assuming that we are using autoconf +. + echo I will take care of setting the most commonly used options. I am + echo including a list of all the available options to confiigure, commen +ted + echo out. You might want to look it over to see if I have missed anythi +ng. + echo + ./configure --help >.config.options + echo -e "\t./configure \\" >>${EBUILD_FILE} + awk '/--prefix/ { print "\t\t--prefix=/usr \\"}' \ + .config.options >>${EBUILD_FILE} + awk '/--infodir/ { print "\t\t--infodir=/usr/share/info \\"}' \ + .config.options >>${EBUILD_FILE} + awk '/--mandir/ { print "\t\t--mandir=/usr/share/man \\"}' \ + .config.options >>${EBUILD_FILE} + echo -e "\t\t"'|| die "./configure failed"' >>${EBUILD_FILE} + echo -e "#\tAvailable options to configure:" >>${EBUILD_FILE} + awk '/--/ { print "#" $0 }' .config.options >>${EBUILD_FILE} + echo -e "\t"'emake || die' >>${EBUILD_FILE} +elif [ -e Makefile ] +then + echo I found a Makefile. You should look at it and possibly prepare + echo a patch. + echo + echo -e "\temake || die" >>${EBUILD_FILE} +else + echo I couldn\'t find a Imakefile, configure script, or Makefile for + echo this package. You will have to figure out what to do on your + echo own. + echo +fi +echo '}' >>${EBUILD_FILE} +echo >>${EBUILD_FILE} +echo 'src_install () {' >>${EBUILD_FILE} +echo >>${EBUILD_FILE} +echo -e "\t"'make DESTDIR=${D} install || die' >>${EBUILD_FILE} +echo '}' >>${EBUILD_FILE} +echo >>${EBUILD_FILE} +echo >>${EBUILD_FILE} +echo >>${EBUILD_FILE} +echo I couldn\'t supply a package description for the ebuild file +echo because I don\'t know what ${PACKAGE_NAME} does. +echo +echo I am assume the hompage for this package is ${SOURCE_LOCATION}/. +echo If that is not correct you will need to edit that portion of +echo the ebuild file as well. +echo +echo I don\'t understand dependencies yet. You will have to add any +echo dependencies you know of by hand. Then try your ebuild script +echo out to see if there are any dependencies you don\'t know of. +echo +echo I am assuming that this package comes with a well-behaved Makefile +echo which does not install anything outside of '${DESTDIR}'. You will +echo need to check this by looking at the portion of the Makefile +echo beginning with the line '"install:"'. + diff --git a/deprecated/old-scripts/mkebuild.1 b/deprecated/old-scripts/mkebuild.1 new file mode 100644 index 0000000..e800d4d --- /dev/null +++ b/deprecated/old-scripts/mkebuild.1 @@ -0,0 +1,20 @@ +.TH mkebuild "1" "Nov 2003" "gentoolkit" +.SH NAME +mkebuild \- Gentoo: Interactive ebuild generator +.SH SYNOPSIS +.B mkebuild +.SH BUGS +This tool is obsolete, as of gentoolkit 0.2.0. +Use ebuilder [app\-portage/ebuilder] instead. +.SH SEE ALSO +.BR ebuilder(1) +.br +.BR /usr/sbin/ebuilder +.br +.BR /usr/sbin/mkebuild + +.SH AUTHORS +This informative man page was written by Karl Trygve Kalleberg + and expanded by Katerina Barone\-Adesi +. + diff --git a/deprecated/old-scripts/pkg-clean b/deprecated/old-scripts/pkg-clean new file mode 100644 index 0000000..9b07337 --- /dev/null +++ b/deprecated/old-scripts/pkg-clean @@ -0,0 +1,107 @@ +#!/usr/bin/python +# Copyright 1999-2003 Gentoo Technologies, Inc. +# Distributed under the terms of the GNU General Public License v2 +# $Header$ +# Author: Leo Lipelis +# Author: Karl Trygve Kalleberg + +import commands +import re +import sys +import time +import os +from output import * + +print +print red("!!! As of Gentoolkit 0.2.0, this tool is deprecated") +print red("!!!") + " Refer to 'emerge clean' and 'emerge depclean' for replacements." +print + +time.sleep(4) + +# constants for package tuples that are stored in pkg_hash +PKG_TIME = 0 # number of seconds for ctime function +PKG = 1 # package full path as accepted by ebuild +PKG_NAME = 2 # package name as accepted by emerge + +(status, pkg_files) = commands.getstatusoutput( + "find /var/db/pkg -iname '*.ebuild' -printf '%T@ %p\n' | sort -n") + +pkg_file_list = pkg_files.splitlines() + +pkg_hash = {} +for time_pkg_pair in pkg_file_list: + (pkg_time, pkg) = time_pkg_pair.split() + pkg_time = int(pkg_time) + # This covers developer trees with not-accepted categories + tmp_name = re.match(r'/var/db/pkg/(.*/.*)/.*', pkg) + if not tmp_name: continue + pkg_name = tmp_name.group(1) + tmp_core = re.match(r'(.*)-\d.*', pkg_name) + if not tmp_core: continue + pkg_core = tmp_core.group(1) + if pkg_hash.has_key(pkg_core): + pkg_hash[pkg_core].append((pkg_time, pkg, pkg_name)) + else: + pkg_hash[pkg_core] = [(pkg_time, pkg, pkg_name)] + +total_len = len(pkg_hash.keys()) +curpkg = 0 +tmpname = os.tmpnam() +assume_yes = 0 + +if len(sys.argv) > 1: + if sys.argv[1] in ["-y", "--yes"]: + assume_yes = 1 + elif sys.argv[1] in ["-h", "--help"]: + print """pkg-clean [options] + +-y, --yes Don't ask for individual confirmation before unmerging; assume yes. +""" + sys.exit(0) + +for pkg_core in pkg_hash.keys(): + print "Examining %s:" % (pkg_core) + if len(pkg_hash[pkg_core]) < 2: + continue + unmerged_indexes = [] + + curpkg += 1 + choices = "" + idx = 1 + for pkg_tuple in pkg_hash[pkg_core]: + choices += " %d \"%s %s\" 0" % \ + (idx, time.ctime(pkg_tuple[PKG_TIME]), + pkg_tuple[PKG_NAME]) + idx += 1 + + params = "dialog --separate-output --backtitle \"pkg-clean processing package %d of %d\" " % ( curpkg, total_len) + params += "--checklist \"Select which package(s) to unmerge\" 20 70 12" + choices + res = os.system(params + " 2> " + tmpname) + if res: + sys.exit(0) + + ins = open(tmpname) + for j in ins.readlines(): + idx = int(j) + if idx == 0: + break + + full_path = pkg_hash[pkg_core][idx-1][PKG] + ebuild = full_path.replace('/var/db/pkg','') + + if not assume_yes: + params = "dialog --backtitle \"" + ebuild + "\" " + \ + "--yesno \"Are you sure you want to unmerge " + ebuild + " ?\" 20 70" + res = os.system(params) + else: + res = 0 + + if res == 0: + (status, unmerge_out) = commands.getstatusoutput( + "ebuild %s unmerge" % (full_path)) + print unmerge_out + time.sleep(2) + if status != 0: + sys.exit(status) + ins.close() diff --git a/deprecated/old-scripts/pkg-clean.1 b/deprecated/old-scripts/pkg-clean.1 new file mode 100644 index 0000000..7a295f3 --- /dev/null +++ b/deprecated/old-scripts/pkg-clean.1 @@ -0,0 +1,20 @@ +.TH pkg\-clean "1" "Nov 2003" "gentoolkit" +.SH NAME +pkg\-clean \- Gentoo: Clean obsolete packages +.SH SYNOPSIS +.B pkg\-clean +.SH BUGS +This tool is obsolete, as of gentoolkit 0.2.0. +Use 'emerge clean' or 'emerge depclean' (with caution; read the man page) +instead. + +.SH SEE ALSO +.BR emerge(1) +.br +.BR /usr/sbin/pkg\-clean + +.SH AUTHORS +This informative man page was written by Karl Trygve Kalleberg + and expanded by Katerina Barone\-Adesi +. + diff --git a/deprecated/old-scripts/pkg-size b/deprecated/old-scripts/pkg-size new file mode 100644 index 0000000..8770db7 --- /dev/null +++ b/deprecated/old-scripts/pkg-size @@ -0,0 +1,63 @@ +#!/bin/sh +# Copyright 1999-2003 Gentoo Technologies, Inc. +# Distributed under the terms of the GNU General Public License v2 +# $Header$ +# Author: Karl Trygve Kalleberg + +echo +echo -e "\x1b[31;01m!!! As of Gentoolkit 0.2.0, this tool is deprecated." +echo -e "!!!\x1b[0;0m Refer to 'equery size' for a replacement." +echo + +spec=$1 + +if [ -z "$spec" ] ; then + echo "Usage: pkg-size package" + exit 1 +fi + +name=`echo $1 | sed "s/\([^/]*\)\///"` +category=`echo $1 | sed "s/\/.*//"` + +if [ "$category" == "$name" ] ; then + category= +fi + +function tryfile() { + local foo + foo=/var/db/pkg/$1/CONTENTS + bar=`ls $foo 2> /dev/null` + for i in $bar ; do + if [ -f "$i" ] ; then + echo $i + break + fi + done +} + +file=`tryfile "${category}/${name}"` +if [ -z $file ] ; then + file=`tryfile "${category}/${name}*"` + if [ -z $file ] ; then + file=`tryfile "${category}*/${name}"` + if [ -z $file ] ; then + file=`tryfile "${category}*/${name}*"` + if [ -z $file ] ; then + echo "!!! Package resembling ${category}/${name} not found" + exit 1 + fi + fi + fi +fi + +pkgname=`echo $file | sed -e "s:\/var\/db\/pkg\/::" -e "s:\/CONTENTS::"` + +totals=`cat $file|grep "obj"|awk '{ print $2 }' | sed "s/ /\\ /" | xargs du -scb | grep total | cut -f 1` + +size=0 +for i in $totals ; do + size=$[size+i] +done + +echo "$pkgname $size ($[size/1024]KB)" + diff --git a/deprecated/old-scripts/pkg-size.1 b/deprecated/old-scripts/pkg-size.1 new file mode 100644 index 0000000..b195412 --- /dev/null +++ b/deprecated/old-scripts/pkg-size.1 @@ -0,0 +1,11 @@ +.TH pkg-size "1" "Nov 2003" "gentoolkit" +.SH NAME +pkg-size \- Gentoo: Package size calculator +.SH SYNOPSIS +.B pkg-size +\fIpackage\fR +.SH DESCRIPTION +Calculate size of \fIpackage\fR. +.SH AUTHORS +\fBpkg-size\fR was written by Karl Trygve Kalleberg . + diff --git a/deprecated/pkg-clean/AUTHORS b/deprecated/pkg-clean/AUTHORS new file mode 100644 index 0000000..f126a36 --- /dev/null +++ b/deprecated/pkg-clean/AUTHORS @@ -0,0 +1,5 @@ +Maintainer: +Karl Trygve Kalleberg + +Authors: +Leo Lipelis (original author) diff --git a/deprecated/pkg-clean/ChangeLog b/deprecated/pkg-clean/ChangeLog new file mode 100644 index 0000000..e69de29 diff --git a/deprecated/pkg-clean/README b/deprecated/pkg-clean/README new file mode 100644 index 0000000..e69de29 diff --git a/deprecated/pkg-clean/pkg-clean b/deprecated/pkg-clean/pkg-clean new file mode 100644 index 0000000..abe0159 --- /dev/null +++ b/deprecated/pkg-clean/pkg-clean @@ -0,0 +1,99 @@ +#!/usr/bin/python +# Copyright 1999-2003 Gentoo Technologies, Inc. +# Distributed under the terms of the GNU General Public License v2 +# $Header$ +# Author: Leo Lipelis +# Author: Karl Trygve Kalleberg + +import commands +import re +import sys +import time +import os + +# constants for package tuples that are stored in pkg_hash +PKG_TIME = 0 # number of seconds for ctime function +PKG = 1 # package full path as accepted by ebuild +PKG_NAME = 2 # package name as accepted by emerge + +(status, pkg_files) = commands.getstatusoutput( + "find /var/db/pkg -iname '*.ebuild' -printf '%T@ %p\n' | sort -n") + +pkg_file_list = pkg_files.splitlines() + +pkg_hash = {} +for time_pkg_pair in pkg_file_list: + (pkg_time, pkg) = time_pkg_pair.split() + pkg_time = int(pkg_time) + # This covers developer trees with not-accepted categories + tmp_name = re.match(r'/var/db/pkg/(.*/.*)/.*', pkg) + if not tmp_name: continue + pkg_name = tmp_name.group(1) + tmp_core = re.match(r'(.*)-\d.*', pkg_name) + if not tmp_core: continue + pkg_core = tmp_core.group(1) + if pkg_hash.has_key(pkg_core): + pkg_hash[pkg_core].append((pkg_time, pkg, pkg_name)) + else: + pkg_hash[pkg_core] = [(pkg_time, pkg, pkg_name)] + +total_len = len(pkg_hash.keys()) +curpkg = 0 +tmpname = os.tmpnam() +assume_yes = 0 + +if len(sys.argv) > 1: + if sys.argv[1] in ["-y", "--yes"]: + assume_yes = 1 + elif sys.argv[1] in ["-h", "--help"]: + print """pkg-clean [options] + +-y, --yes Don't ask for individual confirmation before unmerging; assume yes. +""" + sys.exit(0) + +for pkg_core in pkg_hash.keys(): + print "Examining %s:" % (pkg_core) + if len(pkg_hash[pkg_core]) < 2: + continue + unmerged_indexes = [] + + curpkg += 1 + choices = "" + idx = 1 + for pkg_tuple in pkg_hash[pkg_core]: + choices += " %d \"%s %s\" 0" % \ + (idx, time.ctime(pkg_tuple[PKG_TIME]), + pkg_tuple[PKG_NAME]) + idx += 1 + + params = "dialog --separate-output --backtitle \"pkg-clean processing package %d of %d\" " % ( curpkg, total_len) + params += "--checklist \"Select which package(s) to unmerge\" 20 70 12" + choices + res = os.system(params + " 2> " + tmpname) + if res: + sys.exit(0) + + ins = open(tmpname) + for j in ins.readlines(): + idx = int(j) + if idx == 0: + break + + full_path = pkg_hash[pkg_core][idx-1][PKG] + ebuild = full_path.replace("/var/db/pkg/", "") + + if not assume_yes: + params = "dialog --backtitle \"" + ebuild + "\" " + \ + "--yesno \"Are you sure you want to unmerge " + ebuild + " ?\" 20 70" + res = os.system(params) + else: + res = 0 + + if res == 0: + (status, unmerge_out) = commands.getstatusoutput( + "ebuild %s unmerge" % (full_path)) + print unmerge_out + time.sleep(2) + if status != 0: + sys.exit(status) + ins.close() diff --git a/deprecated/pkg-clean/pkg-clean.1 b/deprecated/pkg-clean/pkg-clean.1 new file mode 100644 index 0000000..7a295f3 --- /dev/null +++ b/deprecated/pkg-clean/pkg-clean.1 @@ -0,0 +1,20 @@ +.TH pkg\-clean "1" "Nov 2003" "gentoolkit" +.SH NAME +pkg\-clean \- Gentoo: Clean obsolete packages +.SH SYNOPSIS +.B pkg\-clean +.SH BUGS +This tool is obsolete, as of gentoolkit 0.2.0. +Use 'emerge clean' or 'emerge depclean' (with caution; read the man page) +instead. + +.SH SEE ALSO +.BR emerge(1) +.br +.BR /usr/sbin/pkg\-clean + +.SH AUTHORS +This informative man page was written by Karl Trygve Kalleberg + and expanded by Katerina Barone\-Adesi +. + diff --git a/deprecated/pkg-size/pkg-size b/deprecated/pkg-size/pkg-size new file mode 100644 index 0000000..84dd7df --- /dev/null +++ b/deprecated/pkg-size/pkg-size @@ -0,0 +1,66 @@ +#! /usr/bin/python +# +# $Header$ +# +# Distributed under the terms of the GNU General Public License v2 +# Copyright (c) 2003 Karl Trygve Kalleberg + +import portage +import pprint +import sys +import os + +__author__ = "Karl Trygve Kalleberg" +__email__ = "karltk@gentoo.org" +__version__ = "0.1.0" +__productname__ = "pkg-size" +__description__ = "Portage package size calculator" + +def find(name): + return portage.portdb.match(name) + +def print_size(cpv): + scpv=portage.catpkgsplit(cpv) + cat = scpv[0] + pnv = scpv[1]+"-"+scpv[2] + if scpv[3] != "r0": + pnv +="-"+scpv[3] + db=portage.dblink(cat,pnv,"") + size=0 + uncounted = 0 + if not os.path.exists(db.getpath()): + return + k=db.getcontents() + if not k: + return + for i in k: + try: + size += os.stat(i).st_size + except OSError: + uncounted += 1 + s = cpv + ": " + str(size) + " bytes (" + str((size+512)/1024) + "KB)" + if uncounted > 0: + s += " (" + str(uncounted) + " file(s) not accessible)" + print s + + +def main(): + # parse parameters + if len(sys.argv) < 2: + print "No arguments!" + return + name = sys.argv[1] + candidates = find(name) + if len(candidates) == 0: + print "No candidate packages found!" + return + + for i in candidates: + print_size(i) + +if __name__ == "__main__": + try: + main() + except KeyboardInterrupt: + print "Operation Aborted!" + diff --git a/deprecated/qpkg/AUTHORS b/deprecated/qpkg/AUTHORS new file mode 100644 index 0000000..e69de29 diff --git a/deprecated/qpkg/ChangeLog b/deprecated/qpkg/ChangeLog new file mode 100644 index 0000000..b25fd25 --- /dev/null +++ b/deprecated/qpkg/ChangeLog @@ -0,0 +1,5 @@ +2004-02-18 Brandon Low + * Fix a reported security issue, have a TMP location that is process specific + +2004-01-07 Karl Trygve Kalleberg + * Added Makefile diff --git a/deprecated/qpkg/Makefile b/deprecated/qpkg/Makefile new file mode 100644 index 0000000..cccdee0 --- /dev/null +++ b/deprecated/qpkg/Makefile @@ -0,0 +1,19 @@ +# Copyright 2004 Karl Trygve Kalleberg +# Copyright 2004 Gentoo Technologies, Inc. +# Distributed under the terms of the GNU General Public License v2 +# +# $Header$ + +include ../../makedefs.mak + +all: + echo "HATHERSAGE (n.) The tiny snippets of beard which coat the inside of a washbasin after shaving in it." + +dist: + mkdir -p ../../${distdir}/src/qpkg + cp Makefile README AUTHORS ChangeLog TODO qpkg qpkg.1 ../../${distdir}/src/qpkg/ + +install: + install -d $(docdir)/deprecated/qpkg + install -m 0755 qpkg $(docdir)/deprecated/qpkg/ + install -m 0644 qpkg.1 README AUTHORS ChangeLog $(docdir)/deprecated/qpkg/ diff --git a/deprecated/qpkg/README b/deprecated/qpkg/README new file mode 100644 index 0000000..e69de29 diff --git a/deprecated/qpkg/TODO b/deprecated/qpkg/TODO new file mode 100644 index 0000000..e69de29 diff --git a/deprecated/qpkg/qpkg b/deprecated/qpkg/qpkg new file mode 100644 index 0000000..dd8344b --- /dev/null +++ b/deprecated/qpkg/qpkg @@ -0,0 +1,581 @@ +#!/bin/bash +# +# qpkg - query portage package system for various information +# +# Copyright (c) Vitaly Kushneriuk +# This program is distributed under the terms of GPL version 2. +# +# Maintainer: Brandon Low +# Additional code thanks to: +# Josh Goebel +# +# $Header$ +ID='$Id$' +VERSION=0.`echo ${ID} | cut -d\ -f3` + +umask 0077 + +TMP="$(mktemp -d -t qpkg-XXXXXX)" +rm -rf ${TMP} +mkdir -p ${TMP} + +PROG=`basename ${0}` + +# Parse args +verb=0 +group="*" +params=${#} +while [ ${#} -gt 0 ] +do + a=${1} + shift + case "${a}" in + + -h|--help) + usage=y + break + ;; + + -i|--info) + info=y + ;; + + -d|--dups) + dups=y + inst=y + ;; + + -q|--query-deps) + query=y + ;; + + -s|--slot) + slot=y + ;; + + -f|--find-file) + ffind=y + inst=y + ;; + + -fp|--find-pattern) + ffind=y + fpat=y + inst=y + ;; + + -I|--installed) + inst=y + ;; + + -m|--masked) + grepmask="-L" + ;; + + -n|--non-masked) + grepmask="-l" + ;; + + -U|--uninstalled) + uninst=y + ;; + + -g|--group) + group=$1 + shift + ;; + + -l|--list) + list=y + inst=y + ;; + + -ct|--check-time|-tc|--time-check) + tcheck=y + inst=y + ;; + + -cm|--check-md5|-mc|--md5-check) + mcheck=y + inst=y + ;; + + -c|--check) + mcheck=y + tcheck=y + inst=y + ;; + + -v|--verbose) + let $((verb++)) + ;; + + -vv) + let $((verb++)) + let $((verb++)) + ;; + + -nc|--no-color|--nocolor|--no-colors|--nocolors) + nocolor=y + ;; + + -*) + echo -e ${CY}${PROG}${NO}:${YL} Invalid option ${RD}$a 1>&2 + usage=y + break + ;; + *) + if [ -n "${arg}" ]; then + echo -e ${CY}${PROG}: ${YL}Only one argument supported + usage=y + break + fi + arg=$a + ;; + + esac +done + +#This is a dumb way to handle things, take it out next time +T="\t" + +#Set up colors +if [ ! "${nocolor}" ]; then + NO="\x1b[0;0m" + BR="\x1b[0;01m" + CY="\x1b[36;01m" + RD="\x1b[31;01m" + GR="\x1b[32;01m" + YL="\x1b[33;01m" + BL="\x1b[34;01m" + STAR=" *" +elif [ ! "${inst}" ] && [ ! "${uninst}" ]; then + STAR=" *" +fi + + +# check for option conflicts +if [ "${inst}" -a "${uninst}" \ + -o \( "${ffind}" -o "${list}" -o "${tcheck}" -o "${mcheck}" \) \ + -a "${uninst}" ]; then + echo -e ${CY}${PROG}${NO}:${YL} conflicting options/modes${NO} + usage=y +fi + +if [ "${usage}" ]; then + echo -e "${CY}${PROG} v. ${VERSION}${NO} + +${CY}${PROG}${NO} is GenToolKit's \"query package\" tool, using it, you can +find packages owning files on your filesystem, check the integrity +of installed packages, and do other queries against installed or +uninstalled packages. + +NOTICE: This tool will be phased out at some point in the + future, please use equery instead. + Bugs are still fixed but new features won't be added. + +${BR}Usage: +${T}${CY}${PROG}${NO} [${BR}options${NO}] [${YL}pkgname${NO}] [${BL}-g${YL} group${NO}] [${BL}-f${YL} ${NO}|${BL}-fp${YL} ${NO}] +${T}${CY}${PROG}${NO} ${BL}--dups${NO} [${BL}--slot${NO}] +${T}${CY}${PROG}${NO} ${BL}--help${NO} + +${BR}Duplicate Locating: + ${BL}-d, --dups${NO}${T}${T}print packages that have multiple versions installed + ${BL}-s, --slot${NO}${T}${T}make ${BL}-d${NO} SLOT only print dups of the same SLOT + +${BR}Package Selection: + ${BL}-f, --find-file${NO}${T}finds package that owns file + ${BL}-fp, --find-pattern${NO}${T}finds to package that owns file matching ** + ${BL}-m, --masked${NO}${T}${T}Include${YL} only${NO} masked packages + ${BL}-n, --non-masked${NO}${T}Include${YL} only${NO} non-masked packages + ${BL}-I, --installed${NO}${T}Include${YL} only${NO} installed packages + ${BL}-U, --uninstalled${NO}${T}Include${YL} only${NO} uninstalled packages + ${BL}-g, --group${NO}${T}${T}Find by group (can be combined with other searches) + +${BR}Information Selection: + ${BL}-l, --list${NO}${T}${T}List package content + ${BL}-i, --info${NO}${T}${T}Get package description and home page. + ${BL}-ct, --check-time${NO} + ${BL}-tc, --time-check${NO}${T}Verify package files timestamps + ${BL}-cm, --check-md5${NO} + ${BL}-mc, --md5-check${NO}${T}Verify package files md5 + ${BL}-c, --check${NO}${T}${T}Verify mtimes${YL} and${NO} md5. + ${BL}-q, --query-deps${NO}${T}display all installed packages +${T}${T}${T}depending on selected packages + +${BR}Operation Modifiers: + ${BL}-nc, --no-color${NO}${T}don't use colors + ${BL}-v, --verbose${NO}${T}Be more verbose [ can be repeated twice ] + ${BL}-vv${NO}${T}${T}${T}Same as ${BL}-v -v${NO} + +${YL}Notes${NO}: +${YL}*${NO} ${BL}-f${NO}, ${BL}-fp, ${BL}-d${NO}, ${BL}-l${NO}, ${BL}-ct${NO}, ${BL}-cm${NO}, and ${BL}-c${NO} apply only to installed packages. +${YL}*${NO} Short options may not be combined on the command-line, yet. +${YL}*${NO} The operation of some flags has been changed by the + stripping of version numbers from some output to see + the version numbers play with ${BL}-v${NO} and ${BL}-vv${NO}. +${YL}*${NO} When using${BL} -f${NO} with ${BL}-l${NO} or ${BL}--check.. -v${NO} options, only + matching files will be displayed, unless ${BL}-v${NO} is doubled, + (yet more verbose) or ${BL}-vv${NO} is used. + + +${YL}Examples${NO}: + ${PROG} --dups print duplicates oldest first + ${PROG} --dups -v .. with versions + ${PROG} print list of installed packages + ${PROG} porta -I print versions of installed portage + ${PROG} porta -i .. + versions in portage tree + descriptions + and homepages + ${PROG} gawk -c -v check integrity of all installed versions of gawk + the older ones will have \"damaged\" files. + ${PROG} -f /bin/ls print package(s) that own /bin/ls +" + rm -rf ${TMP} + exit +fi + +#For the --dups switch only +if [ "${dups}" ]; then +if [ "${grepmask}" ]; then + mask=`python -c 'import portage; print portage.settings["ACCEPT_KEYWORDS"];' 2> /dev/null` + echo -e "Currently accepted keywords: ${BL}${mask}${NO}" + echo -e + mask=`echo ${mask} | perl -pe 's/\s+/|/'` +fi + + #First dig out the list of packages with duplicates + find /var/db/pkg/ -iname "*${arg}*.ebuild" 2> /dev/null > ${TMP}qpkg.lst + dups=`cat ${TMP}qpkg.lst | cut -f7 -d/ | + sed -e 's:\.ebuild$::; s:-r[0-9]*$::; s:-[^-]*$::; /^$/d' | + sort | + uniq -d` + + #Next get all the exact versions + duppak=`cat ${TMP}qpkg.lst | fgrep "${dups}"` + + #Now cut that down to the directory name so we can be smart + dirs=`sed -e 's:/[^/]*$::' ${TMP}qpkg.lst` + + #Go through each package's DB and create a sortable file + #to play with + declare -i defcount=`cat /var/cache/edb/counter` + for DIR in ${dirs} + do #Package COUNTER + NUM=`cat "${DIR}/COUNTER" 2> /dev/null` + [ -z "${NUM}" ] && NUM=defcount + #Package slot if requested + [ ${slot} ] && SLOT=`cat "${DIR}/SLOT"` + #Package fullname + PKG=`ls --color=no -1 ${DIR}/*.ebuild|cut -f5,7 -d"/"` + #Package basename + NAME=`echo "${PKG}"|sed -e 's:\.ebuild$::; s:-r[0-9]\+$::; s:-[0-9].*$::'` + echo "${NUM} ${PKG} ${NAME}${SLOT}" + #Finish loop, and sort that nice sortable file based on + #installation order, and then based on package basename + #bash hates me so I decided to use a temp file + done |sort -t" " -k3 -k1g,2|uniq -D -f2 > ${TMP}qpkg.lst + duppak=`cat ${TMP}qpkg.lst` + rm ${TMP}qpkg.lst + + #If max verbosity is set output with full path to each ebuild + if [ "${verb}" -gt 1 ]; then + echo -n "${duppak}"|cut -f2 -d" "| \ + sed -e "s:^:${BL}/var/db/pkg/${BR}:" \ + -e "s:\(/\)\([^/]*\)\(.ebuild\):\1${CY}\2${NO}\1\2\3:" + + #If normal verbosity output package group, package name and package version + elif [ "${verb}" -gt 0 ]; then + echo -n "${duppak}"|cut -f2 -d" "| \ + sed -e "s:\(^[^/]*/\)\(.*\)\(\.ebuild\):${BR}\1${CY}\2${NO}:" + + #Otherwise just output package group and package name + else + echo -n "${duppak}"|cut -f2 -d" "| \ + sed -e "s:-r[0-9]\+$::" \ + -e "s:-[0-9].*$::" \ + -e "s:\(^[^/]*/\)\(.*\):${BR}\1${CY}\2${NO}:"|uniq + fi + rm -rf ${TMP} + exit +fi + +# get list of ebuilds to work on +if [ "${ffind}" ]; then + # file find mode - list all ebuilds for + # package/CONTENTS containing + if [ "${fpat}" ]; then + dirs=`ls /var/db/pkg/${group}/*/CONTENTS \ + | xargs grep -l "${arg} " \ + | xargs --no-run-if-empty -n 1 dirname` + else + # if the user didnt specify a full path assume they + # want to check in the working dir #17331 + [ "${arg:0:1}" != "/" ] && arg="${PWD}/${arg}" + + dirs=`ls /var/db/pkg/${group}/*/CONTENTS \ + | xargs grep -Fl " ${arg} " \ + | xargs --no-run-if-empty -n 1 dirname` + fi + ipak=`( + for d in ${dirs} -;do + [ "-" = "$d" ] && break + ls ${d}/*.ebuild + done)` +else + # normal mode - list ebuilds for ebuild name containing + + # installed packages + if [ ! "${uninst}" ]; then + ipak=`find /var/db/pkg/ -iname "*.ebuild" 2>/dev/null` + if [[ ${group} != "*" ]]; then + ipak=`echo ${ipak}|sed -e "s: :\n:g"|grep ${group}` + fi + if [ ${arg} ]; then + # avoid ${arg}="db" from pulling in every installed package + temp="/var/db/pkg/.*${arg}" + ipak=`echo ${ipak}|sed -e "s: :\n:g"|grep -i ${temp}` + fi + if [ -n "${mask}" ]; then + ipak=`echo ${ipak}|xargs -r egrep ${grepmask} "^KEYWORDS=.*[[:space:]\"\'](${mask})[[:space:]\"\']"` + fi + fi + # not installed packages (yet:-) + if [ ! "${inst}" ]; then + upak=`find /usr/portage/ -iname "*.ebuild" 2>/dev/null|grep -v --regex="/usr/portage/[^/]*\.ebuild"` + if [[ ${group} != "*" ]]; then + upak=`echo ${upak}|sed -e "s: :\n:g"|grep ${group}` + fi + if [ ${arg} ]; then + upak=`echo ${upak}|sed -e "s: :\n:g"|grep -i ${arg}` + fi + if [ -n "${mask}" ]; then + upak=`echo ${upak}|xargs -r egrep ${grepmask} "^KEYWORDS=.*[[:space:]\"\'](${mask})[[:space:]\"\']"` + fi + fi +fi + +X="\([^/]*\)" + +for p in ${ipak} ${upak} -;do + [ "${p}" = "-" ] && break + + # cut common prefix from ebuild name and mark installed/uninstalled packages + # Note: iii/uuu will be replaced by the pipe at the end + n=${p%.ebuild} + var_db_pkg="/var/db/pkg/" + n=${n/${var_db_pkg}/iii } + usr_portage="/usr/portage/" + n=${n/${usr_portage}/uuu } + n=${n/\/*\//\/} + + d=${p%\/*.ebuild} # faster d=`dirname ${p}` + echo ${n} + + # if we have no passed parameters then + # we can skip the extra conditional checks + [[ ${params} == 0 ]] && continue; + + if [ "${mask}" ]; then + keywords=`grep KEYWORDS ${p}| cut -d\" -f2` + echo -e "${T}Keywords: ${BL}${keywords}${NO}" + fi + + if [ ${verb} -gt 1 ];then + echo "vvv ${p}" + fi + + if [ "${info}" ]; then + source ${p} 2> /dev/null + home="${HOMEPAGE}" + desc="${DESCRIPTION}" + #home=`grep HOMEPAGE ${p}| cut -d\" -f2` + #desc=`grep DESCRIPTION ${p}|cut -d= -f2-|cat` + echo -e "${T}${BL}${desc}${NO} [ ${YL}${home}${NO} ]" + if [ ${verb} -gt 0 ]; then + pdir=${p/$(basename ${p})/} + if [[ -r ${pdir}/USE && -r ${pdir}/IUSE ]]; then + echo -n "Compiled with USE Flags: " + for flag in $(<${pdir}/IUSE) + do + use=$(grep -o ${flag} ${pdir}/USE | tr -d '\n') + if [[ "${use}" == "" ]]; then + echo -n "-" + fi + echo -n "${flag} " + done + echo + fi + fi + fi + + if [ "${query}" ]; then + echo -e "${BL}DEPENDED ON BY:${NO}" + package="`echo ${n}|sed -e 's:-r[0-9]\+$::' \ + -e 's:-[0-9].*$::' \ + -e 's:^iii ::' \ + -e 's:^uuu ::'`" + place="`echo ${n}|cut -f1 -d' '`" + [[ "${place}" == "iii" ]] && color="${GR}" || color="${RD}" + + if [[ ${place} == "iii" ]]; then + for deppkg in $(grep -R "${package}" /var/db/pkg/*/*/RDEPEND | sed 's/RDEPEND.*$//') + do + rdepend=$(< ${deppkg}/RDEPEND) + + for flag in $(< ${deppkg}/USE) + do + if [[ "${flag:0:1}" == "-" ]]; then + rdepend="$(echo ${rdepend} | sed 's/${flag:1}? ( [[:alnum:][:punct:]]* )//')" + fi + done + + if [[ $(echo ${rdepend} | grep -o ${package}) == ${package} ]]; then + echo $'\t'$(< ${deppkg}/PF) + fi + done + else + grep -R "${package}" /var/db/pkg/*/*/RDEPEND | \ + cut -f5,6 -d"/" | sed -e "s:^:\t${color}:;s:$:${NO}:" | sort -u + fi + if [[ $(grep -R "*${package}" /etc/make.profile/packages) != "" ]]; then + echo -e "\t${color}SYSTEM PROFILE${NO}" + fi + fi + + # cat package content, remove obj/sym/dir, md5 and mtime when not verbose + # display only match in file-find mode unless extra verbose + if [ "${list}" ]; then + echo -e ${BL}CONTENTS:${NO} + + if [ ${verb} -gt 1 ]; then + cat ${d}/CONTENTS + else + if [ "${ffind}" ]; then + if [ "${fpat}" ]; then + grep "${arg}[:blank:]" $d/CONTENTS + else + grep " ${arg}\( .*\)*$" $d/CONTENTS + fi + else + cat $d/CONTENTS + fi | + if [ ${verb} -gt 0 ]; then + cat + else + sed -e "s:\(^obj \)\(.*\)\( .*\)\{2\}$:\1${BR}\2${NO}:; + s:\(^sym \)\(.*\)\( -> \)\(.*\)\( .*\)\{2\}$:\1${CY}\2${NO}\3\4:; + s:\(^dir \)\(.*\)$:\1${YL}\2${NO}:" + fi + fi + + echo + + # check files mtime and md5, display summary at the end + elif [ "${tcheck}" -o "${mcheck}" ]; then + # counters + fe=0 + fs=0 + # read the CONTENTS file and check md5 and mtime if needed + # process only matching files in find-file mode unless extra verbose + cat ${d}/CONTENTS | + if [ "${ffind}" -a ${verb} -lt 2 ];then + if [ "${fpat}" ]; then + grep "${arg}" + else + grep " ${arg} " + fi + else + cat + fi | + ( + while read -a line + do + fs=$((fs + 1)) + + unset md5 + unset _md5 + unset mtime + unset _mtime + unset err + unset len + + len="${#line[*]}" + if [ "${line[0]}" = "obj" ]; then + name= + for i in `seq 1 $((${len}-3))`; do + [ "${name}" ] && name="${name} ${line[${i}]}" || name="${line[${i}]}" + done + else + name="${line[1]}" + fi + + missing= + [ ! -e "${name}" ] && missing=1 + + # colorize name and compute mtime/md5 + if [ "obj" = "${line[0]}" ]; then + [ -e "${name}" ] && { + [ "${tcheck}" ] && mtime="${line[$((${len}-1))]}" + [ "${tcheck}" ] && _mtime=`date -r "${name}" +%s` + + [ "${mcheck}" ] && md5=${line[$((${len}-2))]} + [ "${mcheck}" ] && _md5=`md5sum "${name}"|cut -f1 -d" "` + } + + name="${BR}${name}${NO}" + + elif [ "sym" = "${line[0]}" ]; then + name="${CY}${name}${NO}" + + elif [ "dir" = "${line[0]}" ]; then + name="${YL}${name}${NO}" + fi + + # compare + if [ "${missing}" ]; then + err=1 + name="${name} ${RD}!not exist!${NO}" + fi + if [ "${md5}" != "${_md5}" ]; then + #If the md5 fails the first time check it with + #everything changed to lowercase :-D + md5="$(echo ${md5}|tr A-Z a-z)" + if [ "${md5}" != "${_md5}" ]; then + err=1 + name="${name} ${RD}!md5!${NO}" + fi + fi + if [ "${mtime}" != "${_mtime}" ]; then + err=1 + name="${name} ${RD}!mtime!${NO}" + fi + + [ "${verb}" -gt 1 ] && echo -e "${name}" + [[ "${verb}" -eq 1 ]] && [[ "${err}" -eq 1 ]] && echo -e "${name}" + + fe=$((fe + err)) + done + if [ "${fe}" = "0" ]; then + echo -e "${YL}${fe}${CY}/${fs}${NO}" + else + echo -e "${RD}${fe}${CY}/${fs}${NO}" + fi + echo + ) + fi + +done | ( + if [ ! \( "${tcheck}" -o "${mcheck}" -o "${info}" -o "${list}" -o "${query}" -o "${mask}" -o ${verb} -gt 0 \) ]; then + sed -e "s:-r[0-9]\+$::" -e "s:-[0-9][^-]*$::"|sort -k2|uniq -f1 + elif [ ! \( "${tcheck}" -o "${mcheck}" -o "${info}" -o "${list}" -o "${query}" -o "${mask}" -o ${verb} -lt 2 \) ]; then + sort -k2|uniq -f1 + else + cat + fi | sed \ + -e "s:^iii ${X}/${X}:${BR}\1/${CY}\2${STAR}${NO}:" \ + -e "s:^uuu ${X}/${X}:${BR}\1/${YL}\2${NO}:" \ + -e "s:^vvv \(.*\)$:${BL}\1${NO}:" \ + -e "s:^obj ::;s:^sym ::;s:^dir ::" + +) +rm -rf ${TMP} diff --git a/deprecated/qpkg/qpkg.1 b/deprecated/qpkg/qpkg.1 new file mode 100644 index 0000000..6d45a93 --- /dev/null +++ b/deprecated/qpkg/qpkg.1 @@ -0,0 +1,112 @@ +.TH "qpkg" "1" "1.6" "gentoolkit 0.1.11-r1" "" +.SH "NAME" +qpkg \- Gentoo: query package tool +.SH "SYNOPSIS" +.LP +.B qpkg\fR [\fIoptions\fR] [\fIpkgname\fR] [\fI\-g group\fR] +.br + [\fI\-f \fR|\fI\-fp \fR] +.TP +.B qpkg \fI\-\-dups\fR [\fI\-\-slot\fR] +.TP +.B qpkg \fI\-\-help\fR +.SH "DESCRIPTION" +qpkg is GenToolKit's "query package" tool, using it, you can find packages owning files on your filesystem, check the integrity of installed packages, and do other queries against installed or uninstalled packages. +.SH "OPTIONS " +.LP +.I Duplicate Locating: +.LP +.B \-d, \-\-dups\fR print packages that have multiple +.br + versions installed +.br +.B \-s, \-\-slot\fR make \-d SLOT only print dups of the +.br + same SLOT +.LP +.I Package Selection: +.LP +.B \-f, \-\-find\-file\fR Finds package that owns file +.br +.B \-fp, \-\-find\-pattern\fR Finds to package that owns file +.br + matching ** +.br +.B \-I, \-\-installed\fR Include only installed packages +.br +.B \-U, \-\-uninstalled\fR Include only uninstalled packages +.br +.B \-g, \-\-group\fR Find by group (can be combined with +.br + other searches) +.LP +.I Information Selection: +.LP +.B \-l, \-\-list\fR List package content +.br +.B \-i, \-\-info\fR Get package description and home page. +.br +.B \-ct, \-\-check\-time +.br +.B \-tc, \-\-time\-check\fR Verify package files timestamps +.br +.B \-cm, \-\-check\-md5 +.br +.B \-mc, \-\-md5\-check\fR Verify package files md5 +.br +.B \-c, \-\-check\fR Verify mtimes and md5. +.br +.B \-q, \-\-query\-deps\fR display all installed packages +.br +\fR depending on selected packages +.LP +.I Operation Modifiers: +.LP +.B \-nc, \-\-no\-color\fR Don't use colors +.br +.B \-v, \-\-verbose\fR Be more verbose [2 levels] +.br +.B \-vv\fR Same as \-v \-v +.SH "NOTES" +\fI\-f, \-fp, \-d, \-l, \-ct, \-cm, \fRand \fI\-c\fR apply only to installed packages. +.br +.TP +Short options may not be combined on the command\-line, yet. +.TP +The operation of some flags has been changed in version 1.6 by the stripping of version numbers from some output to see the version numbers play with \fI\-v\fR and \fI\-vv\fR. +.TP +When using \fI\-f\fR with \fI\-l\fR or \fI\-\-check.. \-v\fR options, only matching files will be displayed, unless \fI\-v\fR is doubled, (yet more verbose), equivalent to \fI\-vv\fR. +.TP +When using \fI\-q\fR, it is important to note that the querying of deps checks package names only, because qpkg is not advanced enough (nor can it reasonably made so) to check complete deps with versions. Please use \fBdepclean\fR or \fBemerge --dep-clean\fR to more completely check the dependency sanity of your system. +.SH "EXAMPLES" +.LP +.B qpkg \fI\-\-dups\fR print duplicates oldest first +.br +.B qpkg \fI\-\-dups \-v\fR.. with versions +.br +.B qpkg\fR print list of packages +.br +.B qpkg\fR porta \fI\-I\fR print versions of installed portage +.br +.B qpkg porta \fI\-i\fR .. + versions in portage tree + +.br + descriptions and homepages +.br +.B qpkg gawk \fI\-c \-v\fR check integrity all installed versions +.br + of gawk the older versions will have +.br + "damaged" files. +.br +.B qpkg \fI\-f\fR /bin/ls print package(s) that own /bin/ls +.SH "AUTHORS" +Vitaly Kushneriuk , 2002: qpkg +.br +Karl Trygve Kalleberg , 2002: man page +.br +Brandon Low , 2002: maintainance +.SH "SEE ALSO" +ebuild(5) +.TP +The \fI/usr/sbin/qpkg\fR script. +.TP diff --git a/deprecated/qpkg/qpkg.sh b/deprecated/qpkg/qpkg.sh new file mode 100644 index 0000000..cdbe3c7 --- /dev/null +++ b/deprecated/qpkg/qpkg.sh @@ -0,0 +1,520 @@ +#!/bin/bash +# +# qpkg - query portage package system for various information +# +# Copyright (c) Vitaly Kushneriuk +# This program is distributed under the terms of GPL version 2. +# +# Maintainer: Brandon Low +# Additional code thanks to: +# Josh Goebel +# +# $Header$ +ID='$Id$' +VERSION=0.`echo ${ID} | cut -d\ -f3` + +PROG=`basename ${0}` + +# Parse args +verb=0 +group="*" +params=${#} +while [ ${#} -gt 0 ] +do + a=${1} + shift + case "${a}" in + + -h|--help) + usage=y + break + ;; + + -i|--info) + info=y + ;; + + -d|--dups) + dups=y + inst=y + ;; + + -q|--query-deps) + query=y + ;; + + -s|--slot) + slot=y + ;; + + -f|--find-file) + ffind=y + inst=y + ;; + + -fp|--find-pattern) + ffind=y + fpat=y + inst=y + ;; + + -I|--installed) + inst=y + ;; + + -m|--masked) + grepmask="-L" + ;; + + -n|--non-masked) + grepmask="-l" + ;; + + -U|--uninstalled) + uninst=y + ;; + + -g|--group) + group=$1 + shift + ;; + + -l|--list) + list=y + inst=y + ;; + + -ct|--check-time|-tc|--time-check) + tcheck=y + inst=y + ;; + + -cm|--check-md5|-mc|--md5-check) + mcheck=y + inst=y + ;; + + -c|--check) + mcheck=y + tcheck=y + inst=y + ;; + + -v|--verbose) + let $((verb++)) + ;; + + -vv) + let $((verb++)) + let $((verb++)) + ;; + + -nc|--no-color|--nocolor|--no-colors|--nocolors) + nocolor=y + ;; + + -*) + echo -e ${CY}${PROG}${NO}:${YL} Invalid option ${RD}$a 1>&2 + usage=y + break + ;; + *) + if [ -n "${arg}" ]; then + echo -e ${CY}${PROG}: ${YL}Only one argument supported + usage=y + break + fi + arg=$a + ;; + + esac +done + +#This is a dumb way to handle things, take it out next time +T="\t" + +#Set up colors +if [ ! "${nocolor}" ]; then + NO="\x1b[0;0m" + BR="\x1b[0;01m" + CY="\x1b[36;01m" + RD="\x1b[31;01m" + GR="\x1b[32;01m" + YL="\x1b[33;01m" + BL="\x1b[34;01m" + STAR=" *" +elif [ ! "${inst}" ] && [ ! "${uninst}" ]; then + STAR=" *" +fi + + +# check for option conflicts +if [ "${inst}" -a "${uninst}" \ + -o \( "${ffind}" -o "${list}" -o "${tcheck}" -o "${mcheck}" \) \ + -a "${uninst}" ]; then + echo -e ${CY}${PROG}${NO}:${YL} conflicting options/modes${NO} + usage=y +fi + +if [ "${usage}" ]; then + echo -e "${CY}${PROG} v. ${VERSION}${NO} + +${CY}${PROG}${NO} is GenToolKit's \"query package\" tool, using it, you can +find packages owning files on your filesystem, check the integrity +of installed packages, and do other queries against installed or +uninstalled packages. + +${BR}Usage: +${T}${CY}${PROG}${NO} [${BR}options${NO}] [${YL}pkgname${NO}] [${BL}-g${YL} group${NO}] [${BL}-f${YL} ${NO}|${BL}-fp${YL} ${NO}] +${T}${CY}${PROG}${NO} ${BL}--dups${NO} [${BL}--slot${NO}] +${T}${CY}${PROG}${NO} ${BL}--help${NO} + +${BR}Duplicate Locating: + ${BL}-d, --dups${NO}${T}${T}print packages that have multiple versions installed + ${BL}-s, --slot${NO}${T}${T}make ${BL}-d${NO} SLOT only print dups of the same SLOT + +${BR}Package Selection: + ${BL}-f, --find-file${NO}${T}finds package that owns file + ${BL}-fp, --find-pattern${NO}${T}finds to package that owns file matching ** + ${BL}-m, --masked${NO}${T}Include${YL} only${NO} masked packages + ${BL}-n, --non-masked${NO}${T}Include${YL} only${NO} non-masked packages + ${BL}-I, --installed${NO}${T}Include${YL} only${NO} installed packages + ${BL}-U, --uninstalled${NO}${T}Include${YL} only${NO} uninstalled packages + ${BL}-g, --group${NO}${T}${T}Find by goup (can be combined with other searches) + +${BR}Information Selection: + ${BL}-l, --list${NO}${T}${T}List package content + ${BL}-i, --info${NO}${T}${T}Get package description and home page. + ${BL}-ct, --check-time${NO} + ${BL}-tc, --time-check${NO}${T}Verify package files timestamps + ${BL}-cm, --check-md5${NO} + ${BL}-mc, --md5-check${NO}${T}Verify package files md5 + ${BL}-c, --check${NO}${T}${T}Verify mtimes${YL} and${NO} md5. + ${BL}-q, --query-deps${NO}${T}display all installed packages +${T}${T}${T}depending on selected packages + +${BR}Operation Modifiers: + ${BL}-nc, --no-color${NO}${T}don't use colors + ${BL}-v, --verbose${NO}${T}Be more verbose [ can be repeated twise ] + ${BL}-vv${NO}${T}${T}${T}Same as ${BL}-v -v${NO} + +${YL}Notes${NO}: +${YL}*${NO} ${BL}-f${NO}, ${BL}-fp, ${BL}-d${NO}, ${BL}-l${NO}, ${BL}-ct${NO}, ${BL}-cm${NO}, and ${BL}-c${NO} apply only to installed packages. +${YL}*${NO} Short options may not be combined on the command-line, yet. +${YL}*${NO} The operation of some flags has been changed by the + stripping of version numbers from some output to see + the version numbers play with ${BL}-v${NO} and ${BL}-vv${NO}. +${YL}*${NO} When using${BL} -f${NO} with ${BL}-l${NO} or ${BL}--check.. -v${NO} options, only + matching files will be displayed, unless ${BL}-v${NO} is doubled, + (yet more verbose) or ${BL}-vv${NO} is used. + + +${YL}Examples${NO}: + ${PROG} --dups print duplicates oldest first + ${PROG} --dups -v .. with versions + ${PROG} print list of installed packages + ${PROG} porta -I print versions of installed portage + ${PROG} porta -i .. + versions in portage tree + descriptions + and homepages + ${PROG} gawk -c -v check integrity all installed versions of gawk + the older will have \"damaged\" files. + ${PROG} -f /bin/ls print package(s) that own /bin/ls +" + exit +fi + +#For the --dups switch only +if [ "${dups}" ]; then +if [ "${grepmask}" ]; then + mask=`python -c 'import portage; print portage.settings["ACCEPT_KEYWORDS"];' 2> /dev/null` + echo -e "Currently accepted keywords: ${BL}${mask}${NO}" + echo -e + mask=`echo ${mask} | perl -pe 's/\s+/|/'` +fi + + #First dig out the list of packages with duplicates + find /var/db/pkg -iname "*${arg}*.ebuild" 2> /dev/null > /tmp/qpkg.lst + dups=`cat /tmp/qpkg.lst | cut -f7 -d/ | + sed -e 's:\.ebuild$::; s:-r[0-9]*$::; s:-[^-]*$::; /^$/d' | + sort | + uniq -d` + + #Next get all the exact versions + duppak=`cat /tmp/qpkg.lst | fgrep "${dups}"` + + #Now cut that down to the directory name so we can be smart + dirs=`sed -e 's:/[^/]*$::' /tmp/qpkg.lst` + + #Go through each package's DB and create a sortable file + #to play with + declare -i defcount=`cat /var/cache/edb/counter` + for DIR in ${dirs} + do #Package COUNTER + NUM=`cat "${DIR}/COUNTER" 2> /dev/null` + [ -z "${NUM}" ] && NUM=defcount + #Package slot if requested + [ ${slot} ] && SLOT=`cat "${DIR}/SLOT"` + #Package fullname + PKG=`ls --color=no -1 ${DIR}/*.ebuild|cut -f5,7 -d"/"` + #Package basename + NAME=`echo "${PKG}"|sed -e 's:\.ebuild$::; s:-r[0-9]\+$::; s:-[0-9].*$::'` + echo "${NUM} ${PKG} ${NAME}${SLOT}" + #Finish loop, and sort that nice sortable file based on + #installation order, and then based on package basename + #bash hates me so I decided to use a temp file + done |sort -t" " -k3 -k1g,2|uniq -D -f2 > /tmp/qpkg.lst + duppak=`cat /tmp/qpkg.lst` + rm /tmp/qpkg.lst + + #If max verbosity is set output with full path to each ebuild + if [ "${verb}" -gt 1 ]; then + echo -n "${duppak}"|cut -f2 -d" "| \ + sed -e "s:^:${BL}/var/db/pkg/${BR}:" \ + -e "s:\(/\)\([^/]*\)\(.ebuild\):\1${CY}\2${NO}\1\2\3:" + + #If normal verbosity output package group, package name and package version + elif [ "${verb}" -gt 0 ]; then + echo -n "${duppak}"|cut -f2 -d" "| \ + sed -e "s:\(^[^/]*/\)\(.*\)\(\.ebuild\):${BR}\1${CY}\2${NO}:" + + #Otherwise just output package group and package name + else + echo -n "${duppak}"|cut -f2 -d" "| \ + sed -e "s:-r[0-9]\+$::" \ + -e "s:-[0-9].*$::" \ + -e "s:\(^[^/]*/\)\(.*\):${BR}\1${CY}\2${NO}:"|uniq + fi + exit +fi + +# get list of ebuilds to work on +if [ "${ffind}" ]; then + # file find mode - list all ebuilds for + # package/CONTENTS containing + if [ "${fpat}" ]; then + dirs=`ls /var/db/pkg/${group}/*/CONTENTS \ + | xargs grep -l "${arg}" \ + | xargs --no-run-if-empty -n 1 dirname` + else + # if the user didnt specify a full path assume they + # want to check in the working dir #17331 + [ "${arg:0:1}" != "/" ] && arg="${PWD}/${arg}" + + dirs=`ls /var/db/pkg/${group}/*/CONTENTS \ + | xargs grep -l " ${arg}\( .*\)*$" \ + | xargs --no-run-if-empty -n 1 dirname` + fi + ipak=`( + for d in ${dirs} -;do + [ "-" = "$d" ] && break + ls ${d}/*.ebuild + done)` +else + # normal mode - list ebuilds for ebuild name containing + + # installed packages + if [ ! "${uninst}" ]; then + ipak=`find /var/db/pkg/ -iname "*.ebuild" 2>/dev/null` + if [[ ${group} != "*" ]]; then + ipak=`echo ${ipak}|sed -e "s: :\n:g"|grep ${group}` + fi + if [ ${arg} ]; then + # avoid ${arg}="db" from pulling in every installed package + temp="/var/db/pkg/.*${arg}" + ipak=`echo ${ipak}|sed -e "s: :\n:g"|grep ${temp}` + fi + if [ -n "${mask}" ]; then + ipak=`echo ${ipak}|xargs -r egrep ${grepmask} "^KEYWORDS=.*[[:space:]\"\'](${mask})[[:space:]\"\']"` + fi + fi + # not installed packages (yet:-) + if [ ! "${inst}" ]; then + upak=`find /usr/portage/ -iname "*.ebuild" 2>/dev/null|grep -v --regex="/usr/portage/[^/]*\.ebuild"` + if [[ ${group} != "*" ]]; then + upak=`echo ${upak}|sed -e "s: :\n:g"|grep ${group}` + fi + if [ ${arg} ]; then + upak=`echo ${upak}|sed -e "s: :\n:g"|grep ${arg}` + fi + if [ -n "${mask}" ]; then + upak=`echo ${upak}|xargs -r egrep ${grepmask} "^KEYWORDS=.*[[:space:]\"\'](${mask})[[:space:]\"\']"` + fi + fi +fi + +X="\([^/]*\)" + +for p in ${ipak} ${upak} -;do + [ "${p}" = "-" ] && break + + # cut common prefix from ebuild name and mark installed/uninstalled packages + # Note: iii/uuu will be replaced by the pipe at the end + n=${p%.ebuild} + var_db_pkg="/var/db/pkg/" + n=${n/${var_db_pkg}/iii } + usr_portage="/usr/portage/" + n=${n/${usr_portage}/uuu } + n=${n/\/*\//\/} + + d=${p%\/*.ebuild} # faster d=`dirname ${p}` + echo ${n} + + # if we have no passed parameters then + # we can skip the extra conditional checks + [[ ${params} == 0 ]] && continue; + + if [ "${mask}" ]; then + keywords=`grep KEYWORDS ${p}| cut -d\" -f2` + echo -e "${T}Keywords: ${BL}${keywords}${NO}" + fi + + if [ ${verb} -gt 1 ];then + echo "vvv ${p}" + fi + + if [ "${info}" ]; then + home=`grep HOMEPAGE ${p}| cut -d\" -f2` + desc=`grep DESCRIPTION ${p}| cut -d\" -f2` + echo -e "${T}${BL}${desc}${NO} [ ${YL}${home}${NO} ]" + fi + + if [ "${query}" ]; then + echo -e "${BL}DEPENDED ON BY:${NO}" + package="`echo ${n}|sed -e 's:-r[0-9]\+$::' \ + -e 's:-[0-9].*$::' \ + -e 's:^iii ::' \ + -e 's:^uuu ::'`" + place="`echo ${n}|cut -f1 -d' '`" + [[ "${place}" == "iii" ]] && color="${GR}" || color="${RD}" + grep -R "${package}" /var/db/pkg/*/*/RDEPEND | \ + cut -f5,6 -d"/" | sed -e "s:^:\t${color}:;s:$:${NO}:" | sort | uniq +# gawk -F "/" '{printf("${place}\n\t%s/%s${NO}",$5,$6)}' | sort | uniq + fi + + # cat package content, remove obj/sym/dir, md5 and mtime when not verbose + # display only match in file-find mode unless extra verbose + if [ "${list}" ]; then + echo -e ${BL}CONTENTS:${NO} + + if [ ${verb} -gt 1 ]; then + cat ${d}/CONTENTS + else + if [ "${ffind}" ]; then + if [ "${fpat}" ]; then + grep "${arg}" $d/CONTENTS + else + grep " ${arg}\( .*\)*$" $d/CONTENTS + fi + else + cat $d/CONTENTS + fi | + if [ ${verb} -gt 0 ]; then + cat + else + sed -e "s:\(^obj \)\([^ ]*\)\(.*$\):\1${BR}\2${NO}:; + s:\(^sym \)\([^ ]*\)\( -> \)\([^ ]*\)\(.*$\):\1${CY}\2${NO}\3\4:; + s:\(^dir \)\([^ ]*\)\(.*$\):\1${YL}\2${NO}:" + fi + fi + + echo + + # check files mtime and md5, display summary at the end + elif [ "${tcheck}" -o "${mcheck}" ]; then + # counters + fe=0 + fs=0 + # read the CONTENTS file and check md5 and mtime if needed + # process only matching files in find-file mode unless extra verbose + cat ${d}/CONTENTS | + if [ "${ffind}" -a ${verb} -lt 2 ];then + if [ "${fpat}" ]; then + grep "${arg}" + else + grep " ${arg} " + fi + else + cat + fi | + ( + while read -a line + do + fs=$((fs + 1)) + + unset md5 + unset _md5 + unset mtime + unset _mtime + unset err + + name=${line[1]} + + missing= + [ ! -e ${name} ] && missing=1 + + # colorize name and compute mtime/md5 + if [ "obj" = ${line[0]} ]; then + [ -e ${name} ] && { + [ "${tcheck}" ] && mtime=${line[3]} + [ "${tcheck}" ] && _mtime=`date -r ${name} +%s` + + [ "${mcheck}" ] && md5=${line[2]} + [ "${mcheck}" ] && _md5=`md5sum ${name}|cut -f1 -d" "` + } + + name=${BR}${name}${NO} + + elif [ "sym" = ${line[0]} ]; then + name=${CY}${name}${NO} + + elif [ "dir" = ${line[0]} ]; then + name=${YL}${name}${NO} + fi + + # compare + if [ "$missing" ]; then + err=1 + name="${name} ${RD}!not exist!${NO}" + fi + if [ "${md5}" != "${_md5}" ]; then + #If the md5 fails the first time check it with + #everything changed to lowercase :-D + md5=`echo "${md5}"|tr A-Z a-z` + if [ "${md5}" != "${_md5}" ]; then + err=1 + name="${name} ${RD}!md5!${NO}" + fi + fi + if [ "${mtime}" != "${_mtime}" ]; then + err=1 + name="${name} ${RD}!mtime!${NO}" + fi + + [ ${verb} -gt 1 ] && echo -e ${name} + [[ ${verb} -eq 1 ]] && [[ $err -eq 1 ]] && echo -e ${name} + + fe=$((fe + err)) + done + if [ "$fe" = "0" ]; then + echo -e ${YL}$fe${CY}/$fs${NO} + else + echo -e ${RD}$fe${CY}/$fs${NO} + fi + echo + ) + fi + +done | ( + if [ ! \( "${tcheck}" -o "${mcheck}" -o "${info}" -o "${list}" -o "${query}" -o "${mask}" -o ${verb} -gt 0 \) ]; then + sed -e "s:-r[0-9]\+$::" -e "s:-[0-9][^-]*$::"|sort -k2|uniq -f1 + elif [ ! \( "${tcheck}" -o "${mcheck}" -o "${info}" -o "${list}" -o "${query}" -o "${mask}" -o ${verb} -lt 2 \) ]; then + sort -k2|uniq -f1 + else + cat + fi | sed \ + -e "s:^iii ${X}/${X}:${BR}\1/${CY}\2${STAR}${NO}:" \ + -e "s:^uuu ${X}/${X}:${BR}\1/${YL}\2${NO}:" \ + -e "s:^vvv \(.*\)$:${BL}\1${NO}:" \ + -e "s:^obj ::;s:^sym ::;s:^dir ::" + +) diff --git a/deprecated/useflag/AUTHORS b/deprecated/useflag/AUTHORS new file mode 100644 index 0000000..e69de29 diff --git a/deprecated/useflag/ChangeLog b/deprecated/useflag/ChangeLog new file mode 100644 index 0000000..e69de29 diff --git a/deprecated/useflag/README b/deprecated/useflag/README new file mode 100644 index 0000000..e69de29 diff --git a/deprecated/useflag/useflag b/deprecated/useflag/useflag new file mode 100644 index 0000000..fd4cc08 --- /dev/null +++ b/deprecated/useflag/useflag @@ -0,0 +1,610 @@ +#!/bin/bash +# useflag v0.3.1 +# Script to help users manage USE flags in Gentoo Linux +# +# Distributed under the terms of the GNU General Public License, v2 or later +# Author: Michael Thompson , (c) 2002 + +run_name=`basename $0` +use_desc="/usr/portage/profiles/use.desc" +make_conf_dir="/etc" +make_conf="${make_conf_dir}/make.conf" +# Home directory was chosen as the use of /tmp allows for symlink attacks +make_temp="${HOME}/use.make.conf.tmp" +use_cache_parent="/var/cache" +use_cache_dir="${use_cache_parent}/use_desc" +use_cache="${use_cache_dir}/use.cache" +lock_cache="${use_cache_dir}/lock.cache" +changes="0" + + +# Get flag description +# parm1 = Use flag to get description of +do_get_desc() { + local parm1=$1 + # Strip the comments and find the flag. + local out_get_desc=`grep -v "#" ${use_desc} | grep -w -e "${parm1} -"` + if [ "${out_get_desc}" = "" ]; then + local lcl_avail=`grep -v "#" ${use_desc} | cut -d ' ' -f1 | \ + grep -w -e "${parm1}"` + if [ "${lcl_avail}" != "" ]; then + echo "${parm1} - No description available." + else + echo "!!! ${parm1} does not exist." + fi + else + echo "${out_get_desc}" + fi +} + +# Get the contents of the USE variable +# parm1 controls whether or not to include the '-' with each flag +do_get_make() { + local parm1=$1 + # Get the USE flags from make.conf + # using `source` now instead of brain-damaged grepping + source ${make_conf} + local get_make_out=${USE} + # If called with "nodashes", then strip the leading dashes + if [ "${parm1}" = "nodashes" ]; then + for tr_sucks in ${get_make_out}; do + if [ "${tr_sucks:0:1}" = "-" ]; then + local tr_out="${tr_out} ${tr_sucks:1}" + else + local tr_out="${tr_out} ${tr_sucks}" + fi + done + get_make_out="${tr_out}" + fi + echo "${get_make_out}" +} + +# Yes, it's pointless. But it could be used more than once in the future +# so it's a function. +# Gets the master list of available USE flags from use.desc +do_get_avail() { + grep -v "#" ${use_desc} | cut -d " " -f1 | tr '\n' ' ' +} + +# Get deprecated flags. +# parm1 = flag to check for deprecation +# parm2 = list of available flags +do_get_depr() { + local parm1=$1 + local parm2=${@:2} + # This next var can't be local + get_depr_tmp=`echo "${parm2}" | tr ' ' '\n' | grep -x -e "${parm1}"` + local ret_code=$? + if [ "${ret_code}" != "0" ]; then + echo "${parm1}" | tr '\n' ' ' + fi +} + +# Removes a USE flag from make.conf +# parm1 = flag to remove +# use_rm_out = list of available flags +do_use_rm() { + local parm1=$1 + local use_rm_out=${@:2} + # Strip matching USE flags. Yes, this is ugly, I know. + use_rm_out=`echo "${use_rm_out}" | tr ' ' '\n' | \ + grep -x -v -e "${parm1}" | tr '\n' ' '` + # Also strip the inverse. Even uglier... + if [ "${parm1:0:1}" = "-" ]; then + use_rm_out=`echo "${use_rm_out}" | tr ' ' '\n' | \ + grep -x -v -e "${parm1:1}" | tr '\n' ' '` + else + use_rm_out=`echo "${use_rm_out}" | tr ' ' '\n' | \ + grep -x -v -e "-${parm1}" | tr '\n' ' '` + fi + echo "${use_rm_out}" +} + +# Adds a USE flag to make.conf +# parm1 = flag to add +# use_add_out = list of available flags +do_use_add() { + local parm1=$1 + local use_add_out=${@:2} + # First strip existing flags (matching or inverse), then add. + # This is not the best way to do this. Better would be to replace a + # flag if it already exists. That turned out to be a real PITA. + # Maybe in a later version... + use_add_out=`do_use_rm ${parm1} ${use_add_out}` + use_add_out="${use_add_out} ${parm1}" + echo "${use_add_out}" +} + +# Adds a flag to the locked flag cache +# Pass list of flags to lock as parameter. +do_lock_flags() { + local flag_list=$@ + # Merge the new list of flags flags that are already locked. + if [ -r ${lock_cache} ]; then + local lock_old=`cat ${lock_cache}` + fi + flag_list="${lock_old} ${flag_list}" + # Remove duplicates. + echo "${flag_list}" | tr ' ' '\n' | sort | uniq | tr '\n' ' ' +} + +# Writes the list of locked flags to the cache file +# Pass list of flags to write as parameter. +do_write_lock() { + local write_flags=$@ + if [ -r ${make_conf} ]; then + local make_prune=`do_get_make nodashes` + else + do_report_err ${make_conf} read + fi + # Be sure and remove any locked flags that no longer exist in USE. + for prune in ${write_flags}; do + local prune_test=`do_get_depr ${prune} ${make_prune}` + if [ "$prune_test" = "" ]; then + local new_cache="${prune} ${new_cache}" + fi + done + if [ -w ${use_cache_parent} ]; then + mkdir -p ${use_cache_dir} + chmod 700 ${use_cache_dir} + echo "${new_cache}" > ${lock_cache} + chmod 600 ${lock_cache} + else + do_report_err ${lock_cache} write + fi +} + +# Writes new USE variable to make.conf +# Pass new list of USE flags as parameter. +do_write_make() { + local use_write="USE=\"$@\"" + local old_use="USE=\"`do_get_make dashes`\"" + if [ -w ${make_conf} ] && [ -w ${make_conf_dir} ]; then + local use_write="USE=\"$@\"" + local old_use=`grep "USE=\"" ${make_conf} | grep -v "#"` + local start_line=`grep -n "USE=\"" ${make_conf} | \ + grep -v "#" | cut -d ":" -f1` + if [ "${old_use:0-1}" != "\\" ]; then + sed -e "s/${old_use}/${use_write}/" ${make_conf} > \ + ${make_temp} + else + sed -e "s/${old_use}\\/${use_write}/" ${make_conf} > \ + ${make_temp} + fi + let start_line="${start_line} + 1" + if [ "${old_use:0-1}" != "\"" ]; then + del_line=`head -n ${start_line} ${make_temp} | \ + tail -n 1` + until [ "${del_line:0-1}" != "\\" ]; do + let del_length="${#del_line} - 1" + del_line="${del_line:0:${del_length}}" + grep -v -w "${del_line}" ${make_temp} > \ + ${make_temp}.2 + mv ${make_temp}.2 ${make_temp} + del_line=`head -n ${start_line} \ + ${make_temp} | tail -n 1` + done + let del_length="${#del_line} - 1" + del_line="${del_line:0:${del_length}}" + grep -v -x "${del_line}\"" ${make_temp} > \ + ${make_temp}.2 + mv ${make_temp}.2 ${make_temp} + fi + mv ${make_temp} ${make_conf} + else + do_report_err ${make_conf} write + fi +} + +# Reports a read/write error and exits +# parm1 = File to report on +# parm2 = read, write, etc +do_report_err() { + local parm1=$1 + local parm2=$2 + if [ "${parm2}" = "read" ]; then + echo "!!! Could not read ${parm1}" + echo -n "!!! Verify that file exists and that you have " + echo "appropriate permissions." + elif [ "${parm2}" = "write" ]; then + echo "!!! Could not write ${parm1}" + echo "!!! Got root?" + elif [ "${parm2}" = "nolock" ]; then + echo "!!! Could not read ${parm1}" + echo -n "!!! You have no locked flags or you have " + echo "insufficient permissions." + fi + exit 1 +} + + +# The main section of the script +# desc: +# This is the feature for getting USE descriptions. +if [ "$1" = "desc" ] || [ "$1" = "-i" ]; then + if [ -r ${use_desc} ]; then + for flag in ${@:2}; do + do_get_desc ${flag} + done + else + do_report_err ${use_desc} read + fi + +# show: +# This is the feature for showing the contents of the USE variable. +elif [ "$1" = "show" ] || [ "$1" = "-s" ]; then + if [ -r ${make_conf} ]; then + do_get_make dashes + else + do_report_err ${make_conf} read + fi + +# del: +# This is the feature for removing a USE flag. +elif [ "$1" = "del" ] || [ "$1" = "-d" ]; then + if [ -r ${make_conf} ]; then + make_use=`do_get_make dashes` + else + do_report_err ${make_conf} read + fi + for flag in ${@:2}; do + # Strip leading dashes. + if [ "${flag:0:1}" = "-" ]; then + flag="${flag:1}" + fi + del_test1=`do_get_depr ${flag} ${make_use}` + del_test2=`do_get_depr -${flag} ${make_use}` + if [ "${del_test1}" = "" ] || [ "${del_test2}" = "" ]; then + changes="1" + make_use=`do_use_rm ${flag} ${make_use}` + else + echo "!!! ${flag} is not in your USE variable." + fi + done + if [ "${changes}" != "0" ]; then + do_write_make ${make_use} + # Prune deleted USE flags from lock cache + lock_flags=`do_lock_flags $2` + do_write_lock ${lock_flags} + fi + +# add: +# This is the feature for explicitly enabling or disabling a USE flag. +elif [ "$1" = "add" ] || [ "$1" = "-a" ]; then + if [ -r ${make_conf} ]; then + make_use=`do_get_make dashes` + else + do_report_err ${make_conf} read + fi + for flag in ${@:2}; do + changes="1" + make_use=`do_use_add ${flag} ${make_use}` + done + if [ "${changes}" != "0" ]; then + do_write_make ${make_use} + fi + +# lock: +# This is the feature to lock a deprecated USE flag to prevent removal +elif [ "$1" = "lock" ] || [ "$1" = "-l" ]; then + if [ -r ${make_conf} ]; then + make_use=`do_get_make nodashes` + else + do_report_err ${make_conf} read + fi + for flag in ${@:2}; do + # Strip leading dashes. + if [ "${flag:0:1}" = "-" ]; then + flag="${flag:1}" + fi + lock_test=`do_get_depr ${flag} ${make_use}` + if [ "${lock_test}" = "" ]; then + lock_flags="${lock_flags} ${flag}" + else + echo "!!! ${flag} is not in your USE variable." + fi + done + lock_out=`do_lock_flags ${lock_flags}` + do_write_lock ${lock_out} + +# unlock: +# This is the feature to unlock a deprecated USE flag to allow removal +elif [ "$1" = "unlock" ] || [ "$1" = "-k" ]; then + if [ -r ${lock_cache} ]; then + lock_out=`cat ${lock_cache}` + else + do_report_err nolock + fi + for flag in ${@:2}; do + # Strip leading dashes. + if [ "${flag:0:1}" = "-" ]; then + flag="${flag:1}" + fi + lock_flag_check=`do_get_depr ${flag} ${lock_out}` + if [ "${lock_flag_check}" = "" ]; then + lock_out=`do_use_rm ${flag} ${lock_out}` + else + echo "!!! ${flag} is not a locked flag." + fi + done + do_write_lock ${lock_out} + +# showlock: +# This feature prints a list of USE flags that have been locked +elif [ "$1" = "showlock" ] || [ "$1" = "-w" ]; then + if [ -r ${lock_cache} ]; then + cat ${lock_cache} + else + do_report_err nolock + fi + +# update: +# This is the feature to update your USE by removing deprecated flags and +# handling new flags. +elif [ "$1" = "update" ] || [ "$1" = "-u" ]; then + if [ -r ${make_conf} ]; then + # Get our USE but strip leading dashes + make_use=`do_get_make nodashes` + else + do_report_err ${make_conf} read + fi + # Get available USE flags from use.desc + if [ -r ${use_desc} ]; then + use_avail=`do_get_avail` + else + do_report_err ${use_desc} read + fi + # First we check for deprecated flags. + echo "Your USE variable currently looks like this:" + echo + echo `do_get_make dashes` + echo + # Print the list of locked flags if any exist. + if [ -r ${lock_cache} ]; then + lock_test=`cat ${lock_cache} | tr -d ' '` + if [ "${lock_test}" != "" ]; then + echo "The following flags are locked:" + cat ${lock_cache} + echo + fi + fi + echo + echo "*** Checking for deprecated USE flags ..." + echo + for check_flag in ${make_use}; do + depr_ret=`do_get_depr ${check_flag} ${use_avail}` + flag_depr="${flag_depr}${depr_ret}" + done + # Filter out locked flags + if [ -r ${lock_cache} ] && [ "${lock_test}" != "" ]; then + lock_list=`cat ${lock_cache}` + for check_locks in ${flag_depr}; do + lock_ret=`do_get_depr ${check_locks} ${lock_list}` + lock_out="${lock_out}${lock_ret}" + done + flag_depr="${lock_out}" + fi + make_use=`do_get_make dashes` + if [ "${flag_depr}" = "" ]; then + echo "!!! No deprecated flags were found." + else + echo "The following USE flags appear to be deprecated:" + echo "${flag_depr}" + echo + echo "How would you like to handle them?" + echo "1) Handle them individually" + echo "2) Remove all deprecated flags" + echo "3) Don't remove any deprecated flags" + echo "4) Lock all deprecated flags" + echo + echo -n "Type (1, 2, 3, or 4): " + while [ "${luser_input}" = "" ]; do + read luser_input + case ${luser_input} in + "2") + changes="1" + for flag in ${flag_depr}; do + make_use=`do_use_rm \ + ${flag} ${make_use}` + done + echo + echo -n "*** All deprecated flags were " + echo "removed." + ;; + "3") + echo + echo "*** No flags were removed." + ;; + "1") + for flag in ${flag_depr}; do + echo -n "${flag} appears to be " + echo -n "deprecated. Remove it? " + echo -n "[Y]es/[N]o/[L]ock : " + luser_yn="" + while [ "${luser_yn}" = "" ]; do + read luser_yn + case ${luser_yn} in + "y" | "Y") + changes="1" + make_use=`do_use_rm \ + ${flag} \ + ${make_use}` + ;; + "n" | "N") + ;; + "l" | "L") + wlk="${flag} ${wlk}" + ;; + *) + luser_yn="" + ;; + esac + done + done + echo + echo -n "*** All deprecated flags " + echo "processed." + ;; + "4") + wlk="${flag_depr}" + echo + echo "*** All deprecated flags were locked." + ;; + *) + luser_input="" + ;; + esac + done + fi + if [ "${wlk}" != "" ]; then + do_write_lock ${wlk} + fi + # Now we check for new flags. + echo + echo + echo "*** Checking for new USE flags ..." + echo + # Load up our cached USE flags for comparison with use.desc + # Create the cache if it does not exist + if [ -w ${use_cache} ]; then + use_old=`cat ${use_cache}` + echo "${use_avail}" > ${use_cache} + chmod 600 ${use_cache} + elif [ -w ${use_cache_parent} ]; then + mkdir -p ${use_cache_dir} + chmod 700 ${use_cache_dir} + echo "${use_avail}" > ${use_cache} + chmod 600 ${use_cache} + use_old="" + else + do_report_err ${use_cache} write + fi + # Grab the contents of the USE variable. + make_cand=`do_get_make nodashes` + # Build a list of flags that do not exist in the USE variable. + for flag in ${use_avail}; do + new_cand="${new_cand}`do_get_depr ${flag} ${make_cand}`" + done + # Filter that list through the cached master list of flags. + for flag in ${new_cand}; do + new_flags="${new_flags}`do_get_depr ${flag} ${use_old}`" + done + if [ "${new_flags}" = "" ]; then + echo "!!! No new USE flags are available." + else + echo "The following new USE flags are available:" + echo "${new_flags}" + echo + echo "How would you like to handle them?" + echo "1) Handle them individually" + echo "2) Use Portage defaults (do not add to USE)" + echo "3) Explicitly enable all new flags" + echo "4) Explicitly disable all new flags" + echo + echo -n "Type (1, 2, 3, or 4): " + luser_input="" + while [ "${luser_input}" = "" ]; do + read luser_input + case ${luser_input} in + "1") + for h_flag in ${new_flags}; do + do_get_desc ${h_flag} + echo -n "How would you like to handle " + echo -n "${h_flag}? [e]nable, " + echo -n "[d]isable, [u]se default : " + luser_handle="" + while [ "${luser_handle}" = "" ]; do + read luser_handle + case ${luser_handle} in + "e" | "E") + changes="1" + make_use=`do_use_add \ + ${h_flag} \ + ${make_use}` + echo + ;; + "d" | "D") + changes="1" + make_use=`do_use_add \ + "-${h_flag}" \ + ${make_use}` + echo + ;; + "u" | "U") + echo + ;; + *) + luser_handle="" + ;; + esac + done + done + echo -n "*** All new flags have been " + echo "processed." + ;; + "2") + echo + echo -n "*** No new flags were added to " + echo "your USE." + ;; + "3") + changes="1" + for h_flag in ${new_flags}; do + make_use=`do_use_add ${h_flag} \ + ${make_use}` + done + echo + echo -n "*** All new flags were enabled in " + echo "your USE." + ;; + "4") + changes="1" + for h_flag in ${new_flags}; do + make_use=`do_use_add \ + "-${h_flag}" ${make_use}` + done + echo + echo -n "*** All new flags were disabled in " + echo "your USE." + ;; + *) + luser_input="" + ;; + esac + done + fi + # Write the changes if necessary. + if [ "${changes}" != "0" ]; then + do_write_make ${make_use} + # Prune any locked flags that do not exist in the USE variable + lock_prot=`do_lock_flags fakeflag` + do_write_lock ${lock_prot} + fi + echo + echo + echo "*** Script finished ..." + +# Display USAGE statement for unhandled parameters +else + echo "Usage:" + echo " ${run_name} action [flag] [...]" + echo + echo "Actions:" + echo "-s, show Displays the contents of the USE variable." + echo "-i, desc Displays a description of one or more USE flags." + echo -n "-a, add Adds the specified flag(s) to the USE " + echo "variable." + echo -n "-d, del Deletes the specified flag(s) from " + echo "the USE variable." + echo "-l, lock Locks the specified flag(s) to prevent deprecation." + echo -n "-k, unlock Unlocks the specified flags to allow " + echo "deprecation." + echo "-w, showlock Displays a list of locked flags." + echo -n "-u, update Interactively updates the USE variable to " + echo "reflect changes" + echo " to use.desc." + echo + exit 1 +fi +exit 0 + diff --git a/deprecated/useflag/useflag.1 b/deprecated/useflag/useflag.1 new file mode 100644 index 0000000..d321861 --- /dev/null +++ b/deprecated/useflag/useflag.1 @@ -0,0 +1,69 @@ +.TH useflag "1" "May 2002" "gentoolkit" +.SH NAME +useflag \- manage and update Gentoo Linux USE flags +.SH SYNOPSIS +.B useflag +\fIaction\fR [\fIflag\fR] [\fI...\fR] +.SH DESCRIPTION +The \fBuseflag\fR utility allows the user to manage Gentoo Linux USE flags through a simple command-line interface. It allows quick and easy, single-command manipulation of the USE variable defined in \fI/etc/make.conf\fR. It also simplifies the process of handling changes to the master list of USE flags defined in \fI/usr/portage/profile/use.desc\fR. +.br + +It is important to note that a USE variable must exist in \fImake.conf\fR for this utility to work. Be sure that the USE variable is uncommented. It is OK for the USE variable to be empty. Please be sure to back up \fImake.conf\fR before using this utility for the first time. +.PP +.SH ACTIONS +.TP +\fBshow, -s\fR +Displays the raw contents of the USE variable as defined in \fImake.conf\fR. The output contains only the flags themselves. +.TP +\fBdesc, -i [flag] ...\fR +Displays a description of one or more USE flags specified on the command line. The flags should be seperated by spaces and should not contain leading dashes. Specifying a flag that does not exist returns a non-fatal error. +.TP +\fBadd, -a [[\-]flag] ...\fR +Adds one or more specified flags to the USE variable defined in \fImake.conf\fR. The flags are appended to the USE variable exactly as they appear on the command line. If a specified flag already exists in the USE variable, it is removed before the new set of flags is appended. The utility removes existing flags regardless of whether they are in an enabled or disabled state, allowing the user to enable or disable a flag with a single command. The user may add flags that are not defined in the \fIuse.desc\fR master list. +.TP +\fBdel, -d [flag] ...\fR +Deletes one or more specified flags from the USE variable defined in \fImake.conf\fR. The enabled/disabled state of a flag in the USE variable as well as any dashes prepended to flags on the command line is ignored. Attempting to delete a flag that is not in the USE variable returns a non-fatal error. When a flag is deleted from the USE variable using this utility, it is automatically unlocked. +.TP +\fBlock, -l [flag] ...\fR +Locks one or more specified flags that exist in the USE variable defined in \fImake.conf\fR. Locked flags are not considered to be deprecated by the update function of this utility. This allows the user to avoid being queried by the utility about deprecated, undocumented, or custom flags that the user wishes to preserve when performing an update. A flag must exist in the USE variable in order to be locked. The enabled/disabled state of a flag in the USE variable as well as any dashes prepended to flags on the command line is ignored. +.TP +\fBunlock, -k [flag] ...\fR +Unlocks one or more specified USE flags. This allows the update function to consider a flag deprecated if it no longer exists in the master list defined in \fIuse.desc\fR. Any dashes prepended to flags on the command line are ignored. Attempting to unlock flags that are not locked returns a non-fatal error. +.TP +\fBshowlock, -w\fR +Displays the raw list of locked flags, seperated by spaces. +.TP +\fBupdate, -u\fR +Interactively updates the USE variable defined in \fImake.conf\fR to reflect changes to the master list of USE flags defined in \fI use.desc\fR. +.br + +First, the user is presented with the current raw contents of the USE variable. The user is also shown the list of locked flags if any exist. +.br + +Next, the USE variable is searched for flags that do not appear in the master list. If any are found and they are not locked, then they are considered to be deprecated and are displayed to the user along with a list of options for handling them. The user may choose to remove all of the flags, remove none of the flags, lock all of the flags, or handle each flag individually. +.br + +Last, the master list is searched for any new flags that have become available since the last time the update function was run, and these are displayed to the user. If this is the first time, then all flags not currently defined in the USE variable will be displayed. The user will then be presented with a list of options for handling these flags. The user may choose to add all of the new flags to the USE variable as enabled, add all of the new flags as disabled, use Portage defaults for all of the flags, or handle each flag individually. +.SH FILES +.TP +\fI/etc/make.conf\fR +Contains the USE variable that Portage uses to control build-time functionality. +.TP +\fI/usr/portage/profile/use.desc\fR +Contains a master list of all documented USE flags along with their descriptions. +.TP +\fI/var/cache/use_desc/use.cache\fR +Contains a cached list of flags from \fIuse.desc\fR. This prevents the user from being repeatedly queried about flags that exist in \fIuse.desc\fR but not in the USE variable. DO NOT EDIT THIS FILE MANUALLY. +.TP +\fI/var/cache/use_desc/lock.cache\fR +Contains a list of USE flags that have been locked. DO NOT EDIT THIS FILE MANUALLY. +.SH AUTHOR +Michael Thompson , 2002 +.SH SEE ALSO +ebuild(1), ebuild(5), emerge(1), make.conf(5). +.TP +See \fI/usr/share/doc/gentoolkit-/\fR for documentation on other gentoolkit utilities. +.SH TIPS +.TP +Deleting \fI/var/cache/use_desc/use.cache\fR will allow the utility to query about all flags not currently defined in the USE variable. + diff --git a/gentoolkit-dev/AUTHORS b/gentoolkit-dev/AUTHORS new file mode 100644 index 0000000..fdfccf3 --- /dev/null +++ b/gentoolkit-dev/AUTHORS @@ -0,0 +1,6 @@ +Karl Trygve Kalleberg + * Maintenance + +See the AUTHOR file in the various src/ subdirectories for a full +log of who's done what with whome and when. + diff --git a/gentoolkit-dev/COPYING b/gentoolkit-dev/COPYING new file mode 100644 index 0000000..60549be --- /dev/null +++ b/gentoolkit-dev/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/gentoolkit-dev/ChangeLog b/gentoolkit-dev/ChangeLog new file mode 100644 index 0000000..58a2b45 --- /dev/null +++ b/gentoolkit-dev/ChangeLog @@ -0,0 +1,902 @@ +2009-12-11: Christian Ruppert + src/echangelog/test/test.sh, src/echangelog/Makefile: + Fix bug 292932, thanks to Alexis Ballier . + +2009-22-10: Christian Ruppert + src/imlate/imlate: Some cleanup. + Disable metadata warnings. + +2009-22-10: Christian Ruppert + src/imlate/imlate.1: Update man-page. + +2009-11-10: Christian Ruppert + * src/echangelog/echangelog: Fix bug 288589, thanks to Kent Fredric . + +2009-28-09: Christian Ruppert + * src/eshowkw/eshowkw: Make eshowkw a bit more POSIX compliant when using + /bin/sh, thanks to Daniel Pielmeier . + Ignore comments when parsing arch.list, thanks to Fabian Groffen . + +2009-12-09: Christian Ruppert + * src/echangelog/echangelog: Fix bug 284657, thanks to Andrew Gaffney . + Cleanup VCS detection. + Cleanup. + Make --strict default, add --no-strict option. + +2009-09-09: Christian Ruppert + * src/imlate/imlate: Bump to 0.0.4. + Add SLOT support. + Add option to specify the minimum mtime for the mtime check. + Add search by herd or maintainer. + Add single package mode. + Automatic detection of TARGET/MAIN-_ARCH. + Remove EXPERIMENTAL option, make it default. + +2009-09-06: Christian Ruppert + * src/echangelog/echangelog: Fix regex, thanks to Magnus Granberg (zorry) . + +2009-07-20: Christian Ruppert + * README.Developer, README: Some clean-up. + * Makefile, Makefile.skel, makedefs.mak: Some minor improvements. Fix + docdir to use gentoolkit-dev instead of gentoolkit. Add all and clean + targets (skeletons) to makedefs.mak. Fix test target to be + parallel-build compatible. Add Makefile.skel as example for new tools. + * src/eshowkw/eshowkw.1, src/eshowkw/eshowkw, + src/eshowkw/Makefile: Add new tool eshowkw, thanks to Fabian Groffen + + * release.sh: Removed, I think it is not needed anymore. + +2009-07-19: Christian Ruppert + * src/ebump/ebump: Use svn cp instead of cp if vcs == svn, thanks to Justin + Lecher (jlec) . + * src/ekeyword/Makefile src/eviewcvs/Makefile: Add a clean target to remove + generated manpages. + +2009-06-03: Christian Ruppert + Cleanup, update ChangeLog, README, TODO. + * src/echangelog/echangelog: Add support for bzr. Cleanup. Removed git related if statement in check + for unknown/untracked files since it was useless. + +2009-05-26: Christian Ruppert + * src/ebump/ebump: Fixed bug 271322, thanks to Justin Lecher (jlec) + . + +2009-05-15: Christian Ruppert + * src/ekeyword/ekeyword: Fix keywording if the KEYWORDS line starts with + whitespace, thanks to Markus Meier . + +2009-05-12: Christian Ruppert + * src/echangelog/echangelog: Fix regex, bug 269557, thanks to Samuli + Suominen . + +2009-05-09: Christian Ruppert + * src/echangelog/echangelog: Ignore .git dir when running echangelog in + the repository root, fixes bug 199805 c8,c13. Improved + git_unknown_objects(), git status parsing improved. Thanks to Andrew + Gaffney for testing etc. + * src/echangelog/echangelog: Update category/package when creating the + initial ChangeLog, thanks to Serkan Kaba . Cleanup. + +2009-05-07: Christian Ruppert + * echangelog: Re-add files (git) if the copyright has been updated, thanks + to Justin Lecher (jlec) . + +2009-05-06: Christian Ruppert + * ekeyword: Improved die message, bug 257853. + * echangelog: Fixed git detection. Add support for project-wide variables + as suggested in bug 213374. Improved environment handling. Respect $PATH + while looking for git. Fixed stty call. Fix 'Use of uninitialized value in + concatenation' when calling echangelog on untouched ebuild directories + (Add an action for ChangeLog). Removed duplicate sort call. Don't eat + newlines, bug 264146, added new function text_fill (modified + Text::Wrap::fill). Add some useful information when using $EDITOR. + * ebump: Add support for git/svn, bug 256398. Use echangelog instead of + creating own ChangeLog entries. ebump calls ekeyword from now on (default). + Old option opt_add_cvs (now opt_add_vcs) and variables + AUTHORNAME/AUTHOREMAIL are deprecated, see bug 213374 and/or echangelog(1). + +2009-04-30: Paul Varner + * revdep-rebuild: Add patch from loki_val to check -l dependencies in + .la files (Bug #267898) + +2009-04-24: Paul Varner + * ekeyword: Fix to handle multiline KEYWORDS (Bug #267250) + +2009-01-08: Paul Varner + * equery: Fix package.py to account for PORTDIR being a symbolic link + when checking if a package is in an overlay. (Bug #253968) + +2008-11-25: Paul Varner + * revdep-rebuild: Fixes for non-linux Gentoo systems. Add patch from + igli to fix find command to comply with POSIX. Change awk calls to + gawk. + +2008-11-11: Paul Varner + * echangelog: Add --strict option (Bug 246242). + * echangelog: Fix processing of virtual category (Bug 179530) + +2008-09-17: Paul Varner + * euse: Fix check_sanity function to use get_all_make_defaults + function when checking for the make.defaults files in the profile. + (Bug #233651) + +2008-09-03: Paul Varner + * equery: Fix depgraph function to print out dependencies that don't + resolve to a package (Bug #236492) + +2008-08-26: Paul Varner + * glsa-check: Fix has_key() deprecation message. (Bug #232797) + * revdep-rebuild: Update fix for Bug 232270 to utilize better patch + from Ian Abbott. + +2008-08-22: Paul Varner + * gentoolkit: Fix find_packages and find_installed_packages to print + a warning instead of a traceback when an InvalidAtom exception occurs. + (Bug #234358) + * equery: Fix equery belongs to strip multiple slashes from path + names. (Bug #234584) + +2008-07-24: Paul Varner + * equery: Fix equery check to convert mtime to an integer so that + comparisions always work. Thanks to Alexey Parshin for discovering the + problem and providing a patch. (Bug 232803) + +2008-07-22: Paul Varner + * gentoolkit: Fix gentoolkit.split_package_name to work with + newer portage.catpkgsplit that now returns a tuple instead of a + list. (Bug 232599) + +2008-07-21: Paul Varner + * revdep-rebuild: Fix filtering of masked paths from SEARCH_DIRS + variable. (Bug 232270) + +2008-07-18: Paul Varner + * equery: Remove prefixed '+/-' signs from IUSE for equery uses + command. (Bug 232019) + +2008-07-09: Paul Varner + * revdep-rebuild: Fix revdep-rebuild to use TMPDIR instead of HOME for + temporary files. (Bug 203414) + * revdep-rebuild: Fix revdep-rebuild to not evaluate broken objects + multiple times. (Bug 220761) + +2008-07-09: Paul Varner + * gentoolkit: Fix gentoolkit to work without thread support in + python. (Bug 223255) + +2008-06-16: Marius Mauch + * euse: Add support for multi-parent profiles, account for missing + final newline in make.conf + +2008-03-19: Paul Varner + * glsa-check: Fix imports so mail functionality in glsa-check works + with python versions less than 2.5 (Bug 211706) + +2008-03-13: Paul Varner + * euse: Add --info-installed option from patch provided by Andreas + Waidler. (Bug 212573) + +2008-03-13: Paul Varner + * revdep-rebuild: Fix trying to emerge an empty list of packages. (Bug + 213294) + +2008-02-28: Paul Varner + * gentoolkit: Fix traceback when accessing the portage + db. (Bug #211716) + +2008-02-21: Paul Varner + * revdep-rebuild: "Use /etc/init.d/functions.sh instead of + /sbin/functions.sh. (Bug 210940) + +2008-02-18: Paul Varner + * revdep-rebuild: Apply patch to allow combined short options. + (Bug 188343) + * revdep-rebuild: Don't duplicate broken file output. (Bug 201319) + * revdep-rebuild: unset GREP_OPTIONS to prevent problems with grep. + (Bug 189257) + * revdep-rebuild: Apply patch to prevent false matches of object names. + (Bug 196460) + * revdep-rebuild: Apply patch to better handle masked and removed + packages. (Bug 205227) + * revdep-rebuild: Filter SEARCH_DIRS_MASK paths from SEARCH_DIRS. + (Bug 194993) + * revdep-rebuild: Apply patch for revdep-rebuild portable find function. + (Bug 194234) + * equery: Fix equery list to not generate an internal portage error when + fed input with too many slashes. (Bug 119806) + * equery: Assume the -p flag when equery list -I is used by itself. + (Bug 106278) + + +2007-10-09: Marius Mauch + * glsa-check: Change "affected" target so it's based on "new" instead of + "all" (IOW: exclude already applied/injected GLSAs). + +2007-10-05: Marius Mauch + * glsa-check: Use UTF-8 strings to avoid EncodeErrors if a GLSA contains + non-ascii characters (bug #162493) + +2007-09-19: Paul Varner + * epkginfo: Fix handling of KEYWORDS="" in an ebuild. (Bug #193108) + * revdep-rebuild: Fix handling of /var/db/pkg when it is a symbolic + link. (Bug #179392) + +2007-09-18: Paul Varner + * equery: Apply patch from Carlo Marcelo Arenas Belon to fix incorrect + display of masking status in list command. (Bug #188678) + * revdep-rebuild: Correctly handle LD_LIBRARY_MASK when checking for + "no version information" errors/ (Bug #182882) + +2007-09-12: Paul Varner + * eclean: Fix processing of the long arguments to work correctly. (Bug + #192345) + * revdep-rebuild: Correctly handle the case where an ebuild no longer + exists for a package (Bug #188918) + * eread: Fix eread to not accept invalid input for file selection. + (Bug #189994) + +2007-08-08: Paul Varner + * revdep-rebuild: Fix progress bar to only update when there is a + change (Bug #186945) + * revdep-rebuild: Ensure that we source functions.sh before calling + ewarn, etc. + +2007-08-06: Paul Varner + * revdep-rebuild: Fix processing of .la files (Bug #187453) + * revdep-rebuild: Add -X option back for backwards compatibilty (Bug + #187366) + +2007-07-30: Paul Varner + * revdep-rebuild: Fix grepping for non-existant package-owners file + (Bug #187141) + +2007-07-05: Paul Varner + * revdep-rebuild: Added refactored revdep-rebuild from Michael A. + Smith (Bug #184042) + +2007-05-30: Marius Mauch + * glsa-check: check SLOT when selecting and displaying upgrades + * glsa-check: new --emergelike option to use the best version + within the same SLOT instead of the one with the smallest delta. + * glsa-check: prefer visible upgrades to masked upgrades + * equery: check for and warn about unknown options (bug 119674) + * equery,eclean,glsa-check,epkginfo: Only add /usr/lib/portage/pym + to python search path when necessary + +2007-05-21: Paul Varner + * echangelog: Add patch from genstef to fix issues from Bug 176337 + +2007-05-11: Paul Varner + * eclean: Changed permission check to see if you are either root or + belong to the portage group (Bug #177385) + +2007-05-11: Paul Varner + * eclean: Updated eclean to not delete metadata.dtd by default (Bug + #176951) + +2007-05-10: Marius Mauch + * euse: Fix incorrect flag status display when a flag appears multiple + times in a single location + +2007-04-25: Paul Varner + * echangelog: Re-added subversion/git support with fixes from genstef. + (Bug #136048) + +2007-04-24: Paul Varner + * etcat: Removed from Makefile (deprecated since 04-25-2005) + * qpkg: Removed from Makefile (deprecated since 04-25-2005) + +2007-04-23: Paul Varner + * genpkgindex, epkginfo: Move to /usr/bin from + /usr/lib/gentoolkit/bin (Bug #175759) + +2007-04-10: Paul Varner + * equery: Change equery uses to command to display the best matching + uninstalled package version if an uninstalled package is specified. + Changed the meaning of -a to mean display all versions. (Bug #152325) + +2007-04-01: Alec Warner + * eread: Fix path and fully qualified paths (Bug #172969) + +2007-03-31: Paul Varner + * equery: Fix traceback in equery which (Bug #134053) + +2007-03-29: Paul Varner + * gentoolkit: Change package.get_???_deps() methods to try the portage + tree first, since emerge always uses the portage tree for dependencies. + (Bug #164678) + +2007-03-29: Paul Varner + * equery: Convert deprecated strings functions to str methods (Bug + #172694) + +2007-03-25: Paul Varner + * echangelog: Remove subversion/git patch due to many bugs. + +2007-03-18 Paul Varner + * revdep-rebuild: Change --no-color to --nocolor for consistency + within gentoolkit. (Bug #165165) + +2007-03-16 Paul Varner + * gentoolkit: Fix typo in package.py (Bug #168347) + +2007-03-15 Paul Varner + * equery: Fix equery check to not fail for symlinks prefixed with ./ + (Bug #170702) + +2007-03-14 Paul Varner + * equery: Trim trailing slash from query for equery belongs command + (Bug #170981) + +2007-03-13 Paul Varner + * revdep-rebuild: Fix bug with --package-names option not rebuilding + packages (Bug #169761) + +2007-03-10 Paul Varner + * equery: Add --depth option to equery depgraph to limit the depth of + the dependency graph. (Bug #115807) + +2007-03-09 Paul Varner + * revdep-rebuild: Add support to detect "no version information + available" message from ldd (Bug #169973) + +2007-03-08 Paul Varner + * equery: Improved handling of KeyError in equery depends command + (Bug #169929) + +2007-03-07 Paul Varner + * revdep-rebuild: Change ordering algorithm to use --deep instead of + --emptytree on the advice of zmedico + +2007-02-26 Marius Mauch + * glsa-check: Display access information in verbose list mode (bug 168482) + +2007-02-19 Paul Varner + * echangelog: Updated to support git and subversion (Bug #136048) + +2007-01-10 Paul Varner + * epkgmove: removed epkgmove command due to popular demand. (Bug + 161360) + * gensync: Deprecated gensync in favor of app-portage/layman (multiple + bugs) + +2007-01-02 Paul Varner + * equery: Fix equery depends --indirect command. (Bug #124552) + +2006-12-31 Paul Varner + * equery: Reworked equery depends command to be more accurate. + +2006-12-13 Paul Varner + * revdep-rebuild: Fix handling of /etc/portage/package.mask (Bug + #158025) Thanks to Wolfram Schlich for the patch. + +2006-12-12 Paul Varner + * equery: Add --tree option to equery files command. (Bug #62898) + Thanks to scope for the patch. + +2006-12-06 Paul Varner + * equery: Modify equery size command to work like the equery list + command for pkgspec arguments + +2006-11-27 Paul Varner + * eclean: Fix typographical error in help and man page. (Bug #156243) + +2006-10-11 Paul Varner + * equery: Fix fileAsStr to understand device files. + (http://forums.gentoo.org/viewtopic-p-3639575.html) + +2006-10-07 Paul Varner + * euse: Fix quoting bug in get_real_path() (Bug #150335). + +2006-09-21 Paul Varner + * eread: Add eread script for reading and managing portage ELOG files. + Thanks to Donnie Berkholz for writing this. + +2006-09-03 Paul Varner + * revdep-rebuild: Remove unused environment variables before calling + emerge (Bug #142074). Check for permissions to write temporary files + (Bug #142308) + +2006-08-12 Marius Mauch + * glsa-check: Add new --mail option to send out vulnerability reports + (output of --list plus --dump for each matched glsa as attachment), + using elog configuration. + +2006-07-31 Paul Varner + * euse: Replace calls to readlink with bash function for Gentoo/ALT + compatibility. (Bugs #140477, #128960) + +2006-07-28 Paul Varner + * revdep-rebuild: Fix revdep-rebuild to correctly handle --ask being + passed to emerge. Thanks to Sal Gonzalez for + the patch. (Bug #37485) + +2006-07-07 Paul Varner + * revdep-rebuild: Rename --no-path to --no-ld-path and change + functionality to not set LD_LIBRARY_PATH. This fixes bug #96946 as + well as bug #137313 + * revdep-rebuild: Apply patch from truedfx to fix bug #38751 + +2006-07-05 Paul Varner + * revdep-rebuild: Add --no-path option to revdep-rebuild for bug + #137313 + +2006-06-25 Marius Mauch + * glsa-check: update cve code for bug 128115 + +2006-06-14 Paul Varner + * gentoolkit: Fix package.py to honor $ROOT. (bug #136811) + +2006-05-22 Paul Varner + * revdep-rebuild: Use qfile to locate packages if portage-utils is + installed (Bug #128374). Be even more paranoid about extra slashes in + path names (Bug #128108). Remove unused code. Update configuration + section of manpage (Bug #126038). + +2006-04-02 Paul Varner + * revdep-rebuild: Remove double-slashes from path names (Bug #128108) + +2006-04-01 Paul Varner + * revdep-rebuild: Add fix so that packages no longer in the tree cause + errors (Bug #128174). Fix case where masked packages cause + revdep-rebuild to not rebuild any packages (Bug #128085) + +2006-03-29 Marius Mauch + * euse: Add support for special %active argument as placeholder for + active use flags + +2006-03-26 Aron Griffis + * echangelog: Don't warn about missing ebuilds when updating + copyrights #120061 + +2006-03-25 Aron Griffis + * eviewcvs: Update for sources.gentoo.org, add subversion support + +2006-03-21 Paul Varner + * revdep-rebuild: Fix to clear environment before portageq call. (Bug + #126038) + +2006-03-08 Paul Varner + * genpkgindex: Add binary package indexing utility. (Bug 82132) + +2006-03-01 Paul Varner + * gentoolkit: Fix depends parsing to properly handle conjunction. (bug + #123725). Thanks to tgl for the patch. + * gentoolkit: Added function to get post-merge dependencies (PDEPEND) + (bug #99191) + * gentoolkit: Change get_dependency functions to always use the + portage tree + * equery: Added post-merge dependencies to depends and depgraph + actions. (bug #99191) + * equery: Removed requirement for package to be installed to use + depgraph action. + +2006-02-16 Marius Mauch + * euse: add/remove use flags even if there is no USE= statement in make.conf + (bug #95432) + +2006-02-16 Marius Mauch + * glsa-check: Fix bug causing the wrong summary to be displayed + for --test --verbose (bug #123084) + +2006-02-06 Paul Varner + * revdep-rebuild: Reset PORTAGE_NICENESS, so that emerge is not niced + twice. Thanks to Lukas Reck for the patch. (Bug 121482) + +2006-01-24 Marius Mauch + * glsa-check: Use vbd information in verbose list mode (patch by solar) + +2006-01-18 Paul Varner + * revdep-rebuild: Add capability to check libtool .la files for + non-existant references. + +2006-01-06 Paul Varner + * revdep-rebuild: Fix revdep-rebuild to play nicely with portage-2.1 + (Bug 118124) + +2005-12-28 Paul Varner + * revdep-rebuild: Fix to automatically determine how to call find (Bug 111203) + +2005-12-19 Paul Varner + * eclean: Add regular expression matching for exclude files (Bug 114365) + +2005-12-13 Paul Varner + * equery: Fix USE flag parsing. (Bug 115294) + +2005-12-07 Paul Varner + * revdep-rebuild: Fix revdep-rebuild to work with findutils-4.2.27. + (bug 111203) + * equery: Added note to error message about quoting redirection + characters. (Bug 113423) + * gentoolkit: Removed python-config call from make file. (Bug 113386) + +2005-11-23 Paul Varner + * equery: Changed default behavior for equery list to search for + partial name matches. Added equery list examples to the equery man + page. (Bugs 113032, 113134) + +2005-11-15 Marius Mauch + * glsa-check: Changed several messages to stderr instead of stdout + * glsa-check: Added new --cve option as requested by solar (bug 98589) + * glsa-check: Added support for a EMERGE_OPTS env variable to modify the emerge call of glsa-check --fix + * glsa-check: Added a new target "affected" + * glsa-check: Removed the warning message as it is now pretty much tested + * glsa-check: Show GLSA title on --test if --verbose is also used + +2005-11-11 Paul Varner + * equery: Added sanity check to equery files (Bug 75983) + * equery: Fix string matching for equery depends (Bug 85653) + * gentoolkit: Fix package.size() to report correct size for symbolic + links (Bug 90384) + * equery: Fix equery depgraph to show all dependencies (Bug 99191) + * equery: Fix traceback with invalid regular expression for equery + list (Bug 109392) + +2005-11-04 Paul Varner + * equery: Fix equery belongs to correctly work when passed an argument + list of multiple files (Bug 111501) + +2005-11-02 Paul Varner + * revdep-rebuild: Fix to work with findutils-4.2.25 (Bug 111203) + +2005-10-18 Paul Varner + * equery: Make equery look at both DEPEND and RDEPEND for dependencies + * gentoolkit: Fix _parse_deps to understand || syntax (Bug 101377) + +2005-10-14 Paul Varner + * equery: Add qpkg --dups functionality to equery list command (bug + 109156) + +2005-10-13 Paul Varner + * equery: equery depgraph shows USE flags (Bug 74554) + * equery: equery should properly parse use.local.desc (Bug 74569) + * equery: equery list escapes regular expressions (Bug 77113) + * equery: equery uses displays flags correctly (Bug 86633) + * equery: equery -N option to disable pipe detection (Bug 90046) + * equery: equery list properly detects version string (Bug 91286) + * equery: equery belongs now requires a filename (Bug 94618) + * equery: equery files over a pipe only prints file names (Bug 100148) + * revdep-rebuild: Fix typo in man page (Bug 109147) + +2005-09-25 Paul Varner + * revdep-rebuild: Update to read configuration files from + /etc/revdep-rebuild + +2005-09-23 Paul Varner + * equery: Sort output from equery list (bug 67152) + * equery: Update man page (Bugs 73893, 74944) + * equery: equery which returns best-visible ebuild (bug 78687) + * equery: equery --quiet is actually quiet (bug 78921) + * equery: Fixed typo in equery -h (bug 82352) + * gentoolkit: gentoolkit now uses a single portage.config object (bug + 90680) + * equery: equery uses returns unique, sorted list (bug 91623) + * equery: equery always honors nocolor flag and settings (bug 98634) + +2005-09-08 Paul Varner + * eclean: Inital commit of eclean 0.4.1 from Thomas de Grenier de + Latour (tgl) (bug 33877) + +2005-06-28 Paul Varner + * revdep-rebuild: Revert fix for bug 93574 as it can cause packages to + be missed. (bug 97171) + +2005-06-07 Paul Varner + * revdep-rebuild: Delete temporary files if the environment does not + match the previous environment (bug 95274) + +2005-06-05 Paul Varner + * revdep-rebuild: Imported revdep-rebuild release from bug 62644 + * revdep-rebuild: Major changes to the functionality when using + --package-names/-X The script should now update slotted packages + correctly. (bug 22161) + * revdep-rebuild: Customizable searching controlled through environment + variables. This removes the need for end users to directly modify the + script. (bugs 32276, 38011, 59803) + * revdep-rebuild: The directories to search are no longer hard coded + into the script. revdep-rebuild now determines the directories to + search based upon /etc/profile.env and /etc/ld.so.conf. (bugs 32276, + 38011, 89781) + * revdep-rebuild: --ignore option to ignore temporary files left from + previous runs. Automatically ignore temporary files older than 24 hours. + (bug 34052) + * revdep-rebuild: Always return an exit status based upon success or + failure. (bug 38472) + * revdep-rebuild: Fixed to only emerge packages with direct missing + dependencies. (bug 38487) + * revdep-rebuild: New man page. (bug 40042) + * revdep-rebuild: emerge is no longer called with --nodeps. This allows + for needed dependencies to be pulled in. (bug 62893) + * revdep-rebuild: Cleaned up grammatical errors (bug 85278) + * revdep-rebuild: Added support for revdep-rebuild --soname + /path/to/library.so (bug 91503) + * revdep-rebuild: Removed symbolically linked directories from search + (bug 93574) + * revdep-rebuild: --nocolor option to turn off colored output, the + script also obeys the NOCOLOR setting from /etc/make.conf. + * revdep-rebuild: Removed dependency on qpkg + * revdep-rebuild: Script uses PORTAGE_NICENESS from /etc/make.conf + * revdep-rebuild: Undocumented --keep-temp option. This is primarily + for debugging/testing. This option prevents temporary files from being + deleted. + * revdep-rebuild: Changed --soname --soname-regexp options to --library + and treat all arguments as basic regular expressions. --soname and + --soname-regexp can still be used as options for backwards + compatability. + * revdep-rebuild: Removed requirement to keep revdep-rebuild and emerge + options distinct. Options that are unrecognized by revdep-rebuild are + passed directly to emerge. + +2005-04-30 Marius Mauch + * glsa-check: add V to short option list so it actually works + * equery: added new option --name-only to belongs command to make it + "emerge-compatible" + +2005-04-26 Marius Mauch + * gentoolkit: fix broken Makefile + * gentoolkit: add some sticky tape to get the stupid thing working again + * equery: fix a few minor problems + +2005-04-25 Marius Mauch + * qpkg: moving to /usr/share/doc/gentoolkit-*/deprecated + * etcat: moving to /usr/share/doc/gentoolkit-*/deprecated + * revdep-rebuild: replacing qpkg call with equivalent grep/sed call + +2005-04-07 Marius Mauch + * euse: fixed bugs 74344, 75525 and 84521 + * euse: add better support for cascaded profiles + * glsa-check: use --oneshot (bug 79819) + * glsa.py: fix stupid revision comparison bug (bug 75233) + +2005-03-12 Aron Griffis + * Added eviewcvs to -dev, utility for generating viewcvs URLs + +2005-03-01 Karl Trygve Kalleberg + * Dropped epkgmove from the -dev + * Released gentoolkit-dev-0.2.3 + +2005-03-01 Karl Trygve Kalleberg + * Released gentookit-dev-0.2.2 + +2004-12-09 Marius Mauch + * glsa.py: Another stupid bug, this time revisionMatch() broke as + ~foobar-rN isn't valid anymore + +2004-12-08 Marius Mauch + * equery: implemented the --category option + * glsa-check: fixed the bug where it wanted to unnecessary merge masked + packages + * glsa-check: added a check to verify that all non-option arguments are + valid GLSAs + * glsa.py: changed the outfile parameter in Glsa.dump() to outstream so + we don't have to open/close a file which breaks pipes + * glsa.py: checks now for python versions below 2.3 and throws an + exception + +2004-11-29 Karl Trygve Kalleberg + * branched v0-3-0: major rework in equery is in progess. the main + branch is reserved for minor and incremental fixups. + +2004-10-20 Karl Trygve Kalleberg + * release.sh: New script that automates the relase of a new gentoolkit + relase. Only works for gentoolkit-dev at the moment. + * src/echangelog/Makefile: Fixed spurious '}' + * Released gentoolkit-dev-0.2.1 + +2004-10-31 Marius Mauch + * qpkg: security fix for bug #68846 + +2004-10-20 Karl Trygve Kalleberg + * etcat: fixed get_use_vars to get_use_flags, fixes #67349. + +2004-10-18 Karl Trygve Kalleberg + * gentoolkit: collapsed ChangeLog into base ChangeLog + * gentoolkit: reverted indenting back to tabs, due to loud protests + from Marius;) + * equery: collapsed ChangeLog into base ChangeLog + * equery: reverted indenting back to tabs, due to loud protests from + Marius;) + * equery: minor syntactical cleanups. + * equery: minor documentation improvements + * equery: added errors module that will hold various types of internal + errors raised. + * equery: added try block around on md5sum check, which fails on various + conditions like insufficient permission or stale temporary checksum + files. + +2004-10-17 Marius Mauch + * equery: fix for bug #67473 (checking md5sums of prelinked binaries) + * equery: fix for bug #67275 (--nocolor didn't work as configure was + called before parsing the arguments + * equery: changed defaults for `equery depends` as making a depgraph for + the full portage tree isn't a good idea and find_all_packages() uses way + to much memory currently + * euse: replaced the old perl version with a newly written bash version. + +2004-10-12 Marius Mauch + * equery: fix for bug #67210 + +2004-10-10 Marius Mauch + * Removed old-scripts directory from gentoolkit + * euse: added a errormessage that it doesn't support cascading profiles + * equery: small bugfixes + * equery: performance speedup for `equery belongs` by using portage + directly + * equery: added MD5 verification to `equery check` + * equery: renamed 'hasuses' to 'hasuse' + * equery: added filter patch for `equery files` from bug 43422, thanks + to degrenier@easyconnect.fr + * Released gentoolkit-0.2.0_pre10 + +2004-10-10 Karl Trygve Kalleberg + * equery: Added unit tests for all supported commands + * equery: Fixed printing order and recognition of overlay, #53432. + +2004-10-11 Karl Trygve Kalleberg + * gentoolkit: Split gentoolkit.py into helpers.py and package.py + +2004-10-10 Karl Trygve Kalleberg + * gentoolkit: Fixed Makefiles to work with posix-compatible shells + * gentoolkit: Fixed is_overlay() to report properly, #53432. + +2004-10-06 Marius Mauch + * glsa.py: Convert Unicode strings to ascii before passing them to + portage + * glsa.py: Some formatting fixes for dump() + * glsa.py: changed the matching routines so the reports are hopefully + more accurate + * glsa-check: added color support + * glsa-check: added a --verbose option to show the warnings about + invalid GLSAs + +2004-09-30 Karl Trygve Kalleberg + * equery: Added unit tests for --help + * equery: Added unit tests for 'files' + +2004-09-27 Karl Trygve Kalleberg + * gentoolkit: Added find_installed_packages + * equery: Added short commands + * equery: Fixed copyright dates + * equery: Fixed belongs to search only installed packages + * equery: Fixed reporting bug in uses command + * equery: Fixed reference to cppv + * equery: Added import of die + * equery: Added searching header to uses + * equery: Fixed hasuses to report properly + * Released gentoolkit-0.2.0_pre9 + * Released gentoolkit-dev-0.2.0_pre4 + +2004-09-08 Karl Trygve Kalleberg + * equery: Added man page rewrites by Katerina Barone-Adesi + , fixes #63045 + * equery: Fixed spacing issues with files, fixes #63036. + * equery: Added depends command by Olivier Crete , + fixes #40830. + * equery: Reworked output yet again. + * equery: Belongs handles multiple files on the command line, partially + fixes #62361. + * gentoolkit: Reworked printing functions + +2004-08-29 Karl Trygve Kalleberg + * gentoolkit: Added printing functions + * equery: Added check for bad regexp in belongs, fixes #58494 + * equery: Added proper error reporting to stderr, fixes #57580 + +2004-08-22 Karl Trygve Kalleberg + * gentoolkit: Fixed Package.get_env_var to use the correct tree db. + * gentoolkit: Renamed Package.get_use_vars to Package.get_use_flags + * equery: Searches now include masked packages, when installed. + * equery: Fixed output to be piping-friendly + * equery: Added -N option to force non-piping output + * equery: Added hasuses command + +2004-08-01 Marius Mauch + * Fixed grep expression for `qpkg -f` + +2004-05-04 Karl Trygve Kalleberg + * equery: Added a -f/--full-regex option to belongs and some logic so + users can do belongs ant, belongs /usr/bin/ant and belongs -f ".*ant.*" + while getting sensible results. Fixes #37637. + +2004-04-14 Karl Trygve Kalleberg + * Released gentoolkit-dev-0.2.0_pre3 + +2004-03-31 Marius Mauch + * glsa-check: updates, fixing #45528 and #45522, adding support for rXX + operators and passing filenames as arguments to Glsa() + +2004-03-13 Marius Mauch + * Added glsa-check and glsa.py, please note: + - they are only temporary for testing, so no manpage/ChangeLog + - their CVS home is in gentoo-projects + * fixed bugs #42160, #40935, #43389 + * equery: fixing descriptions for local USE flags + * equery: more checking on exceptions + +2004-02-08 Karl Trygve Kalleberg + * Added ebump + * Added gensync + * Added epkgmove, closes #36663. + +2004-02-06 Marius Mauch + * fixed bugs #40159, #39798, #39652, #39596, #39293 + * changed etcat and equery behavior for ambigous package names, + they now return values for all matching packages rather + than erroring out + * added "will be phased out" messages to etcat and qpkg + +2004-01-23 Marius Mauch + * lots of bugfixes + * equery: now catches Exceptions thrown by portage + * equery: minor bugfixes + +2004-01-14 Karl Trygve Kalleberg + * Added src/ego to gentoolkit-dev + +2004-01-12 Marius Mauch + * equery: added mask, keyword and slot information to list command + * equery: fixed traceback in equery + * equery: added more information on "equery list" + +2004-01-10 Karl Trygve Kalleberg + * Added src/ego + +2004-01-07 Karl Trygve Kalleberg + * equery: Added Makefile + * Added new build system + * Added src/old-scripts, the scripts from app-portage/gentoolkit + * Renamed gentool to equery + * Released 0.2.0_pre1 + +2003-12-31 Karl Trygve Kalleberg + * equery: Added which command + * equery: Added check command (not finished) + +2003-12-12 Karl Trygve Kalleberg + * equery: Added size command + * equery: Added depgraph command + +2003-12-11 Karl Trygve Kalleberg + * equery: Added list command + * equery: Added uses command + +2003-12-08 Karl Trygve Kalleberg + * Removed emerge-rsync, emerge-webrsync + * Added moo + * Added skeleton man pages to all packages + * Added Makefile + +2003-10-05 Karl Trygve Kalleberg + * equery: Added files command + * equery: Added belongs command + +2003-10-04 Karl Trygve Kalleberg + * Rewrote dep-clean to python + +2003-06-31 Karl Trygve Kalleberg + * Rewrote more of etcat; many of the functions now employ + gentoolkit. + * Replaced qpkg with stubs of a reimplementation in python. + +2003-06-27 Karl Trygve Kalleberg + * Added patch to echangelog to consider PORTDIR, fixes #23881. + +2003-06-26 Karl Trygve Kalleberg + * Added echangelog, by agenkin + * Added ekeyword, by agenkin + * Added gentoolkit, the common python library for all Gentoolkit tools. + * Revived pkg-size as a testbed for the gentoolkit library + * Fixed some minor issues in qpkg + * Added revdep-rebuild-1 + * Added revdep-rebuild-2 + * Restructuring etcat + * Fixed some minor issues in dep-clean + +2002-11-21 Karl Trygve Kalleberg + * Renamed pkg-size to gentool-package-size + * Renamed pst-package-count to gentool-package-count + * Retired rest of pst-* stuff + +2002-08-06 Karl Trygve Kalleberg + * Created separate CVS module for Gentoolkit + * Restructured directory hierarchy diff --git a/gentoolkit-dev/Makefile b/gentoolkit-dev/Makefile new file mode 100644 index 0000000..fdd48a7 --- /dev/null +++ b/gentoolkit-dev/Makefile @@ -0,0 +1,54 @@ +# Copyright 1999-2009 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +include makedefs.mak + +TOOLS=ebump echangelog ego ekeyword eshowkw eviewcvs imlate +RELEASE="gentoolkit-dev-$(VERSION)$(RELEASE_TAG)" + +all: + @echo "YARMOUTH (vb.) To shout at foreigners in the belief that the louder you speak, the better they'll understand you." + @echo "PYVERSION=$(PYVERSION)" + @echo "VERSION=$(VERSION)" + @echo "docdir=$(docdir)" + @echo "bindir=$(bindir)" + @echo "sbindir=$(sbindir)" + @echo "mandir=$(mandir)" + +# use $(TOOLS) if we have more than one test +test: + $(MAKE) -C src/echangelog test + +clean: + rm -rf release/ + @for tool in $(TOOLS); do \ + ( $(MAKE) -C src/$${tool} clean ) \ + done + +dist: + mkdir -p release/gentoolkit-dev-$(VERSION)$(RELEASE_TAG) + @for tool in $(TOOLS); do \ + ( $(MAKE) -C src/$${tool} distdir=release/$(RELEASE) dist ) \ + done + + cp Makefile AUTHORS README README.Developer TODO COPYING NEWS ChangeLog release/$(RELEASE)/ + + @sed -e "s/^VERSION=.*/VERSION=$(VERSION)/" \ + -e "s/^RELEASE_TAG=.*/RELEASE_TAG=$(RELEASE_TAG)/" \ + makedefs.mak > release/$(RELEASE)/makedefs.mak + + ( cd release ; tar zcf $(RELEASE).tar.gz $(RELEASE)/ ) + +install: install-gentoolkit-dev + +install-gentoolkit-dev: + install -d $(docdir) + install -d $(bindir) + install -d $(mandir) + + install -m 0644 AUTHORS ChangeLog COPYING NEWS README README.Developer TODO $(docdir)/ + + @for tool in $(TOOLS); do \ + ( $(MAKE) -C src/$${tool} DESTDIR=$(DESTDIR) install ) \ + done diff --git a/gentoolkit-dev/Makefile.skel b/gentoolkit-dev/Makefile.skel new file mode 100644 index 0000000..aa03f75 --- /dev/null +++ b/gentoolkit-dev/Makefile.skel @@ -0,0 +1,18 @@ +# Copyright 1999-2009 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +include ../../makedefs.mak + +.PHONY: all + +all: + +dist: + mkdir -p ../../$(distdir)/src// + cp Makefile .1 ../../$(distdir)/src// + +install: all + install -m 0755 $(bindir)/ + install -m 0644 .1 $(mandir)/ + diff --git a/gentoolkit-dev/NEWS b/gentoolkit-dev/NEWS new file mode 100644 index 0000000..e69de29 diff --git a/gentoolkit-dev/README b/gentoolkit-dev/README new file mode 100644 index 0000000..992e86d --- /dev/null +++ b/gentoolkit-dev/README @@ -0,0 +1,37 @@ +Package: gentoolkit-dev +Authors: Aron Griffis + Brandon Low + Ian Leitch + Karl Trygve Kalleberg + Marius Mauch + Paul Varner + Christian Ruppert + See src//AUTHORS for tool-specific authors + +MOTIVATION + +The gentoolkit and gentoolkit-dev packages contain a collection of useful +administration scripts particular to the Gentoo Linux distribution. It contains +rough drafts and implementations of features that may in time make it into +Portage, or into full-fledged tools in their own right. + +The gentoolkit-dev package is intended primarily for Gentoo developers. + +CONTENTS + +gentoolkit-dev +============== +ebump - Ebuild revision bumper +echangelog - update portage ChangeLogs +ego - +ekeyword - modify package KEYWORDS +eshowkw - Display ebuild keywords in a graphical form +eviewcvs - generate viewcvs URLs +imlate - Displays candidates for keywords for an architecture based upon a target architecture + +IMPROVEMENTS + +Any suggestions for improvements should be sent to tools-portage@gentoo.org, or +added as a bug assigned to us. + +We only accept new contributions if they are written in bash or python. diff --git a/gentoolkit-dev/README.Developer b/gentoolkit-dev/README.Developer new file mode 100644 index 0000000..1fc76ae --- /dev/null +++ b/gentoolkit-dev/README.Developer @@ -0,0 +1,49 @@ + +OVERVIEW + +The SVN module 'gentoolkit' contains all the scripts and stuff for both the +gentoolkit and the gentoolkit-dev package. The gentoolkit-dev package is +an optional add-on, that is only intented for the Gentoo developers. + +STYLE POLICY + +If you're touching any of the python scripts please don't change the indentation +style (if it's using tabs, you should use tabs too). Especially don't mix +spaces and tabs as that makes the code completely unreadable. +Tabs should be default for new scripts. + +Each script must provide a manpage. + +MAKING A RELEASE + +Releases should only be made by members of the tools-portage team. See +http://www.gentoo.org/proj/en/metastructure/herds/herds.xml?select=tools-portage +for who to contact on IRC, or shuffle over a bug report to us, or send +us a mail at tools-portage@gentoo.org if you need an immediate release. + +The release manager (big words;) will then do + +1) make VERSION=major.minor.patch RELEASE_TAG= dist +2) copy release/gentoolkit-dev-${VERSION}-${RELEASE_TAG}.tar.gz to + dev.gentoo.org:/space/distfiles-local/ +3) make a new ebuild, app-portage/gentoolkit-dev/gentoolkit-dev-${VERSION}.ebuild + with a SRC_URI that points to + mirror://gentoo/gentoolkit-dev-${VERSION}-${RELEASE_TAG}.tar.gz + (just use one of the previous ebuilds) + +Important! +1) _ALWAYS_ make sure you don't "overwrite" a previous release. Your + new VERSION must be newer than any previous released version. If you + mess up a release, don't overwrite with the same release number, iterate + the patch version and try again (and again, and again until you get + it right;) + + +Currently, the following people have "release access": + + - zmedico@gentoo.org + - fuzzyray@gentoo.org + - idl0r@gentoo.org + +If you want a new release, ping either one of us. If you want to get +"release access", talk to fuzzyray@gentoo.org diff --git a/gentoolkit-dev/TODO b/gentoolkit-dev/TODO new file mode 100644 index 0000000..117b6d3 --- /dev/null +++ b/gentoolkit-dev/TODO @@ -0,0 +1,8 @@ +- rewrite ekeyword and echangelog to use gentoolkit +- look through forums.gentoo.org for additional scripts +- write a Gentoolkit Guide +- revision bump tool + - bump versioned files in filesdir + + - imlate + Compare one arch with all to see possible candidates for several architectures diff --git a/gentoolkit-dev/makedefs.mak b/gentoolkit-dev/makedefs.mak new file mode 100644 index 0000000..2ec1e3e --- /dev/null +++ b/gentoolkit-dev/makedefs.mak @@ -0,0 +1,21 @@ +# Copyright 1999-2009 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +# Override this on command line when making a release, ie 'dist' +VERSION=9.9.9 +RELEASE_TAG= + +# python-config is not installed on all arches Bug #113386 +PYVERSION="`LC_COLLATE=C; python -V 2>&1 | tr '[:upper:]' '[:lower:]' | sed -e 's/ //g;s/\([0-9]\.[0-9]\)\.[0-9]/\1/'`" +DESTDIR= + +docdir=$(DESTDIR)/usr/share/doc/gentoolkit-dev-$(VERSION)$(RELEASE_TAG) +bindir=$(DESTDIR)/usr/bin +sbindir=$(DESTDIR)/usr/sbin +mandir=$(DESTDIR)/usr/share/man/man1 +sysconfdir=$(DESTDIR)/etc + +# skeletons +all: +clean: diff --git a/gentoolkit-dev/src/ebump/AUTHORS b/gentoolkit-dev/src/ebump/AUTHORS new file mode 100644 index 0000000..2432e06 --- /dev/null +++ b/gentoolkit-dev/src/ebump/AUTHORS @@ -0,0 +1,5 @@ +Maintainer: +Karl Trygve Kalleberg + +Original author: +Karl Trygve Kalleberg diff --git a/gentoolkit-dev/src/ebump/ChangeLog b/gentoolkit-dev/src/ebump/ChangeLog new file mode 100644 index 0000000..4434b94 --- /dev/null +++ b/gentoolkit-dev/src/ebump/ChangeLog @@ -0,0 +1,8 @@ +2004-06-21 Karl Trygve Kalleberg + * Fixed handling of deletion. + +2004-03-11 Karl Trygve Kalleberg + * Fixed incorrect cut'ing of wc -l output when updating ChangeLog + +2004-02-08 Karl Trygve Kalleberg + * Initial import diff --git a/gentoolkit-dev/src/ebump/Makefile b/gentoolkit-dev/src/ebump/Makefile new file mode 100644 index 0000000..aa1d347 --- /dev/null +++ b/gentoolkit-dev/src/ebump/Makefile @@ -0,0 +1,20 @@ +# Copyright 2004 Karl Trygve Kalleberg +# Copyright 2004 Gentoo Technologies, Inc. +# Distributed under the terms of the GNU General Public License v2 +# +# $Header$ + +include ../../makedefs.mak + +.PHONY: all +all: + +dist: + mkdir -p ../../$(distdir)/src/ebump/ + cp Makefile AUTHORS README TODO ChangeLog ebump ebump.1 ../../$(distdir)/src/ebump/ + +install: all + install -m 0755 ebump $(bindir)/ + install -d $(docdir)/ebump + install -m 0644 AUTHORS README TODO ChangeLog $(docdir)/ebump/ + install -m 0644 ebump.1 $(mandir)/ diff --git a/gentoolkit-dev/src/ebump/README b/gentoolkit-dev/src/ebump/README new file mode 100644 index 0000000..c81835c --- /dev/null +++ b/gentoolkit-dev/src/ebump/README @@ -0,0 +1,18 @@ + +Package : ebump +Version : 0.1.0 +Author : See AUTHORS + +MOTIVATION + +The ebump utility is a Gentoo-specific tool for bumping the revision of +a given ebuild and auxiliary files in the Portage tree. It is only +useful for Gentoo developers with CVS commit access. + +MECHANICS + +N/A + +IMPROVEMENTS + +N/A diff --git a/gentoolkit-dev/src/ebump/TODO b/gentoolkit-dev/src/ebump/TODO new file mode 100644 index 0000000..e69de29 diff --git a/gentoolkit-dev/src/ebump/ebump b/gentoolkit-dev/src/ebump/ebump new file mode 100755 index 0000000..b877318 --- /dev/null +++ b/gentoolkit-dev/src/ebump/ebump @@ -0,0 +1,390 @@ +#! /bin/sh +# +# Copyright (c) 2004 Karl Trygve Kalleberg +# Copyright (c) Gentoo Technologies, Inc. +# Licensed under the GNU General Public License, version 2 +# +# Maintainer: Karl Trygve Kalleberg + +__version__="0.1.0" +__author__="Karl Trygve Kalleberg" +__email__="" +__description__="Ebuild version bumping tool" + + + +die() { + echo $1 > /dev/stderr + exit -1 +} + +einfo() { + if [ ${opt_verbosity} -gt 1 ] ; then + echo $* + fi +} + +print_version() { + echo "${__description__}, v${__version__}" + echo "Copyright (c) 2004 ${__author__} ${__email__}" + echo "Copyright (c) 2004 Gentoo Technologies, Inc." + echo "Licensed under the GNU General Public License, version 2" +} + +print_usage() { + echo "Usage: ebump foo<.ebuild>" + echo "Ebuild version bumping tool, v${__version__}" + echo " -V|--version show version info" + echo " -v|--verbose increase verbosity" + echo " -q|--quiet turn off output" + echo " -C|--no-vcs do not add to VCS" + echo " -m|--message append message to ChangeLog" + echo " -d|--delete-old delete previous revision from VCS (DANGEROUS!)" +} + +# +# Load options from /etc/gentoolkit/ebump.conf and ${HOME}/.gentoo/ebump.conf +# Home directory file takes precedence. +# +load_options() { + + # FIXME: Sourcing config files like this is really a bad idea; users may + # easily override any function in this program inside his config files. + + if [ -f /etc/gentoolkit/ebump.conf ] ; then + . /etc/gentoolkit/ebump.conf + fi + if [ -f ${HOME}/.gentoo/gentool-env ] ; then + . ${HOME}/.gentoo/gentool-env + fi + if [ -f ${HOME}/.gentoo/ebump.conf ] ; then + . ${HOME}/.gentoo/ebump.conf + fi + + # FIXME: remove this warning in 2-3 releases. + if [[ -n ${opt_add_cvs} ]]; + then + echo "Warning: opt_add_cvs is deprecated, please use opt_add_vcs from now on!" >/dev/stderr + fi +} + +# +# Find closes ebuild to ${1}, if any +# +find_ebuild() { + f=${1} + + if [ -f ${1} ] ; then + echo ${1} + fi + + if [ -f ${1}.ebuild ] ; then + echo ${1} + fi +} + +# +# splitname (version|name|revision) package-name-version-revision +# +splitname() { + case $1 in + version) + echo ${2} | sed -r "s/.*-([0-9].*)/\1/" + ;; + name) + name=$(echo ${2} | sed -r "s/(.*)-[0-9].*/\1/") + if [ ${name} == ${2} ] ; then + if [ $(echo ${2} | grep "^[0-9].*") ] ; then + # The filename starts with a version number, thus it has no + # name + name="" + else + # The filename doesn't have a recognizeable version number; + # everything is a name + name=${2} + fi + fi + echo ${name} + ;; + revision) + rev=$(echo ${2} | sed -r "s/.*-r([0-9][0-9]*)/\1/") + if [ ${rev} == ${2} ] ; then + rev=0 + fi + echo ${rev} + ;; + vernorev) + ver=$(echo ${2} | sed -r "s/.*-([0-9].*)-r[0-9]+/\1/") + if [ ${ver} == ${2} ] ; then + ver=$(echo ${2} | sed -r "s/.*-([0-9].*)/\1/") + fi + echo ${ver} + ;; + *) + echo + esac +} + +process_ebuild() { + vcs=$1 + ebuild_arg=$2 + shift $# + + # Files to add to VCS + addfiles="" + # Files to remove from VCS + delfiles="" + + if [ -z ${ebuild_arg} ] ; then + print_usage + exit + fi + + # + # Try to find a matching ebuild + # + + ebuild_name=$(find_ebuild ${ebuild_arg}) + if [ -z ${ebuild_name} ] ; then + die "Could not find ${ebuild_arg}" + fi + einfo "Processing ebuild ${ebuild_name}" + + # + # Bump revision suffix (or add one) + # + + PF=$(basename ${ebuild_name} .ebuild) + PN=$(splitname name ${PF}) + PV=$(splitname version ${PF}) + rev=$(splitname revision ${PF}) + PV_norev=$(splitname vernorev ${PF}) + newPF=${PN}-${PV_norev}-r$[rev+1] + +# echo $PF / $PN / $PV / $rev / $PV_norev / $newPF + + einfo "Bumped ${PF}.ebuild to ${newPF}.ebuild" + + if [[ "${vcs}" == "svn" ]]; + then + svn cp ${PF}.ebuild ${newPF}.ebuild + else + cp ${PF}.ebuild ${newPF}.ebuild + fi + + einfo "Reset keywords to ~arch" + + ekeyword '~all' "${newPF}.ebuild" + + addfiles="${addfiles} ${newPF}.ebuild" + delfiles="${delfiles} ${PF}.ebuild" + + # + # (Optional) Bump relevant files in files/ + # + + if [ "${opt_bump_auxfiles}" == "y" ] ; then + + # Gather list of auxiliary files in files/ that has a versioned + # filename, where the version matches our current version. + + bumplist="" + for x in $(echo files/*) ; do + if [ ! -z $(echo $x | grep "${PV}$") ] ; then + bumplist="${bumplist} ${x}" + fi + done + + # Bump version of all matches + + for x in ${bumplist} ; do + + bn=$(basename ${x}) + dn=$(dirname ${x}) + + PN=$(splitname name ${bn}) + PV=$(splitname version ${bn}) + rev=$(splitname revision ${bn}) + PV_norev=$(splitname vernorev ${bn}) + +# echo $PN / ${PV_norev} / ${rev} + + # Special case for when we have no name part; filename + # is just a version number + if [ -z "${PN}" ] ; then + newbn=${PV_norev}-r$[rev+1] + else + newbn=${PN}-${PV_norev}-r$[rev+1] + fi + + if [ -d ${dn}/${bn} ] ; then + if [ -e ${dn}/${newbn} ] ; then + echo "Directory ${dn}/${newbn} exists, not copying" > /dev/stderr + else + cp -a ${dn}/${bn} ${dn}/${newbn} + # uhm, is that necessary? +# find ${dn}/${newbn} -name CVS | xargs rm -rf + fi + else + cp ${dn}/${bn} ${dn}/${newbn} + fi + + addfiles="${addfiles} ${dn}/${newbn}" + delfiles="${delfiles} ${dn}/${bn}" + + einfo "Bumped ${dn}/${bn} to ${dn}/${newbn}" + done + fi + +# echo "addfiles ${addfiles}" +# echo "delfiles ${delfiles}" + + filelist="${addfiles}" + + # + # (Optional) Add VCS entry for all new files + # + if [ "${opt_add_vcs}" == "y" ] ; then + for x in ${addfiles} ; do + if [ -d ${x} ] ; then + find ${x} -exec ${vcs} add {} ';' + else + ${vcs} add ${x} + fi + done + einfo "Added ${addfiles} to VCS" + fi + + + # + # (Optional) Delete previous entry + # + # Could we use 'rm' instead of remove for all vcs? + if [ "${opt_delete_old}" == "y" ] ; then + for x in ${delfiles} ; do + if [[ "${vcs}" == "cvs" ]]; + then + ${vcs} remove -f ${x} + elif [[ "${vcs}" == "git" ]]; + then + ${vcs} rm ${x} + else + ${vcs} remove ${x} + fi + done + einfo "Removed ${delfiles} from VCS" + fi + + # + # (Optional) Add ChangeLog entry + # + if [[ "${opt_add_changelog}" == "y" ]] && [[ "${opt_add_vcs}" == "y" ]]; + then + # FIXME: remove this warning in 2-3 releases + if [[ -n ${AUTHORNAME} ]] || [[ -n ${AUTHOREMAIL} ]]; + then + echo "Warning: AUTHORNAME and AUTHOREMAIL is deprecated!" >/dev/stderr + echo "Please take a look at echangelog(1)." >/dev/stderr + echo "To avoid this warning unset AUTHORNAME and AUTHOREMAIL." >/dev/stderr + fi + + echangelog "${opt_commitmessage}" || set $? + + if [[ ${1:-0} -ne 0 ]]; + then + einfo "Modifying ChangeLog failed!" + else + einfo "Added ChangeLog entry" + fi + fi +} + +function get_vcs() { + if [[ -d "CVS" ]]; + then + echo "cvs" + return 0 + elif [[ -d ".svn" ]]; + then + echo "svn" + return 0 + else + if [[ -x "$(which git)" ]]; + then + if [[ -n "$(git rev-parse --git-dir 2>/dev/null)" ]]; + then + echo "git" + return 0 + fi + fi + echo + return 1 + fi +} + +original_params=${#} + +# +# Global options +# +opt_verbosity=1 +opt_warn_on_delete=y +opt_add_changelog=y +opt_add_vcs=y +opt_bump_auxfiles=y +opt_delete_old=n +opt_commitmessage="" + +load_options + +skip=0 +while [ ${#} -gt 0 ] ; do + arg=${1} + shift + if [ ${skip} -gt 0 ] ; then + skip=$[skip-1] + else + case ${arg} in + -h|--help) + print_usage + exit 0 + ;; + -m|--message) + opt_commitmessage="${1}" + skip=1 + ;; + -C|--no-vcs) + opt_add_vcs=n + ;; + -V|--version) + print_version + exit + ;; + -v|--verbose) + opt_verbosity=$[opt_verbosity + 1] + ;; + -q|--quiet) + opt_verbosity=0 + ;; + -d|--delete-old) + opt_delete_old=y + ;; + *) + ebuild_arg=${arg} + ;; + esac + fi +done + +_vcs=$(get_vcs) +if [[ -z "${_vcs}" ]]; +then + echo "Warning: no cvs, git or svn repository found!" >/dev/stderr + echo "Changes can't be added to the VCS" >/dev/stderr + opt_add_vcs=n + opt_delete_old=n +fi +process_ebuild "${_vcs}" ${ebuild_arg} + +# TODO: +# - put cli parser into separate functions diff --git a/gentoolkit-dev/src/ebump/ebump.1 b/gentoolkit-dev/src/ebump/ebump.1 new file mode 100644 index 0000000..38cd795 --- /dev/null +++ b/gentoolkit-dev/src/ebump/ebump.1 @@ -0,0 +1,110 @@ +.TH "ebump" "1" "0.1.0" "Gentoolkit" "Gentoo Administration" +.SH "NAME" +.LP +ebump \- Gentoo: Ebuild revision bumper +.SH "SYNTAX" +.LP +ebump [\fIoption\fP] <\fIpackage-name[-version]\fP> + +.SH "DESCRIPTION" + +.LP +\fIebump\fR bumps the revision of a particular ebuild, and all auxiliary +files in the files/ directory that have a matching version suffix. + +.LP +By default, the all new revision files will be added to the VCS. + +.LP +You must stand in the directory of the ebuild to be bumped. + +.SH "OPTIONS" +.LP +\fB\-C\fR +.br +\fB--no-vcs\fB +.IP +Do not add new files to VCS. + +.LP +\fB\-V\fR +.br +\fB--version\fB +.IP +Display version information and exit. + +.LP +\fB\-v\fR +.br +\fB--verbose\fB +.IP +Increase verbosity level. May be used more than once. + +.LP +\fB\-q\fR +.br +\fB--quiet\fB +.IP +Do not output any non-essential information. + +.LP +\fB\-m\fR <\fIChangeLog text\fR> +.br +\fB\--message\fR <\fIChangeLog text\fR> +.IP +Specifies the message to add to the ChangeLog, instead of the standard +placeholder. + +.LP +\fB\-d\fR +.br +\fB\--delete-old\fR +.IP +Delete old revision and old auxiliary files from VCS. This is +\fIdangerous\fR and should only be used if you know exactly what you are +doing, because +.br +1) the old revision may be stable on a different architecture than the one you +are working on. +.br +2) the auxiliary files may be required by other versions of the ebuild. +.br +3) the new revision should usually undergo a period of testing before being marked stable. + +.SH "CONFIGURATION" + +.LP +\fB/etc/gentoolkit/ebump.conf\fR +.br +\fB~/.gentoo/ebump.conf\fR +.IP +From these files, \fIebump\fR will load the settings +.br +\fBopt_verbosity\fR (default \fI1\fR) - verbosity level 0-10 +.br +\fBopt_add_changelog\fR (default \fIy\fR) - add entry in ChangeLog +.br +\fBopt_add_vcs\fR (default \fIy\fR) - add new files to VCS +.br +\fBopt_bump_auxfiles\fR (default \fIy\fR) - bump auxiliary files in files/ +.br +\fBopt_delete_old\fR (default \fIn\fR) - delete old revision (DANGEROUS!) +.br +\fBopt_commitmessage\fR (default \fI""\fR) - default ChangeLog message + +.LP +\fB(DEPRECATED)\fR +.br +\fB~/.gentoo/gentool-env\fR +.IR +From this file, \fIebump\fR will load the env vars \fBAUTHORNAME\fR and +\fBAUTHOREMAIL\fR, which are used to generate proper ChangeLog entries. + +.SH "SEE ALSO" +.LP +The rest of the utilities in \fIapp-portage/gentoolkit-dev\fR, such as +\fIechangelog(1)\fR and \fIekeyword(1)\fR. + +.SH "AUTHORS" +.LP +Karl Trygve Kalleberg diff --git a/gentoolkit-dev/src/echangelog/AUTHORS b/gentoolkit-dev/src/echangelog/AUTHORS new file mode 100644 index 0000000..36d5bfd --- /dev/null +++ b/gentoolkit-dev/src/echangelog/AUTHORS @@ -0,0 +1 @@ +Aron Griffis diff --git a/gentoolkit-dev/src/echangelog/ChangeLog b/gentoolkit-dev/src/echangelog/ChangeLog new file mode 100644 index 0000000..c1c5885 --- /dev/null +++ b/gentoolkit-dev/src/echangelog/ChangeLog @@ -0,0 +1,84 @@ +26 Mar 2006 Aron Griffis + * echangelog: Don't warn about missing ebuilds when updating + copyrights #120061 + +27 Apr 2005 Aron Griffis + * more changes for #90326; report all trivial files if no significant + changes can be found + +26 Apr 2005 Aron Griffis + * detect conflicts explicitly + * report ChangeLog in the list of files if it's the only file that is + changing #90326 + +23 Mar 2005 Aron Griffis + * handle package moves without adding new version lines + +08 Mar 2005 Aron Griffis + * don't complain about cvs add of digests #84377 + * use gmtime instead of localtime + +07 Mar 2005 Aron Griffis + * report all changed versions #84332 + +25 Feb 2005 Aron Griffis + * strip GECOS #80011 + +09 Nov 2004 Aron Griffis + * change "cvs diff -fU 0" => "cvs -f diff U0" because -f is a + global option, not a diff option + +08 Nov 2004 Aron Griffis + * call cvs with -f to refrain from using .cvsrc, which might + contain conflicting options + * fix auto-addition of ChangeLog; last attempt was broken + +03 Nov 2004 Aron Griffis + * abort when there are unresolved files (files that aren't under + revision control) just like repoman + * auto-add to cvs when a new ChangeLog is created + +15 Sep 2004 Aron Griffis + * fix the wrapping to fit in 80 columns properly. It was + previously possible to get lines with 81 chars. Thanks to + ciaranm for reporting. + +29 Mar 2004 Aron Griffis + * fix bug 46111 by testing for / + * apply patch from plasmaroo, with minor modifications, to enable EDITOR + and +- support + +27 Mar 2004 Michael Sterrett + * don't fall out of the loop if update_copyright() didn't change + anything. Just go on to the next file. + +21 Mar 2004 Aron Griffis + * Fix typo $0 -> 0 + +19 Mar 2004 Aron Griffis + * Remove debugging output + * Fix $v bug introduced in last commit + +16 Mar 2004 Aron Griffis + * Make Feb 17 behavior work without Feb 20 bug :-) + * Release as version 0.2.0 + +20 Feb 2004 Aron Griffis + * Only update copyrights on modified ebuilds, otherwise if you run + echangelog again, it reports that all the ebuilds have been updated! + The copyright year issue would be better solved on Jan 1 of each year by + a separate script. + +17 Feb 2004 Aron Griffis + * Update copyrights on all ebuilds, not just the modified ones + +07 Jan 2004 Aron Griffis + * Updated Makefile to understand building man-page from pod + * Removed static man-page in favor of generated man-page from pod + * Added copyright year updating + * Allow echangelog to run even when no files have changed + +2004-01-07 Karl Trygve Kalleberg + * Added Makefile diff --git a/gentoolkit-dev/src/echangelog/Makefile b/gentoolkit-dev/src/echangelog/Makefile new file mode 100644 index 0000000..a3e5aac --- /dev/null +++ b/gentoolkit-dev/src/echangelog/Makefile @@ -0,0 +1,26 @@ +# Copyright 2004 Karl Trygve Kalleberg +# Copyright 2004 Gentoo Technologies, Inc. +# Distributed under the terms of the GNU General Public License v2 +# +# $Header$ + +include ../../makedefs.mak + +.PHONY: all test + +all: + +test: + cd test; bash test.sh + +dist: + mkdir -p ../../$(distdir)/src/echangelog/test/templates + cp Makefile AUTHORS README TODO ChangeLog echangelog echangelog.1 ../../$(distdir)/src/echangelog/ + cp test/TEST.pm test/test.sh ../../$(distdir)/src/echangelog/test/ + cp test/templates/test.patch test/templates/vcstest-0.0.1.ebuild ../../$(distdir)/src/echangelog/test/templates + +install: all + install -m 0755 echangelog $(bindir)/ + install -d $(docdir)/echangelog + install -m 0644 AUTHORS README $(docdir)/echangelog/ + install -m 0644 echangelog.1 $(mandir)/ diff --git a/gentoolkit-dev/src/echangelog/README b/gentoolkit-dev/src/echangelog/README new file mode 100644 index 0000000..77a7930 --- /dev/null +++ b/gentoolkit-dev/src/echangelog/README @@ -0,0 +1,11 @@ +Most of the documentation is contained in the man-page, which you can +read directly (using GNU man) by doing + + man ./echangelog.1 + +To rebuild the man-page from pod source, do + + pod2man --name=echangelog --center='Gentoolkit' \ + echangelog.pod echangelog.1 + +03 Nov 2004 agriffis diff --git a/gentoolkit-dev/src/echangelog/TODO b/gentoolkit-dev/src/echangelog/TODO new file mode 100644 index 0000000..e69de29 diff --git a/gentoolkit-dev/src/echangelog/echangelog b/gentoolkit-dev/src/echangelog/echangelog new file mode 100755 index 0000000..8767a19 --- /dev/null +++ b/gentoolkit-dev/src/echangelog/echangelog @@ -0,0 +1,794 @@ +#!/usr/bin/perl -w +# +# echangelog: Update the ChangeLog for an ebuild. For example: +# +# $ echangelog 'Add ~alpha to KEYWORDS' +# 4a5,7 +# > 10 Feb 2003; Aron Griffis oaf-0.6.8-r1.ebuild : +# > Add ~alpha to KEYWORDS +# > + +use strict; +use POSIX qw(strftime getcwd setlocale); +use File::Basename; +use Getopt::Long; + +# Fix bug 21022 by restricting to C locale +setlocale(&POSIX::LC_ALL, "C"); + +use Text::Wrap; +$Text::Wrap::columns = 77; +$Text::Wrap::unexpand = 0; + +# Global variables +my (@files, @ebuilds, @conflicts, @trivial, @unknown, @new_versions, %actions); +my ($input, $editor, $entry, $user, $date, $text, $vcs); +my ($opt_help, $opt_nostrict, $opt_version); + +$opt_help = 0; +$opt_nostrict = 0; +$opt_version = 0; +# DEPRECATED +my $opt_strict = 0; + +my %vcs = ( + bzr => { + diff => "bzr diff", + status => "bzr status -S .", + add => "bzr add", + skip => 3, + # The same as for hg. + regex => qr/^=== \S+ file '\S+\/\S+\/((\S+)\.ebuild)/ + }, + cvs => { + diff => "cvs -f diff -U0", + status => "cvs -fn up", + add => "cvs -f add", + skip => 6, + regex => qr/^Index: (([^\/]*?)\.ebuild)\s*$/ + }, + git => { + diff => "git diff", + status => "git diff-index HEAD --name-status", + add => "git add", + # This value should usually be 3 but on new file mode we need skip+1. + # So 4 should be fine anyway. + skip => 4, + regex => qr/^diff \-\-git \S*\/((\S*)\.ebuild)/ + }, + hg => { + diff => "hg diff", + status => "hg status .", + add => "hg add", + skip => 3, + # hg diff is relative to the root. + # TODO: Write a proper regex :) + regex => qr/diff \-r \S+ \S+\/\S+\/((\S+)\.ebuild)/ + }, + svn => { + diff => "svn diff -N", + status => "svn status", + add => "svn add", + skip => 4, + regex => qr/^Index: (([^\/]*?)\.ebuild)\s*$/ + }, +); + +sub usage { + (my $usage = <<" EOF") =~ s/^\t//gm; + Usage: echangelog [options] + + Options: + --help err, this screen ... + --no-strict do not abort on trivial/no changes + --version show version info + EOF + print $usage; + exit 0; +} + +sub version { + my $Revision = "Last svn change rev"; + my $Date = "Last svn change date"; + my $foo = ""; + print "echangelog\n$Revision$foo \n$Date$foo\n"; + exit 0; +} + +sub getenv($) { + my $key = shift; + + # Ensure our variable exist + if ( defined($ENV{$key}) ) { + # Ensure we don't get empty variables + if ( length($ENV{$key}) > 0 ) { + return $ENV{$key}; + } + } + return undef; +} + +# Bug 264146. +# Copied from Text::Wrap. +# The only modified thing is: +# We trim _just_ tab/space etc. but not \n/\r. +# \s treats even \n/\r as whitespace. +# BUGS: +# ' test' +# ' test' +# Will end up in: +# ' test' +# '' +# 'test' +# See 'my $ps = ($ip eq $xp) ? "\n\n" : "\n";' +sub text_fill { + my ($ip, $xp, @raw) = @_; + my @para; + my $pp; + + for $pp ( split(/\n\s+/, join("\n", @raw)) ) { + $pp =~ s/[\x09|\x0B|\x0C|\x20]+/ /g; + my $x = Text::Wrap::wrap($ip, $xp, $pp); + push(@para, $x); + } + + # if paragraph_indent is the same as line_indent, + # separate paragraphs with blank lines + my $ps = ($ip eq $xp) ? "\n\n" : "\n"; + return join ($ps, @para); +} + +sub changelog_info(%) { + my %changed = @_; + + open(INFO, '>', 'ChangeLog.new'); + + print(INFO "\n"); + print(INFO "# Please enter the ChangeLog message for your changes. Lines starting\n"); + print(INFO "# with '#' will be ignored, and an empty message aborts the ChangeLog.\n"); + print(INFO "#\n# Changes:\n"); + + foreach my $key (keys(%changed)) { + if ($changed{$key} eq "+") { + printf(INFO "# new file:\t%s\n", $key); + } + elsif ($changed{$key} eq "-") { + printf(INFO "# deleted:\t%s\n", $key); + } + else { + printf(INFO "# modified:\t%s\n", $key); + } + } + + close(INFO); +} + +sub update_cat_pn { + my $t = shift; + my $cwd = getcwd(); + + my $category = basename(dirname($cwd)); + my $package_name = basename($cwd); + + $t =~ s/^(# ChangeLog for).*/$1 $category\/$package_name/; + + return $t; +} + +# Just to ensure we don't get duplicate entries. +sub mypush(\@@) { + my $aref = shift; + + foreach my $value (@_) { + push(@{$aref}, $value) if !grep(/^\Q$value\E$/, @{$aref}); + } +} + +GetOptions( + 'help' => \$opt_help, + 'no-strict' => \$opt_nostrict, + 'version' => \$opt_version, + 'strict' => \$opt_strict, +); + +usage() if $opt_help; +version() if $opt_version; + +if($opt_strict) { + print STDERR "Warning: The option '--strict' has been deprecated and will be removed soon!\n"; + print STDERR "--strict behaviour is now default.\n"; +} + +# Figure out what kind of repo we are in. +# Respect $PATH while looking for the VCS +if (getenv("PATH")) { + foreach my $path ( split(":", getenv("PATH")) ) { + if ( -X "${path}/bzr" ) { + open(BZR, '-|', "${path}/bzr root 2>/dev/null"); + $vcs = "bzr" if defined(); + close(BZR); + last if $vcs; + } + if ( -X "${path}/cvs" ) { + $vcs = "cvs" if -d "CVS"; + last if $vcs; + } + if ( -X "${path}/git" ) { + open(GIT, '-|', "${path}/git rev-parse --git-dir 2>/dev/null"); + $vcs = "git" if defined(); + close(GIT); + last if $vcs; + } + if ( -X "${path}/hg" ) { + open(HG, '-|', "${path}/hg root 2>/dev/null"); + $vcs = "hg" if defined(); + close(HG); + last if $vcs; + } + if ( -X "${path}/svn" ) { + $vcs = "svn" if -d ".svn"; + last if $vcs; + } + } +} + +if ( ! $vcs ) { + print STDERR "Either no CVS, .git, .svn, ... directories found, the specific VCS has not been\n"; + print STDERR "installed or you don't have execute rights!\n"; + exit(1); +} + +# Read the current ChangeLog +if (-f 'ChangeLog') { + open(I, '<', 'ChangeLog') or die "Can't open ChangeLog for input: $!\n"; + { local $/ = undef; $text = ; } + close(I); +} else { + # No ChangeLog here, maybe we should make one... + if (<*.ebuild>) { + open(C, '-|', "portageq portdir") or die "portageq returned with an error: $!\n"; + my $portdir = ; + $portdir =~ s/\s+$//; + close(C); + + die "Can't find PORTDIR\n" if (length $portdir == 0); + + open(I, '<', "$portdir/skel.ChangeLog") + or die "Can't open $portdir/skel.ChangeLog for input: $!\n"; + { local $/ = undef; $text = ; } + close(I); + + $text =~ s/^\*.*//ms; # don't need the fake entry + + $text = update_cat_pn($text); + } else { + die "This should be run in a directory with ebuilds...\n"; + } +} + +# Figure out what has changed around here +open C, $vcs{$vcs}{status}.' 2>&1 |' or die "Can't run ".$vcs{$vcs}{status}.": $!\n"; +while () { + # I don't want mess our existing stuff with the horrible bazaar stuff. + # TODO: add stuff for untracked/conflicting files. + if ($vcs eq "bzr") { + # NEW, DELETED, MODIFIED + if (/^[\s\+\-]([NDM])\s+(.*)/) { + my ($status, $filename) = ($1, $2); + # strip category/package/ since everything is relative to the repo root. + $filename =~ s/^([^\/]+\/){2}//; + + # skip empty $filename, e.g. if you add a new package, the first + # line would be the package directory app-foo/bar/ but thats stripped above. + next if !$filename; + # skip directories + next if -d $filename; + + ($actions{$filename} = $status) =~ tr/NDM/+-/d; + push(@files, $filename); + next; + } + # RENAMED/MOVED + elsif (/^R\s+(\S+) => (\S+)/) { + my ($old, $new) = ($1, $2); + $old =~ s/^([^\/]+\/){2}//; + $new =~ s/^([^\/]+\/){2}//; + + next if !$old or !$new; + next if -d $old or -d $new; + + $actions{$old} = '-'; + $actions{$new} = '+'; + + push(@files, $old, $new); + next; + } + } + if (/^C\s+(\S+)/) { + # TODO: The git part here might be unused + if($vcs eq "git") { + my $filename = $1; + $filename =~ /\S*\/(\S*)/; + + next if -d $filename; + + push @conflicts, $filename; + next; + } + + push @conflicts, $1; + next; + } + elsif (/^\?\s+(\S+)/) { + push @unknown, $1; + $actions{$1} = '?'; + next; + } + elsif (/^([ARMD])\s+\+?\s*(\S+)/) { + my ($status, $filename) = ($1,$2); + + if($vcs eq "git") { + open(P, '-|', "git rev-parse --sq --show-prefix"); + my $prefix =

; + close(P); + + if (defined($prefix)) { + chomp($prefix); + + if ($filename =~ /\Q$prefix\E(\S*)/) { + $filename = $1 ; + } + else { + next; + } + } + } + + next if -d $filename; + + push(@files, $filename); + ($actions{$filename} = $status) =~ tr/DARM/-+-/d; + } +} + +sub git_unknown_objects { + open(GIT, "-|", "${vcs} ls-files --exclude-standard --others"); + while(defined( my $line = )) { + chomp($line); + + # IMHO we can skip those files, even if they're untracked + #next if $line =~ m/^\.gitignore$/; + + push(@unknown, $line); + } + close(GIT); +} + +# git only shows files already added so we need to check for unknown files +# separately here. +if($vcs eq "git") { + git_unknown_objects(); +} + +# Separate out the trivial files for now +@files = grep { + !/^(Manifest|ChangeLog)$/ or do { push @trivial, $_; 0; } +} @files; + +@unknown = grep { + !/^(Manifest|ChangeLog)$/ or do { push @trivial, $_; 0; } +} @unknown; + +# Don't allow any conflicts +if (@conflicts) { + print STDERR < $nb[$i]); + return $retval if $retval; + next; + } + + # char vs. char + if ($na[$i] =~ /^\D/ and $nb[$i] =~ /^\D/) { + $retval = ($na[$i] cmp $nb[$i]); + return $retval if $retval; + next; + } + + # num vs. char + $retval = ($na[$i] =~ /\d/ and -1 or +1); + return $retval; + } + + # + # compare suffix second + # + if (defined $sa and !defined $sb) { + return +2 if $sa eq "p"; + return -2; + } + if (defined $sb and !defined $sa) { + return -3 if $sb eq "p"; + return +3; + } + + if (defined $sa) { # and defined $sb + $retval = ($sa cmp $sb); + if ($retval) { + return +4 if $sa eq "p"; + return -4 if $sb eq "p"; + return $retval; # suffixes happen to be alphabetical order, mostly + } + + # compare suffix number + return +5 if defined $sna and !defined $snb; + return -5 if defined $snb and !defined $sna; + + if (defined $sna) { # and defined $snb + $retval = ($sna <=> $snb); + return $retval if $retval; + } + } + + # + # compare rev third + # + return +6 if defined $ra and !defined $rb; + return -6 if defined $rb and !defined $ra; + + if (defined $ra) { # and defined $rb + return ($ra <=> $rb); + } + + # + # nothing left to compare + # + return 0; +} + +# Forget ebuilds that only have changed copyrights, unless that's all +# the changed files we have +@ebuilds = grep /\.ebuild$/, @files; +@files = grep !/\.ebuild$/, @files; + +if (@ebuilds) { + if ($vcs eq "git") { + open C, $vcs{$vcs}{diff}." HEAD -- @ebuilds 2>&1 |" or die "Can't run: ".$vcs{$vcs}{diff}."$!\n"; + } else { + open C, $vcs{$vcs}{diff}." @ebuilds 2>&1 |" or die "Can't run: ".$vcs{$vcs}{diff}."$!\n"; + } + + $_ = ; + + while (defined $_) { + # only possible with cvs + if (/^$vcs diff: (([^\/]*?)\.ebuild) was removed/) { + mypush(@files, $1); + } + # We assume GNU diff output format here. + # git format: diff --git a/app-doc/repodoc/metadata.xml b/app-doc/repodoc/metadata.xml + elsif (/$vcs{$vcs}{regex}/) { + my ($file, $version) = ($1, $2); + + if ($vcs eq "git") { + while () { + last if /^deleted file mode|^index/; + if (/^new file mode/) { + mypush(@files, $file); + mypush(@new_versions, $version); + last; + } + } + } + + if ($vcs eq "bzr") { + if (/^=== added file/) { + mypush(@files, $file); + mypush(@new_versions, $version); + last; + } + elsif(/^=== renamed file '.+\/([^\/]+\.ebuild)' => '.+\/(([^\/]+)\.ebuild)'/) { + mypush(@files, $1, $2); + mypush(@new_versions, $3); + last; + } + } + + # check if more than just copyright date changed. + # skip some lines (vcs dependent) + foreach(1..$vcs{$vcs}{skip}) { + $_ = ; + } + + while () { + last if /^[A-Za-z]/; + if (/^[-+](?!# Copyright)/) { + mypush(@files, $file); + last; + } + } + + # at this point we've either added $f to @files or not, + # and we have the next line in $_ for processing + next; + } + elsif (/^$vcs.*?: (([^\/]*?)\.ebuild) is a new entry/) { + mypush(@files, $1); + mypush(@new_versions, $2); + } + + # other cvs output is ignored + $_ = ; + } +} +close C; + +# Subversion diff doesn't identify new versions. So use the status command +if (($vcs eq "svn") and (@ebuilds)) { + open C, $vcs{$vcs}{status}." @ebuilds 2>&1 |" or die "Can't run: ".$vcs{$vcs}{status}."$!\n"; + $_ = ; + + while (defined $_) { + if (/^A\s+\+?\s*(([^\s]*)\.ebuild)/) { + mypush(@files, $1); + mypush(@new_versions, $2); + } + + $_ = ; + } +} + +# When a package move occurs, the versions appear to be new even though they are +# not. Trim them from @new_versions in that case. +@new_versions = grep { $text !~ /^\*\Q$_\E\s/m } @new_versions; + +# Check if we have any files left, otherwise re-insert ebuild list +# (of course, both might be empty anyway) +@files = @ebuilds unless (@files); + +# Allow ChangeLog entries with no changed files, but give a fat warning +unless (@files) { + print STDERR "**\n"; + print STDERR "** NOTE: No non-trivial changed files found. Normally echangelog\n"; + print STDERR "** should be run after all affected files have been added and/or\n"; + print STDERR "** modified. Did you forget to $vcs add?\n"; + print STDERR "**\n"; + + if (!$opt_nostrict) { + print STDERR "** In strict mode, exiting\n"; + print STDERR "** If you know what you're doing there pass '--no-strict' to echangelog\n"; + exit(1); + } + + @files = sort sortfunc @trivial; + + # last resort to put something in the list + unless (@files) { + @files = qw/ChangeLog/; + $actions{'ChangeLog'} = ""; + } +} + +# sort +@files = sort sortfunc @files; +@new_versions = sort sortfunc @new_versions; + +# Get the input from the cmdline, editor or stdin +if ($ARGV[0]) { + $input = "@ARGV"; +} else { + $editor = getenv('ECHANGELOG_EDITOR') ? getenv('ECHANGELOG_EDITOR') : getenv('EDITOR') || undef; + + if ($editor) { + # Append some informations. + changelog_info(%actions); + + system("$editor ChangeLog.new"); + + if ($? != 0) { + # This usually happens when the editor got forcefully killed; and + # the terminal is probably messed up: so we reset things. + system('stty sane'); + print STDERR "Editor died! Reverting to stdin method.\n"; + undef $editor; + } else { + if (open I, "; + close(I); + + # Remove comments from changelog_info(). + local $/ = "\n"; + $input =~ s/^#.*//mg; + local $/ = undef; + } else { + print STDERR "Error opening ChangeLog.new: $!\n"; + print STDERR "Reverting to stdin method.\n"; + undef $editor; + } + } + unlink('ChangeLog.new') if -f 'ChangeLog.new'; + } + + unless ($editor) { + print "Please type the log entry: use Ctrl-d to finish, Ctrl-c to abort...\n"; + local $/ = undef; + $input = <>; + } +} +die "Empty entry; aborting\n" unless $input =~ /\S/; + +# If there are any long lines, then wrap the input at $columns chars +# (leaving 2 chars on left, one char on right, after adding indentation below). +$input = text_fill(' ', ' ', $input); + +# Prepend the user info to the input +# Changes related to bug 213374; +# This sequence should be right: +# 1. GENTOO_COMMITTER_NAME && GENTOO_COMMITTER_EMAIL +# 2. GENTOO_AUTHOR_NAME && GENTOO_AUTHOR_EMAIL +# 3. ECHANGELOG_USER (fallback/obsolete?) +# 4. getpwuid().. +if ( getenv("GENTOO_COMMITTER_NAME") && getenv("GENTOO_COMMITTER_EMAIL") ) { + $user = sprintf("%s <%s>", getenv("GENTOO_COMMITTER_NAME"), getenv("GENTOO_COMMITTER_EMAIL")); +} +elsif ( getenv("GENTOO_AUTHOR_NAME") && getenv("GENTOO_AUTHOR_EMAIL") ) { + $user = sprintf("%s <%s>", getenv("GENTOO_AUTHOR_NAME"), getenv("GENTOO_AUTHOR_EMAIL")); +} +elsif ( getenv("ECHANGELOG_USER") ) { + $user = getenv("ECHANGELOG_USER"); +} +else { + my ($fullname, $username) = (getpwuid($<))[6,0]; + $fullname =~ s/,.*//; # remove GECOS, bug 80011 + $user = sprintf('%s <%s@gentoo.org>', $fullname, $username); +} + +# Make sure that we didn't get "root" +die "Please set ECHANGELOG_USER or run as non-root\n" if $user =~ /ChangeLog.new' or die "Can't open ChangeLog.new for output: $!\n"; +print O $text or die "Can't write ChangeLog.new: $!\n"; +close O or die "Can't close ChangeLog.new: $!\n"; + +# Update affected ebuild copyright dates. There is no reason to update the +# copyright lines on ebuilds that haven't changed. I verified this with an IP +# lawyer. +for my $e (grep /\.ebuild$/, @files) { + if (-s $e) { + my ($etext, $netext); + + open E, "<$e" or warn("Can't read $e to update copyright year\n"), next; + { local $/ = undef; $etext = ; } + close E; + + # Attempt the substitution and compare + $netext = update_copyright($etext); + next if $netext eq $etext; # skip this file if no change. + + # Write the new ebuild + open E, ">$e.new" or warn("Can't open $e.new\n"), next; + print E $netext and + close E or warn("Can't write $e.new\n"), next; + + # Move things around and show the diff + system "diff -U 0 $e $e.new"; + rename "$e.new", $e or warn("Can't rename $e.new: $!\n"); + + # git requires to re-add this file else it wouln't be included in the commit. + if ($vcs eq "git") + { + system("$vcs{$vcs}{add} ${e}"); + } + } +} + +# Move things around and show the ChangeLog diff +system 'diff -Nu ChangeLog ChangeLog.new'; +rename 'ChangeLog.new', 'ChangeLog' or die "Can't rename ChangeLog.new: $!\n"; + +# Okay, now we have a starter ChangeLog to work with. +# The text will be added just like with any other ChangeLog below. +# Add the new ChangeLog to vcs before continuing. +if ($vcs eq "cvs") { + if (open F, "CVS/Entries") { + system("cvs -f add ChangeLog") unless (scalar grep /^\/ChangeLog\//, ); + } +} elsif ($vcs eq "svn") { + if (open F, ".svn/entries") { + system("svn add ChangeLog") unless (scalar grep /ChangeLog/, ); + } +} else { + system("$vcs{$vcs}{add} ChangeLog 2>&1 >> /dev/null"); +} + +# vim: set ts=4 sw=4 tw=0: diff --git a/gentoolkit-dev/src/echangelog/echangelog.1 b/gentoolkit-dev/src/echangelog/echangelog.1 new file mode 100644 index 0000000..1575644 --- /dev/null +++ b/gentoolkit-dev/src/echangelog/echangelog.1 @@ -0,0 +1,270 @@ +.\" Automatically generated by Pod::Man 2.16 (Pod::Simple 3.07) +.\" +.\" Standard preamble: +.\" ======================================================================== +.de Sh \" Subsection heading +.br +.if t .Sp +.ne 5 +.PP +\fB\\$1\fR +.PP +.. +.de Sp \" Vertical space (when we can't use .PP) +.if t .sp .5v +.if n .sp +.. +.de Vb \" Begin verbatim text +.ft CW +.nf +.ne \\$1 +.. +.de Ve \" End verbatim text +.ft R +.fi +.. +.\" Set up some character translations and predefined strings. \*(-- will +.\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left +.\" double quote, and \*(R" will give a right double quote. \*(C+ will +.\" give a nicer C++. Capital omega is used to do unbreakable dashes and +.\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, +.\" nothing in troff, for use with C<>. +.tr \(*W- +.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' +.ie n \{\ +. ds -- \(*W- +. ds PI pi +. if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch +. if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch +. ds L" "" +. ds R" "" +. ds C` "" +. ds C' "" +'br\} +.el\{\ +. ds -- \|\(em\| +. ds PI \(*p +. ds L" `` +. ds R" '' +'br\} +.\" +.\" Escape single quotes in literal strings from groff's Unicode transform. +.ie \n(.g .ds Aq \(aq +.el .ds Aq ' +.\" +.\" If the F register is turned on, we'll generate index entries on stderr for +.\" titles (.TH), headers (.SH), subsections (.Sh), items (.Ip), and index +.\" entries marked with X<> in POD. Of course, you'll have to process the +.\" output yourself in some meaningful fashion. +.ie \nF \{\ +. de IX +. tm Index:\\$1\t\\n%\t"\\$2" +.. +. nr % 0 +. rr F +.\} +.el \{\ +. de IX +.. +.\} +.\" +.\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). +.\" Fear. Run. Save yourself. No user-serviceable parts. +. \" fudge factors for nroff and troff +.if n \{\ +. ds #H 0 +. ds #V .8m +. ds #F .3m +. ds #[ \f1 +. ds #] \fP +.\} +.if t \{\ +. ds #H ((1u-(\\\\n(.fu%2u))*.13m) +. ds #V .6m +. ds #F 0 +. ds #[ \& +. ds #] \& +.\} +. \" simple accents for nroff and troff +.if n \{\ +. ds ' \& +. ds ` \& +. ds ^ \& +. ds , \& +. ds ~ ~ +. ds / +.\} +.if t \{\ +. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" +. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' +. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' +. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' +. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' +. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' +.\} +. \" troff and (daisy-wheel) nroff accents +.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' +.ds 8 \h'\*(#H'\(*b\h'-\*(#H' +.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] +.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' +.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' +.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] +.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] +.ds ae a\h'-(\w'a'u*4/10)'e +.ds Ae A\h'-(\w'A'u*4/10)'E +. \" corrections for vroff +.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' +.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' +. \" for low resolution devices (crt and lpr) +.if \n(.H>23 .if \n(.V>19 \ +\{\ +. ds : e +. ds 8 ss +. ds o a +. ds d- d\h'-1'\(ga +. ds D- D\h'-1'\(hy +. ds th \o'bp' +. ds Th \o'LP' +. ds ae ae +. ds Ae AE +.\} +.rm #[ #] #H #V #F C +.\" ======================================================================== +.\" +.IX Title "echangelog 1" +.TH echangelog 1 "2009-04-28" "perl v5.10.0" "Gentoolkit" +.\" For nroff, turn off justification. Always turn off hyphenation; it makes +.\" way too many mistakes in technical documents. +.if n .ad l +.nh +.SH "NAME" +echangelog \- Gentoo: update portage ChangeLogs +.SH "SYNOPSIS" +.IX Header "SYNOPSIS" +echangelog [ \fItext\fR ] +.SH "DESCRIPTION" +.IX Header "DESCRIPTION" +This tool provides an easy way to create or update portage ChangeLogs +in Gentoo. The tool scans the current directory, which is assumed to +be a package directory such as /usr/portage/app\-editors/vim, finds +what files have been changed or added, and inserts the appropriate +entry to ChangeLog. If \fItext\fR is not provided on the command-line, +echangelog prompts for it. +.PP +All modifications should occur before running echangelog so that it +can include the appropriate file information in the ChangeLog entry. +For example, you should run \*(L"cvs add\*(R" on your files, otherwise +echangelog won't know those files are part of the update. +.PP +If your text would cause the ChangeLog entry to exceed 80 columns, it +will be rewrapped to keep the ChangeLog neat. If you need special +formatting in the ChangeLog, then you can either (1) run echangelog +with no text on the command-line, and make sure that your text won't +be too wide, (2) edit the ChangeLog manually. If you prefer (2), I'd +recommend something like \*(L"echangelog blah\*(R" so that the header lines +are computed correctly, then edit and change \*(L"blah\*(R" to your preferred +text. +.PP +In addition to updating the ChangeLog, echangelog will automatically +update the copyright year of all out-of-date ebuilds, as well as the +ChangeLog itself. These updates are included in the diff displayed by +echangelog when it finishes its work. +.SH "OPTIONS" +.IX Header "OPTIONS" +Presently echangelog is simple enough that it supplies no options. +Probably I'll add \fB\-\-help\fR and \fB\-\-version\fR in the future, but for +now it's enough to track the gentoolkit version. +.SH "EXAMPLES" +.IX Header "EXAMPLES" +To create a ChangeLog for a completely new package. The header is +parsed from skel.ebuild. +.PP +.Vb 2 +\& $ cvs add metalog\-0.1.ebuild +\& cvs server: use \*(Aqcvs commit\*(Aq to add this file permanently +\& +\& $ echangelog \*(AqNew ebuild, thanks to Harvey McGillicuddy\*(Aq +\& \-\-\- ChangeLog 1969\-12\-31 19:00:00.000000000 \-0500 +\& +++ ChangeLog.new 2003\-02\-23 14:04:06.000000000 \-0500 +\& @@ \-0,0 +1,9 @@ +\& +# ChangeLog for app\-admin/metalog +\& +# Copyright 2000\-2003 Gentoo Technologies, Inc.; Distributed under the GPL v2 +\& +# $Header$ +\& + +\& +*metalog\-0.1 (23 Feb 2003) +\& + +\& + 23 Feb 2003; Aron Griffis metalog\-0.1.ebuild : +\& + New ebuild, thanks to Harvey McGillicuddy +\& + +.Ve +.PP +To bump a revision. Note you need to \*(L"cvs add\*(R" so that echangelog +will notice the new file. +.PP +.Vb 2 +\& $ cvs add metalog\-0.1\-r1.ebuild +\& cvs server: use \*(Aqcvs commit\*(Aq to add this file permanently +\& +\& $ echangelog \*(AqBump revision to fix bug #999\*(Aq +\& \-\-\- ChangeLog 2003\-02\-23 14:04:06.000000000 \-0500 +\& +++ ChangeLog.new 2003\-02\-23 14:07:48.000000000 \-0500 +\& @@ \-2,6 +2,11 @@ +\& # Copyright 2000\-2003 Gentoo Technologies, Inc.; Distributed under the GPL v2 +\& # $Header$ +\& +\& +*metalog\-0.1\-r1 (23 Feb 2003) +\& + +\& + 23 Feb 2003; Aron Griffis metalog\-0.1\-r1.ebuild : +\& + Bump revision to fix bug #999 +\& + +\& *metalog\-0.1 (23 Feb 2003) +\& +\& 23 Feb 2003; Aron Griffis metalog\-0.1.ebuild : +.Ve +.PP +For a multi-line entry, omit the command-line arg. +.PP +.Vb 10 +\& $ echangelog +\& Please type the log entry, finish with ctrl\-d +\& Bump revision to fix bug #999. Necessary to bump the revision because +\& the problem appears at run\-time, not compile\-time. This should also +\& give users the updated default configuration file. +\& \-\-\- ChangeLog 2003\-02\-23 14:09:12.000000000 \-0500 +\& +++ ChangeLog.new 2003\-02\-23 14:12:43.000000000 \-0500 +\& @@ \-2,6 +2,13 @@ +\& # Copyright 2000\-2003 Gentoo Technologies, Inc.; Distributed under the GPL v2 +\& # $Header$ +\& +\& +*metalog\-0.1\-r1 (23 Feb 2003) +\& + +\& + 23 Feb 2003; Aron Griffis metalog\-0.1\-r1.ebuild : +\& + Bump revision to fix bug #999. Necessary to bump the revision because +\& + the problem appears at run\-time, not compile\-time. This should also +\& + give users the updated default configuration file. +\& + +\& *metalog\-0.1 (23 Feb 2003) +\& +\& 23 Feb 2003; Aron Griffis metalog\-0.1.ebuild : +.Ve +.SH "ENVIRONMENT VARIABLES" +.IX Header "ENVIRONMENT VARIABLES" +.IP "\s-1ECHANGELOG_USER\s0" 4 +.IX Item "ECHANGELOG_USER" +If echangelog can't figure out your username for the entry, you should +set \s-1ECHANGELOG_USER\s0. For example, export ECHANGELOG_USER=\*(L"Aron +Griffis \*(R" +.SH "NOTES" +.IX Header "NOTES" +As of the most recent version of echangelog (when this man-page +appeared), echangelog puts all new entries at the top of the file +instead of finding the appropriate *version line within the file. +This is because that \*(L"new\*(R" ChangeLog format was never agreed upon by +the Gentoo developers. Unfortunately the existence of both formats +will undoubtedly cause much confusion. +.PP +This also means that the examples above are wrong, since I just copied +them from some old email. However they're not much wrong. ;\-) +.PP +This tool was written by Aron Griffis . Bugs +found should be filed against me at http://bugs.gentoo.org/ diff --git a/gentoolkit-dev/src/echangelog/test/TEST.pm b/gentoolkit-dev/src/echangelog/test/TEST.pm new file mode 100644 index 0000000..6632148 --- /dev/null +++ b/gentoolkit-dev/src/echangelog/test/TEST.pm @@ -0,0 +1,26 @@ +# We just return a static/predefined date because we're working with +# static md5 checksums. + +package TEST; + +use strict; +use warnings; + +BEGIN { + use Exporter(); + our ($VERSION, @ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS); + + $VERSION = 1.00; + + @ISA = qw(Exporter); + @EXPORT = qw(&strftime); + %EXPORT_TAGS = ( ); + @EXPORT_OK = qw(); +} +our @EXPORT_OK; + +sub strftime { + return "01 Jan 2009"; +} + +1; diff --git a/gentoolkit-dev/src/echangelog/test/templates/test.patch b/gentoolkit-dev/src/echangelog/test/templates/test.patch new file mode 100644 index 0000000..72d46fa --- /dev/null +++ b/gentoolkit-dev/src/echangelog/test/templates/test.patch @@ -0,0 +1,6 @@ +--- test.patch 2009-04-28 14:13:26.171225175 +0200 ++++ test.patch 2009-04-28 14:12:26.246497830 +0200 +@@ -0,0 +1,3 @@ ++This is just an example. ++Its used for several echangelog tests. ++ diff --git a/gentoolkit-dev/src/echangelog/test/templates/vcstest-0.0.1.ebuild b/gentoolkit-dev/src/echangelog/test/templates/vcstest-0.0.1.ebuild new file mode 100644 index 0000000..2824b83 --- /dev/null +++ b/gentoolkit-dev/src/echangelog/test/templates/vcstest-0.0.1.ebuild @@ -0,0 +1,16 @@ +# Copyright 1999-2009 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +DESCRIPTION="echangelog test ebuild" +HOMEPAGE="" +SRC_URI="" + +LICENSE="" +SLOT="0" +KEYWORDS="" +IUSE="" + +DEPEND="" +RDEPEND="" + diff --git a/gentoolkit-dev/src/echangelog/test/test.sh b/gentoolkit-dev/src/echangelog/test/test.sh new file mode 100755 index 0000000..14703d4 --- /dev/null +++ b/gentoolkit-dev/src/echangelog/test/test.sh @@ -0,0 +1,176 @@ +#!/bin/bash + +source /etc/init.d/functions.sh + +SUPPORTED_VCS=( "cvs" "svn" "git" ) +VCSTEST="echangelog-test/vcstest" +_ROOT=$(pwd) + +export ECHANGELOG_USER="Just a test " + +MD5_INIT="34d54bc2ab1a2154b0c7bd5cdd7f6119" +MD5_PATCH="db1ab89bb7374824d0f198078f79a83f" +MD5_REVBUMP="31ddfa60d2ae4dd1fccd7e3d2bd2c06c" +MD5_COPYRIGHT="6f39fa409ea14bb6506347c53f6dee50" +MD5_OBSOLETE="0aedadf159c6f3add97a3f79fb867221" +MD5_FINAL="17eb0df69f501cc6fdaffebd118b7764" + +function md5() { + local fname=$1 + echo $(md5sum ${fname} | awk '{ print $1 }') +} + +function ech() { + local bin=$1 + local msg=$2 + + perl -I$(dirname $(dirname ${bin})) ${bin} "${msg}" +} + +function make_test() { + local root=$1 + local vcs=$2 + + local echangelog="${root}/tmp/echangelog" + local tmp="${root}/tmp/${vcs}" + local template="${root}/templates" + + cd $root + mkdir -p ${tmp} + cd ${tmp} + + [[ "${vcs}" == "cvs" ]] && mkdir -p ${tmp}/cvsroot + [[ "${vcs}" == "svn" ]] && mkdir -p ${tmp}/svnroot + + if [[ "${vcs}" == "git" ]]; + then + git init + touch .gitignore + git add .gitignore + git commit -a -m 'Initial Commit' + elif [[ "${vcs}" == "svn" ]]; + then + svnadmin create svnroot + svn co file://${tmp}/svnroot svn + cd svn + elif [[ "${vcs}" == "cvs" ]]; + then + CVSROOT="${tmp}/cvsroot" cvs init + mkdir cvsroot/cvs + cvs -d:local:${tmp}/cvsroot co cvs + cd cvs + fi + + mkdir -p ${VCSTEST} + + cp ${template}/vcstest-0.0.1.ebuild ${VCSTEST} + ${vcs} add $(dirname ${VCSTEST}) + if [[ "${vcs}" == "cvs" ]]; + then + ${vcs} add ${VCSTEST} + ${vcs} add "${VCSTEST}/vcstest-0.0.1.ebuild" + fi + + cd ${VCSTEST} + ech ${echangelog} 'New ebuild for bug .' + + if [[ "${MD5_INIT}" != "$(md5 ChangeLog)" ]]; + then + eerror "WRONG MD5_INIT!" + fi + + mkdir files + cp ${template}/test.patch files + if [[ "${vcs}" == "cvs" ]]; + then + ${vcs} add files/ + ${vcs} add files/test.patch + else + ${vcs} add files + fi + + ech ${echangelog} "Added adittional patch to fix foo." + + if [[ "${MD5_PATCH}" != "$(md5 ChangeLog)" ]]; + then + eerror "WRONG MD5_PATCH!" + fi + + if [[ "${vcs}" == "svn" ]]; + then + ${vcs} commit -m 'New ebuild for bug .' ../ + else + ${vcs} commit -m 'New ebuild for bug .' + fi + + [[ "${vcs}" == "cvs" ]] && sed -i -e 's:# $Header\: .*$:# $Header\: $:' ChangeLog + + cp vcstest-0.0.1.ebuild vcstest-0.0.1-r1.ebuild + ${vcs} add vcstest-0.0.1-r1.ebuild + + ech ${echangelog} "Revbump..." + + if [[ "${MD5_REVBUMP}" != "$(md5 ChangeLog)" ]]; + then + eerror "WRONG MD5_REVBUMP!" + fi + + sed -i -e 's:# Copyright 1999-2009 Gentoo Foundation:# Copyright 1999-2010 Gentoo Foundation:' vcstest-0.0.1.ebuild + ech ${echangelog} "Revbump...; Just copyright changed." + + if [[ "${MD5_COPYRIGHT}" != "$(md5 ChangeLog)" ]]; + then + eerror "WRONG MD5_COPYRIGHT!" + fi + + if [[ "${vcs}" == "cvs" ]]; + then + rm -f files/test.patch + ${vcs} remove files/test.patch + else + ${vcs} rm files/test.patch + fi + + ech ${echangelog} "Revbump...; Just copyright changed; Removed obsolete patch." + + if [[ "${MD5_OBSOLETE}" != "$(md5 ChangeLog)" ]]; + then + eerror "WRONG MD5_OBSOLETE!" + fi + + echo>>vcstest-0.0.1.ebuild + ech ${echangelog} "Revbump...; Just copyright changed; Removed obsolete patch; Modified more then just the copyright." + + if [[ "${MD5_FINAL}" != "$(md5 ChangeLog)" ]]; + then + eerror "WRONG MD5_FINAL!" + fi +} + +[[ -d "${_ROOT}/tmp" ]] && rm -rf ${_ROOT}/tmp +mkdir -p ${_ROOT}/tmp + +ebegin "Preparing echangelog" + +if [[ -e ../echangelog ]]; +then + cp ../echangelog "${_ROOT}/tmp" || set $? + sed -i -e 's:use POSIX qw.*:use POSIX qw(setlocale getcwd);\nuse TEST qw(strftime);:' "${_ROOT}/tmp/echangelog" || set $? + eend ${1:-0} || exit ${1} +else + eerror "error" + eend ${1:-1} + exit 1 +fi + +for vcs in ${SUPPORTED_VCS[*]}; +do + if [[ -x "$(which ${vcs} 2>/dev/null)" ]]; + then + ebegin "Starting test with ${vcs}" + make_test $_ROOT "${vcs}" || set $? + eend ${1:-0} + else + ewarn "No ${vcs} executable found, skipping test..." + fi +done diff --git a/gentoolkit-dev/src/ego/AUTHOR b/gentoolkit-dev/src/ego/AUTHOR new file mode 100644 index 0000000..36d5bfd --- /dev/null +++ b/gentoolkit-dev/src/ego/AUTHOR @@ -0,0 +1 @@ +Aron Griffis diff --git a/gentoolkit-dev/src/ego/AUTHORS b/gentoolkit-dev/src/ego/AUTHORS new file mode 100644 index 0000000..36d5bfd --- /dev/null +++ b/gentoolkit-dev/src/ego/AUTHORS @@ -0,0 +1 @@ +Aron Griffis diff --git a/gentoolkit-dev/src/ego/ChangeLog b/gentoolkit-dev/src/ego/ChangeLog new file mode 100644 index 0000000..503d0da --- /dev/null +++ b/gentoolkit-dev/src/ego/ChangeLog @@ -0,0 +1,2 @@ +2004-15-01 Karl Trygve Kalleberg + * Added Makefile diff --git a/gentoolkit-dev/src/ego/Makefile b/gentoolkit-dev/src/ego/Makefile new file mode 100644 index 0000000..b27a2cb --- /dev/null +++ b/gentoolkit-dev/src/ego/Makefile @@ -0,0 +1,18 @@ +# Copyright 2004 Karl Trygve Kalleberg +# Copyright 2004 Gentoo Technologies, Inc. +# Distributed under the terms of the GNU General Public License v2 +# +# $Header$ + +include ../../makedefs.mak + +all: + +dist: + mkdir -p ../../$(distdir)/src/ego/ + cp Makefile AUTHORS README TODO ChangeLog ego ../../$(distdir)/src/ego/ + +install: all + install -d $(docdir)/ego + install -m 0644 AUTHORS README ego $(docdir)/ego/ + diff --git a/gentoolkit-dev/src/ego/README b/gentoolkit-dev/src/ego/README new file mode 100644 index 0000000..6c44b4c --- /dev/null +++ b/gentoolkit-dev/src/ego/README @@ -0,0 +1,2 @@ +[ -f ${HOME}/scripts/ego.bash ] && +alias ego="unalias ego ; source ${HOME}/scripts/ego.bash ; ego " diff --git a/gentoolkit-dev/src/ego/TODO b/gentoolkit-dev/src/ego/TODO new file mode 100644 index 0000000..e69de29 diff --git a/gentoolkit-dev/src/ego/ego b/gentoolkit-dev/src/ego/ego new file mode 100644 index 0000000..f1691f2 --- /dev/null +++ b/gentoolkit-dev/src/ego/ego @@ -0,0 +1,86 @@ +echo1() { + echo "$1" +} + +ego() { + local portdir tmpdir category pkg target + + # This is WAY faster than portageq: + # portdir=$(portageq portdir) + # tmpdir=$(portageq envvar PORTAGE_TMPDIR)/portage + eval $( + . /etc/make.globals + . /etc/make.conf + export PORTDIR PORTAGE_TMPDIR + export | sed -n ' + s/^declare -x PORTDIR=/portdir=/p + s/^declare -x PORTAGE_TMPDIR=\(.*\)/tmpdir=\1\/portage/p' + ) + + case $1 in + *-*/*) + pkg=${1##*/} + category=${1%/*} + ;; + + ?*) + pkg=$1 + # require an ebuild so that we can block deprecated packages + # such as dev-libs/rep-gtk + category=$(echo1 $portdir/*-*/$pkg/*.ebuild) + [[ -f $category ]] || category=$(echo1 $portdir/*-*/$pkg*/*.ebuild) + [[ -f $category ]] || category=$(echo1 $portdir/*-*/*$pkg/*.ebuild) + [[ -f $category ]] || category=$(echo1 $portdir/*-*/*$pkg*/*.ebuild) + if [[ ! -f $category ]]; then + echo "Can't find $pkg in $portdir" >&2 + return 1 + fi + pkg=${category%/*} + pkg=${pkg##*/} + category=${category#$portdir/} + category=${category%%/*} + ;; + + *) + # Check if we're under $portdir first + pkg=${PWD##*/} + category=${PWD%/*} + category=${category##*/} + if [[ ! -d $portdir/$category/$pkg ]]; then + # Next check if we're in PORTAGE_TMPDIR + if [[ $PWD = $tmpdir/* ]]; then + pkg=${PWD#$tmpdir/} + pkg=${pkg%%/*} + pkg=${pkg%%-[0-9]*} # not really a valid assumption + category=$(echo1 $portdir/*-*/$pkg/*.ebuild) + if [[ ! -f $category ]]; then + echo "Can't find $pkg in $portdir" >&2 + return 1 + fi + category=${category#$portdir/} + category=${category%%/*} + else + echo "syntax: ego [pkgname]" >&2 + echo "or simply ego from a dir under $portdir or $tmpdir" >&2 + return 1 + fi + fi + ;; + esac + + # go to tmpdir or portdir? + if [[ $PWD/ = */$category/$pkg/* ]]; then + [[ -n $tmpdir ]] || tmpdir=$(portageq envvar PORTAGE_TMPDIR)/portage + target=$(command ls -1td $tmpdir/$pkg-* 2>/dev/null | head -n 1) + if [[ -z $target ]]; then + echo "No matches found for $tmpdir/$pkg-*" >&2 + return 1 + fi + cd $target/work/$pkg* 2>/dev/null || + cd $target/work 2>/dev/null || + cd $target + else + cd $portdir/$category/$pkg + fi +} + diff --git a/gentoolkit-dev/src/ekeyword/AUTHORS b/gentoolkit-dev/src/ekeyword/AUTHORS new file mode 100644 index 0000000..36d5bfd --- /dev/null +++ b/gentoolkit-dev/src/ekeyword/AUTHORS @@ -0,0 +1 @@ +Aron Griffis diff --git a/gentoolkit-dev/src/ekeyword/ChangeLog b/gentoolkit-dev/src/ekeyword/ChangeLog new file mode 100644 index 0000000..68d99e5 --- /dev/null +++ b/gentoolkit-dev/src/ekeyword/ChangeLog @@ -0,0 +1,46 @@ +24 Apr 2009 Paul Varner + * Handle multiline KEYWORDS + +07 Jan 2009 Mike Frysinger + * Support intended KEYWORDS + * Convert every instance of KEYWORDS in the file + * Error out on invalid arguments #156827 + * Tighten up diff output to show KEYWORDS changes + +27 Oct 2005 Aron Griffis + * Fix handling of comments + * Add support for bare ~ as a synonym for ~all + +23 Mar 2005 Aron Griffis + * Only modify non-masked keywords with "all" + +17 Mar 2005 Aron Griffis + * Sort keywords alphabetically + +09 Nov 2004 Aron Griffis + * Fix mismatching of ppc vs. ppc-macos #69683 + +15 Sep 2004 Aron Griffis + * Update for GLEP 22 keywords + * Change copyright line for Gentoo Foundation + +12 Apr 2004 Aron Griffis + * Add ability to remove keywords with ^, for example: + ekeyword ^alpha blah.ebuild + * Add support for -*, for example: ekeyword -* would add it; + ekeyword ^* would remove it. + * Add a man-page for ekeyword + +09 Apr 2004 Aron Griffis + * Add ability to modify all keywords via all, ~all, or -all, for + example: ekeyword -all ~alpha ia64 blah.ebuild + +31 Mar 2004 Aron Griffis + * Fix bug 28426 with patch from Mr_Bones_ to keep ekeyword from confusing + ppc and ppc64 + +2004-01-12 Aron Griffis + * Allow multiple keywords + +2004-01-07 Karl Trygve Kalleberg + * Added Makefile diff --git a/gentoolkit-dev/src/ekeyword/Makefile b/gentoolkit-dev/src/ekeyword/Makefile new file mode 100644 index 0000000..a1a5802 --- /dev/null +++ b/gentoolkit-dev/src/ekeyword/Makefile @@ -0,0 +1,26 @@ +# Copyright 2004 Karl Trygve Kalleberg +# Copyright 2004 Gentoo Technologies, Inc. +# Distributed under the terms of the GNU General Public License v2 +# +# $Header$ + +include ../../makedefs.mak + +%.1 : %.pod + pod2man $< > $@ + +.PHONY: all +all: ekeyword.1 + +dist: ekeyword.1 + mkdir -p ../../$(distdir)/src/ekeyword + cp Makefile AUTHORS README TODO ChangeLog ekeyword ekeyword.1 ../../$(distdir)/src/ekeyword/ + +install: all + install -m 0755 ekeyword $(bindir)/ + install -d $(docdir)/ekeyword + install -m 0644 AUTHORS README TODO ChangeLog $(docdir)/ekeyword/ + install -m 0644 ekeyword.1 $(mandir)/ + +clean: + $(RM) ekeyword.1 diff --git a/gentoolkit-dev/src/ekeyword/README b/gentoolkit-dev/src/ekeyword/README new file mode 100644 index 0000000..ec7ff5e --- /dev/null +++ b/gentoolkit-dev/src/ekeyword/README @@ -0,0 +1,20 @@ +Package : ekeyword +Version : 0.1.0 +Author : See AUTHORS + +MOTIVATION + +Update the KEYWORDS in an ebuild. + +MECHANICS + +N/A + +IMPROVEMENTS + +- Should rewrite to Python, and use Portage directly to select candidate + ebuilds. +- Should add entry to ChangeLog. + +For improvements, send a mail to agriffis@gentoo.org or make out a bug at +bugs.gentoo.org. diff --git a/gentoolkit-dev/src/ekeyword/TODO b/gentoolkit-dev/src/ekeyword/TODO new file mode 100644 index 0000000..e69de29 diff --git a/gentoolkit-dev/src/ekeyword/ekeyword b/gentoolkit-dev/src/ekeyword/ekeyword new file mode 100755 index 0000000..e38801d --- /dev/null +++ b/gentoolkit-dev/src/ekeyword/ekeyword @@ -0,0 +1,147 @@ +#!/usr/bin/perl -w +# +# Copyright 2003-2009, Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# Written by Aron Griffis +# +# ekeyword: Update the KEYWORDS in an ebuild. For example: +# +# $ ekeyword ~alpha oaf-0.6.8-r1.ebuild +# - ppc sparc x86 +# + ~alpha ppc sparc x86 + +my ($kw_re) = '^(?:([-~^]?)(\w[\w-]*)|([-^]\*))$'; +my (@kw); + +# make sure the cmdline consists of keywords and ebuilds +unless (@ARGV > 0) { + # NOTE: ~all will ignore all -arch keywords + print STDERR "syntax: ekeyword { arch | ~[arch] | -[arch] } ebuild...\n"; + print STDERR "instead of 'arch' you can also use 'all' which covers all existing keywords...\n"; + exit(1); +} +for my $a (@ARGV) { + $a = '~all' if $a eq '~' or $a eq $ENV{'HOME'}; # for vapier + next if $a =~ /$kw_re/o; # keyword + next if $a =~ /^\S+\.ebuild$/; # ebuild + die "I don't understand $a\n"; +} + +my $files = 0; +for my $f (@ARGV) { + if ($f =~ /$kw_re/o) { + push @kw, $f; + next; + } + + print "$f\n"; + + open I, "<$f" or die "Can't read $f: $!\n"; + open O, ">$f.new" or die "Can't create $f.new: $!\n"; + select O; + + my $keys_before; + my $keys_after; + while () { + if (/^\s*KEYWORDS=/) { + + # extract the quoted section from KEYWORDS + while (not /^\s*KEYWORDS=["'].*?["']/) { + chomp; + my $next = ; + $_ = join " ", $_, $next; + } + (my $quoted = $_) =~ s/^.*?["'](.*?)["'].*/$1/s; + $keys_before = $quoted; + + # replace -* with -STAR for our convenience below + $quoted =~ s/-\*/-STAR/; + + for my $k (@kw) { + my ($leader, $arch, $star) = ($k =~ /$kw_re/o); + + # handle -* and ^* + if (defined $star) { + $leader = substr $star,0,1; + $arch = 'STAR'; + } + + # remove keywords + if ($leader eq '^') { + if ($arch eq 'all') { + $quoted = ''; + } else { + $quoted =~ s/[-~]?\Q$arch\E\b//; + } + + # add or modify keywords + } else { + if ($arch eq 'all') { + # modify all non-masked keywords in the list + $quoted =~ s/(^|\s)~?(?=\w)/$1$leader/g; + } else { + # modify or add keyword + unless ($quoted =~ s/[-~]?\Q$arch\E(\s|$)/$leader$arch$1/) { + # modification failed, need to add + if ($arch eq 'STAR') { + $quoted = "$leader$arch $quoted"; + } else { + $quoted .= " $leader$arch"; + } + } + } + } + } + + # replace -STAR with -* + $quoted =~ s/-STAR\b/-*/; + + # sort keywords and fix spacing + $quoted = join " ", sort { + (my $sa = $a) =~ s/^\W//; + (my $sb = $b) =~ s/^\W//; + return -1 if $sa eq '*'; + return +1 if $sb eq '*'; + $sa .= "-"; + $sb .= "-"; + $sa =~ s/([a-z0-9]+)-([a-z0-9]*)/$2-$1/g; + $sb =~ s/([a-z0-9]+)-([a-z0-9]*)/$2-$1/g; + $sa cmp $sb; + } split " ", $quoted; + + $keys_after = $quoted; + + # re-insert quoted to KEYWORDS + s/(["']).*?["']/$1$quoted$1/; + + print $_ or die "Can't write $f.new: $!\n"; + } else { + print, next; + } + } + + close I; + close O; + select STDOUT; + + if ($keys_before ne $keys_after) { + # This gives uniform output, but actually seems to make + # it harder to pick out differences, and doesn't work so + # well when adding/removing keywords + #$keys_before =~ s/(^| )/ /g; + #$keys_before =~ s/ ([-~])/$1/g; + #$keys_after =~ s/(^| )/ /g; + #$keys_after =~ s/ ([-~])/$1/g; + print " - $keys_before\n + $keys_after\n"; + #system "diff -U 0 $f $f.new | sed -n -r 's:^(.)[[:space:]]*KEYWORDS=\"(.*)\": \\1 \\2:p'"; + #system "diff -U 0 $f $f.new | sed -n '/KEYWORDS=/s:^: :p'"; + } + rename "$f.new", "$f" or die "Can't rename: $!\n"; + $files++; +} + +if ($files == 0) { + die "No ebuilds processed!"; +} + +# vim:ts=4 sw=4 diff --git a/gentoolkit-dev/src/ekeyword/ekeyword.pod b/gentoolkit-dev/src/ekeyword/ekeyword.pod new file mode 100644 index 0000000..ff837b9 --- /dev/null +++ b/gentoolkit-dev/src/ekeyword/ekeyword.pod @@ -0,0 +1,68 @@ +=head1 NAME + +ekeyword - Gentoo: modify package KEYWORDS + +=head1 SYNOPSIS + +ekeyword { arch|~arch|-arch|^arch } ebuild... + +=head1 DESCRIPTION + +This tool provides a simple way to add or update KEYWORDS in a set of +ebuilds. Each command-line argument is processed in order, so that +keywords are added to the current list as they appear, and ebuilds are +processed as they appear. + +Instead of specifying a specific arch, it's possible to use the word +"all". This causes the change to apply to all keywords presently +specified in the ebuild. + +The ^ leader instructs ekeyword to remove the specified arch. + +=head1 OPTIONS + +Presently ekeyword is simple enough that it supplies no options. +Probably I'll add B<--help> and B<--version> in the future, but for +now it's enough to track the gentoolkit version. + +=head1 EXAMPLES + +To mark a single arch stable: + + $ ekeyword alpha metalog-0.7-r1.ebuild + metalog-0.7-r1.ebuild + -KEYWORDS="~alpha ~amd64 ~hppa ~ia64 ~mips ~ppc ~sparc ~x86" + +KEYWORDS="alpha ~amd64 ~hppa ~ia64 ~mips ~ppc ~sparc ~x86" + +When bumping a package, to mark all arches for testing: + + $ ekeyword ~all metalog-0.7-r2.ebuild + metalog-0.7-r2.ebuild + -KEYWORDS="alpha amd64 hppa ia64 mips ppc sparc x86" + +KEYWORDS="~alpha ~amd64 ~hppa ~ia64 ~mips ~ppc ~sparc ~x86" + +To signify that a package is broken for all arches except one: + + $ ekeyword ^all -* ~x86 metalog-0.7-r3.ebuild + metalog-0.7-r3.ebuild + -KEYWORDS="~alpha ~amd64 ~hppa ~ia64 ~mips ~ppc ~sparc ~x86" + +KEYWORDS="-* ~x86" + +To do lots of things at once: + + $ ekeyword alpha metalog-0.7-r1.ebuild \ + ~all metalog-0.7-r2.ebuild ^all -* ~x86 metalog-0.7-r3.ebuild + metalog-0.7-r1.ebuild + -KEYWORDS="~alpha ~amd64 ~hppa ~ia64 ~mips ~ppc ~sparc ~x86" + +KEYWORDS="alpha ~amd64 ~hppa ~ia64 ~mips ~ppc ~sparc ~x86" + metalog-0.7-r2.ebuild + -KEYWORDS="alpha amd64 hppa ia64 mips ppc sparc x86" + +KEYWORDS="~alpha ~amd64 ~hppa ~ia64 ~mips ~ppc ~sparc ~x86" + metalog-0.7-r3.ebuild + -KEYWORDS="~alpha ~amd64 ~hppa ~ia64 ~mips ~ppc ~sparc ~x86" + +KEYWORDS="-* ~x86" + +=head1 NOTES + +This tool was written by Aron Griffis . Bugs +found should be filed against me at http://bugs.gentoo.org/ diff --git a/gentoolkit-dev/src/ekeyword2/ekeyword2 b/gentoolkit-dev/src/ekeyword2/ekeyword2 new file mode 100755 index 0000000..ce8842d --- /dev/null +++ b/gentoolkit-dev/src/ekeyword2/ekeyword2 @@ -0,0 +1,96 @@ +#!/usr/bin/python + +# Output like: +# setuptools-0.6_rc9.ebuild +# < KEYWORDS="~alpha ~amd64 ~arm ~hppa ~ia64 ~mips ~ppc ~ppc64 ~s390 ~sh ~sparc ~sparc-fbsd -x86 ~x86-fbsd" +# --- +# > KEYWORDS="~alpha ~amd64 ~arm ~hppa ~ia64 ~mips ~ppc ~ppc64 ~s390 ~sh ~sparc ~sparc-fbsd x86 ~x86-fbsd" + +from __future__ import with_statement +from sys import argv +from fnmatch import fnmatch +from shutil import copyfile +from os import environ as env + +import re +import string + +from portage import settings + +STABLE_KEYWORDS = frozenset(settings["PORTAGE_ARCHLIST"].split()) +BROKEN_KEYWORDS = frozenset(['-*'] + ['-'+k for k in STABLE_KEYWORDS]) +TEST_KEYWORDS = frozenset(['~'+k for k in STABLE_KEYWORDS]) +KNOWN_KEYWORDS = STABLE_KEYWORDS | TEST_KEYWORDS | BROKEN_KEYWORDS + +argv = set(argv[1:]) +kw_re = re.compile(r'KEYWORDS="([^"]*)"') +ebuilds = frozenset([x for x in argv if fnmatch(x, '*.ebuild')]) +pretend = bool(argv.intersection(('-p', '--pretend',))) +keywords = argv.difference(('-p', '--pretend',)) - ebuilds + +if not ebuilds: + print 'usage: ekeyword [-p|--pretend] [^|~|-][all] [[^|~|-]arch [[^|~|-]arch]...] ebuild [ebuild...]' + +for e in ebuilds: + # TODO: error handling for file I/O + kw = set(keywords) + if not pretend: + try: + copyfile(e, e+'.orig') + except IOError: + print "Can't copy file %s. Check permissions." % e + exit(1) + try: + with open(e) as c: + ebuild = c.read() + except IOError: + print "Can't open file %s. Aborting." % e + exit(1) + + orig = kw_re.search(ebuild) + curkw = set(orig.groups()[0].split()) + + # ^ or ^all by itself means remove all keywords + # (however, other keywords established in the same args still get set.) + if kw.intersection(('^', '^all',)): + kw -= set(('^', '^all',)) + curkw = set() + + # ~ or ~all by itself means set ~keyword for all keywords + # since ~ expands to "$HOME" in the shell, assume the user meant ~ if we see + # the expansion of "$HOME". (Hope there's no user named 'all'.) + if kw.intersection(('~', '~all', env['HOME'],)): + kw -= set(('~', '~all', env['HOME'],)) + curkw = set(['~'+k if k in STABLE_KEYWORDS else k for k in curkw]) + + for k in kw: + # Remove keywords starting with ^ + if k[0] == '^': + curkw -= set((k[1:], '-'+k[1:], '~'+k[1:], )) + # Set ~ and - keywords to TEST and BROKEN, respectively + elif k[0] == '~' or k[0] == '-': + curkw -= set((k[1:], '-'+k[1:], '~'+k[1:], )) + curkw |= set((k,)) + # Set remaining keywords to STABLE + else: + curkw -= set(('~'+k,)) + curkw |= set((k,)) + + # Sort by arch, then OS (Luckily, this makes -* show up first if it's there) + result = 'KEYWORDS="%s"' % ' '.join(sorted(curkw, + key=lambda x: x.strip(string.punctuation).lower())) + + if not pretend: + try: + with open(e, 'w') as rebuild: + rebuild.write(kw_re.sub(result, ebuild)) + except IOError: + print "Can't write file %s. Aborting." % e + exit(1) + + unknown_keywords = curkw - KNOWN_KEYWORDS + if unknown_keywords: + print "\nWarning: Unknown keywords '%s'.\n" % ', '.join(sorted(unknown_keywords)) + + print '<<< %s' % orig.group() + print '>>> %s' % result diff --git a/gentoolkit-dev/src/eshowkw/Makefile b/gentoolkit-dev/src/eshowkw/Makefile new file mode 100644 index 0000000..77bf1d8 --- /dev/null +++ b/gentoolkit-dev/src/eshowkw/Makefile @@ -0,0 +1,18 @@ +# Copyright 1999-2009 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +include ../../makedefs.mak + +.PHONY: all + +all: + +dist: + mkdir -p ../../$(distdir)/src/eshowkw/ + cp Makefile eshowkw eshowkw.1 ../../$(distdir)/src/eshowkw/ + +install: all + install -m 0755 eshowkw $(bindir)/ + install -m 0644 eshowkw.1 $(mandir)/ + diff --git a/gentoolkit-dev/src/eshowkw/eshowkw b/gentoolkit-dev/src/eshowkw/eshowkw new file mode 100644 index 0000000..d5d3584 --- /dev/null +++ b/gentoolkit-dev/src/eshowkw/eshowkw @@ -0,0 +1,357 @@ +#!/bin/bash +# vim: set sw=4 sts=4 et tw=80 : + +# Author: Ciaran McCreesh +# Purpose: Display ebuild keywords in a graphical form +# Invocation: eshowkw [ packagename ] (defaults to current directory if no +# packagename is provided) + +shopt -s extglob + +PID_TO_KILL=$$ + +die() { + echo "$@" 1>&2 + kill $PID_TO_KILL +} + +trap 'exit 250' 15 + +get_portage_dir() { + local dir + if [[ -z ${portage_dir_cache} ]] ; then + for dir in "${HOME}/cvs/gentoo-x86" "/usr/portage" ; do + [[ -d ${dir}/profiles ]] && portage_dir_cache=${dir} && break + done + fi + [[ -z ${portage_dir_cache} ]] && portage_dir_cache=$(portageq portdir ) + export portage_dir_cache + echo ${portage_dir_cache} +} + +version_sort() { + local items= left=0 + items=( $@ ) + + while [[ ${left} -lt ${#items[@]} ]] ; do + local lowest_idx=${left} + local idx=$(( ${lowest_idx} + 1 )) + while [[ ${idx} -lt ${#items[@]} ]] ; do + version_compare "${items[${lowest_idx}]}" "${items[${idx}]}" + [[ $? -eq 3 ]] && lowest_idx=${idx} + idx=$(( ${idx} + 1 )) + done + local tmp=${items[${lowest_idx}]} + items[${lowest_idx}]=${items[${left}]} + items[${left}]=${tmp} + left=$(( ${left} + 1 )) + done + echo ${items[@]} +} + +version_compare() { + local ver_a=${1} ver_b=${2} parts_a parts_b cur_idx_a=0 cur_idx_b=0 + parts_a=( $(get_all_version_components "${ver_a}" ) ) + parts_b=( $(get_all_version_components "${ver_b}" ) ) + + ### compare number parts. + local inf_loop=0 + while true ; do + # grab the current number components + local cur_tok_a=${parts_a[${cur_idx_a}]} + local cur_tok_b=${parts_b[${cur_idx_b}]} + + # number? + if [[ -n ${cur_tok_a} ]] && [[ -z ${cur_tok_a//[[:digit:]]} ]] ; then + cur_idx_a=$(( ${cur_idx_a} + 1 )) + [[ ${parts_a[${cur_idx_a}]} == "." ]] \ + && cur_idx_a=$(( ${cur_idx_a} + 1 )) + else + cur_tok_a="" + fi + + if [[ -n ${cur_tok_b} ]] && [[ -z ${cur_tok_b//[[:digit:]]} ]] ; then + cur_idx_b=$(( ${cur_idx_b} + 1 )) + [[ ${parts_b[${cur_idx_b}]} == "." ]] \ + && cur_idx_b=$(( ${cur_idx_b} + 1 )) + else + cur_tok_b="" + fi + + # done with number components? + [[ -z ${cur_tok_a} ]] && [[ -z ${cur_tok_b} ]] && break + + # to avoid going into octal mode, strip any leading zeros. otherwise + # bash will throw a hissy fit on versions like 6.3.068. + cur_tok_a=${cur_tok_a##+(0)} + cur_tok_b=${cur_tok_b##+(0)} + + # if a component is blank, make it zero. + [[ -z ${cur_tok_a} ]] && cur_tok_a=0 + [[ -z ${cur_tok_b} ]] && cur_tok_b=0 + + # compare + [[ ${cur_tok_a} -lt ${cur_tok_b} ]] && return 1 + [[ ${cur_tok_a} -gt ${cur_tok_b} ]] && return 3 + done + + ### number parts equal. compare letter parts. + local letter_a= + letter_a=${parts_a[${cur_idx_a}]} + if [[ ${#letter_a} -eq 1 ]] && [[ -z ${letter_a/[a-z]} ]] ; then + cur_idx_a=$(( ${cur_idx_a} + 1 )) + else + letter_a="@" + fi + + local letter_b= + letter_b=${parts_b[${cur_idx_b}]} + if [[ ${#letter_b} -eq 1 ]] && [[ -z ${letter_b/[a-z]} ]] ; then + cur_idx_b=$(( ${cur_idx_b} + 1 )) + else + letter_b="@" + fi + + # compare + [[ ${letter_a} < ${letter_b} ]] && return 1 + [[ ${letter_a} > ${letter_b} ]] && return 3 + + ### letter parts equal. compare suffixes in order. + local suffix rule part r_lt r_gt + for rule in "alpha=1" "beta=1" "pre=1" "rc=1" "p=3" "r=3" ; do + suffix=${rule%%=*} + r_lt=${rule##*=} + [[ ${r_lt} -eq 1 ]] && r_gt=3 || r_gt=1 + + local suffix_a= + for part in ${parts_a[@]} ; do + [[ ${part#${suffix}} != ${part} ]] && \ + [[ -z ${part##${suffix}*([[:digit:]])} ]] && \ + suffix_a=${part#${suffix}}0 + done + + local suffix_b= + for part in ${parts_b[@]} ; do + [[ ${part#${suffix}} != ${part} ]] && \ + [[ -z ${part##${suffix}*([[:digit:]])} ]] && \ + suffix_b=${part#${suffix}}0 + done + + [[ -z ${suffix_a} ]] && [[ -z ${suffix_b} ]] && continue + + [[ -z ${suffix_a} ]] && return ${r_gt} + [[ -z ${suffix_b} ]] && return ${r_lt} + + # avoid octal problems + suffix_a=${suffix_a##+(0)} ; suffix_a=${suffix_a:-0} + suffix_b=${suffix_b##+(0)} ; suffix_b=${suffix_b:-0} + + [[ ${suffix_a} -lt ${suffix_b} ]] && return 1 + [[ ${suffix_a} -gt ${suffix_b} ]] && return 3 + done + + ### no differences. + return 2 +} + +get_all_version_components() { + local ver_str=${1} result result_idx=0 + result=( ) + + while [[ -n "$ver_str" ]] ; do + case "${ver_str:0:1}" in + # number: parse whilst we have a number + [[:digit:]]) + result[$result_idx]="${ver_str%%[^[:digit:]]*}" + ver_str="${ver_str##+([[:digit:]])}" + result_idx=$(($result_idx + 1)) + ;; + + # separator: single character + [-_.]) + result[$result_idx]="${ver_str:0:1}" + ver_str="${ver_str:1}" + result_idx=$(($result_idx + 1)) + ;; + + # letter: grab the letters plus any following numbers + [[:alpha:]]) + local not_match="${ver_str##+([[:alpha:]])*([[:digit:]])}" + result[$result_idx]=${ver_str:0:$((${#ver_str} - ${#not_match}))} + ver_str="${not_match}" + result_idx=$(($result_idx + 1)) + ;; + + # huh? + *) + result[$result_idx]="${ver_str:0:1}" + ver_str="${ver_str:1}" + result_idx=$(($result_idx + 1)) + ;; + esac + done + + echo ${result[@]} +} + +get_package_dir() { + if [[ -z ${1} ]] ; then + pwd + return 0 + fi + + if [[ -d ${1} ]] ; then + readlink -f ${1} + return 0 + fi + + get_portage_dir 1>/dev/null + if [[ ${1/\/} != ${1} ]] ; then + local d=$(get_portage_dir )/${1} + if [[ -d ${d} ]] ; then + echo ${d} + return 0 + fi + else + local d + d=( $(echo $(get_portage_dir )/*-*/${1} ) ) + if [[ ${#d[@]} -gt 1 ]] ; then + die "${1} is ambiguous" + elif [[ -d ${d[0]} ]] ; then + echo ${d[0]} + return 0 + fi + fi + + return 1 +} + +repeat() { + local i + for (( i=0 ; i < ${1} ; i=$(( ${i} + 1 )) )) ; do + echo -n "${2}" + done +} + +get_keywords() { + ( + inherit() { :; } + source "$(pwd)/${1}" 2>/dev/null + echo ${KEYWORDS} + ) +} + +colorarch() { + case "${1}" in + amd64) + echo -n -e "\033[0;33m${2}\033[0;0m" + ;; + x86) + echo -n -e "\033[0;31m${2}\033[0;0m" + ;; + *) + echo -n "${2}" + ;; + esac +} + +colourise() { + case "${1}" in + \*) + echo -n -e "\033[0;31m*\033[0;0m" + ;; + +) + echo -n -e "\033[0;32m+\033[0;0m" + ;; + -) + echo -n -e "\033[0;31m-\033[0;0m" + ;; + \~) + echo -n -e "\033[0;33m~\033[0;0m" + ;; + *) + echo -n "${1}" + ;; + esac +} + +show_keyword_diagram() { + echo -n -e "Keywords for \033[1;34m" + local title=$(readlink -f $(pwd ) ) + title=${title#$(readlink -f ../.. )/*( )} + echo -n "${title}" + echo -e "\033[0;0m:" + echo + + local archs=() arch_length=0 arch= + while read arch + do + [[ -z "${arch}" ]] && continue + [[ "${arch:0:1}" == "#" ]] && continue + [[ ${#arch} -gt ${arch_length} ]] && arch_length=${#arch} + + archs[${#archs[*]}]=$arch + done < "$(get_portage_dir)/profiles/arch.list" + + + local versions= pkgname= version_length=0 version= + pkgname=$(basename $(readlink -f ./ ) ) + versions=( $(for e in $(echo *.ebuild ) ; do \ + [[ -f ${e} ]] && echo ${e} | sed -e 's/\.ebuild$//g' \ + -e "s/^${pkgname}-//g" ; \ + done ) ) + versions=( $(version_sort ${versions[@]} ) ) + for version in "${versions[@]}" ; do + [[ ${#version} -gt ${version_length} ]] && version_length=${#version} + done + + local i=0 archletter= + for (( i = 0 ; i < ${arch_length} ; i=$(( ${i} + 1 )) )) ; do + repeat ${version_length} " " + echo -n " | " + for arch in "${archs[@]}" ; do + archletter="${arch:${i}:1}" + echo -n "$(colorarch "${arch}" "${archletter:- }" ) " + done + echo + done + + repeat ${version_length} "-" + echo -n "-+" + repeat ${#archs[@]} "--" + echo + + for version in "${versions[@]}" ; do + echo -n "${version}" + repeat $(( ${version_length} - ${#version} )) " " + echo -n " | " + + local keyword keywords + keywords=( $(get_keywords "${pkgname}-${version}.ebuild" ) ) + for arch in "${archs[@]}" ; do + local display=" " + [[ ${keywords[@]/-\*} != ${keywords[@]} ]] && display="*" + for keyword in "${keywords[@]}" ; do + [[ ${arch} == "${keyword#[~-]}" ]] && \ + display=${keyword:0:1} && \ + break; + done + [[ -z ${display#[~ *-]} ]] || display="+" + echo -n "$(colourise "${display}" ) " + done + + echo + done +} + +main() { + local dir=$(get_package_dir "${1}" ) + [[ -z ${dir} ]] && die "Couldn't find '${1}'" + cd ${dir} + [[ $(echo *.ebuild ) != "*.ebuild" ]] || die "No ebuilds in ${dir}" + show_keyword_diagram + true +} + +main "$@" + diff --git a/gentoolkit-dev/src/eshowkw/eshowkw.1 b/gentoolkit-dev/src/eshowkw/eshowkw.1 new file mode 100644 index 0000000..8d08048 --- /dev/null +++ b/gentoolkit-dev/src/eshowkw/eshowkw.1 @@ -0,0 +1,14 @@ +.TH "eshowkw" "1" "Ciaran McCreesh" "gentoolkit-dev" +.SH "NAME" +.LP +eshowkw \- Displays ebuild keywords in a graphical form. +.SH "SYNTAX" +.LP +eshowkw [ packagename ] (defaults to current directory if no packagename is provided) + + +.SH "AUTHORS" +.LP +Ciaran McCreesh +.SH "BUGS" +Please report any bugs to http://bugs.gentoo.org diff --git a/gentoolkit-dev/src/eviewcvs/AUTHORS b/gentoolkit-dev/src/eviewcvs/AUTHORS new file mode 100644 index 0000000..36d5bfd --- /dev/null +++ b/gentoolkit-dev/src/eviewcvs/AUTHORS @@ -0,0 +1 @@ +Aron Griffis diff --git a/gentoolkit-dev/src/eviewcvs/Makefile b/gentoolkit-dev/src/eviewcvs/Makefile new file mode 100644 index 0000000..7ab81c6 --- /dev/null +++ b/gentoolkit-dev/src/eviewcvs/Makefile @@ -0,0 +1,25 @@ +# Copyright 2005 Gentoo Technologies, Inc. +# Distributed under the terms of the GNU General Public License v2 +# +# $Header$ + +include ../../makedefs.mak + +%.1 : %.pod + pod2man $< > $@ + +.PHONY: all +all: eviewcvs.1 + +dist: eviewcvs.1 + mkdir -p ../../$(distdir)/src/eviewcvs/ + cp Makefile AUTHORS README eviewcvs eviewcvs.pod eviewcvs.1 ../../$(distdir)/src/eviewcvs/ + +install: all + install -m 0755 eviewcvs $(bindir)/ + install -d $(docdir)/eviewcvs + install -m 0644 AUTHORS README $(docdir)/eviewcvs/ + install -m 0644 eviewcvs.1 $(mandir)/ + +clean: + $(RM) eviewcvs.1 diff --git a/gentoolkit-dev/src/eviewcvs/README b/gentoolkit-dev/src/eviewcvs/README new file mode 100644 index 0000000..c7258d7 --- /dev/null +++ b/gentoolkit-dev/src/eviewcvs/README @@ -0,0 +1,11 @@ +Most of the documentation is contained in the man-page, which you can +read directly (using GNU man) by doing + + man ./eviewcvs.1 + +To rebuild the man-page from pod source, do + + pod2man --name=eviewcvs --center='Gentoolkit' \ + eviewcvs.pod eviewcvs.1 + +03 Nov 2004 agriffis diff --git a/gentoolkit-dev/src/eviewcvs/eviewcvs b/gentoolkit-dev/src/eviewcvs/eviewcvs new file mode 100755 index 0000000..280ec0b --- /dev/null +++ b/gentoolkit-dev/src/eviewcvs/eviewcvs @@ -0,0 +1,95 @@ +#!/bin/bash +# $Id$ +# +# Copyright 2005, Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# Written by Aron Griffis +# +# eviewcvs - generate viewcvs urls for some files +# + +if [[ -t 1 ]]; then + blue="" + cyan="" + green="" + red="" + off="" +else + unset blue cyan green red off +fi + +startdir="$PWD" +url="http://sources.gentoo.org/viewcvs.py" +unset diffs +declare -a hdr orev + +chdir() { + cd "$1" || return + + # Figure out where we are, hopefully + unset cwd root + if [[ -f CVS/Repository ]]; then + cwd=$(/dev/null | awk '/^head:/{print $2}') + elif [[ -d .svn ]]; then + frev=$(svn info "$f" 2>/dev/null | awk '/^Revision:/{print $2}') + fi + ;; + esac + [[ -n ${frev} ]] || continue + + # Here is the simple URL to view it + echo "${url}/${fwd:+$fwd/}${green}${f}${off}?rev=${frev}&view=markup" + + # Also supply a diff URL if possible + if [[ ${frev##*.} -gt 1 ]]; then + orev=( ${frev//./ } ) # convert to array + (( orev[${#orev[@]}-1]-- )) # decrement the last element + orev=${orev[*]} # convert to string + orev=${orev// /.} # revert spaces to dots + diffs="${diffs:+$diffs +}${url}/${fwd:+$fwd/}${blue}${f}${off}?r1=${orev}&r2=${frev}" + fi +done + +if [[ -n ${diffs} ]]; then + echo "${diffs}" +fi + +# vim:set expandtab sw=4 smarttab: diff --git a/gentoolkit-dev/src/eviewcvs/eviewcvs.pod b/gentoolkit-dev/src/eviewcvs/eviewcvs.pod new file mode 100644 index 0000000..b4403c8 --- /dev/null +++ b/gentoolkit-dev/src/eviewcvs/eviewcvs.pod @@ -0,0 +1,48 @@ +=head1 NAME + +eviewcvs - Gentoo: generate viewcvs URLs + +=head1 SYNOPSIS + +eviewcvs [ I ] + +=head1 DESCRIPTION + +This tool generates a list of viewcvs URLs based on the files listed, or all the +files in the current directory if the file list is omitted. The first part of +the output, hilighted in green, is the simple URLs to view the files. The +second part of the output, hilighted in blue, is the URLs to view the diffs +against the previous revision. + +=head1 OPTIONS + +Presently eviewcvs is simple enough that it supplies no options. +Probably I'll add B<--help> and B<--version> in the future, but for +now it's enough to track the gentoolkit version. + +=head1 EXAMPLES + +To generate viewcvs URLs for a given file: + + $ eviewcvs package.mask + http://www.gentoo.org/cgi-bin/viewcvs.cgi/profiles/package.mask?rev=1.3716&content-type=text/vnd.viewcvs-markup + http://www.gentoo.org/cgi-bin/viewcvs.cgi/profiles/package.mask?r1=1.3715&r2=1.3716 + +To generate viewcvs URLs for all files in a directory: + + $ cd portage/net-misc/keychain + $ eviewcvs + http://sources.gentoo.org/viewcvs.py/gentoo-x86/net-misc/keychain/ChangeLog?rev=1.54&view=markup + http://sources.gentoo.org/viewcvs.py/gentoo-x86/net-misc/keychain/Manifest?rev=1.86&view=markup + http://sources.gentoo.org/viewcvs.py/gentoo-x86/net-misc/keychain/keychain-2.6.1.ebuild?rev=1.3&view=markup + http://sources.gentoo.org/viewcvs.py/gentoo-x86/net-misc/keychain/keychain-2.6.2.ebuild?rev=1.1&view=markup + http://sources.gentoo.org/viewcvs.py/gentoo-x86/net-misc/keychain/metadata.xml?rev=1.3&view=markup + http://sources.gentoo.org/viewcvs.py/gentoo-x86/net-misc/keychain/ChangeLog?r1=1.53&r2=1.54 + http://sources.gentoo.org/viewcvs.py/gentoo-x86/net-misc/keychain/Manifest?r1=1.85&r2=1.86 + http://sources.gentoo.org/viewcvs.py/gentoo-x86/net-misc/keychain/keychain-2.6.1.ebuild?r1=1.2&r2=1.3 + http://sources.gentoo.org/viewcvs.py/gentoo-x86/net-misc/keychain/metadata.xml?r1=1.2&r2=1.3 + +=head1 AUTHOR + +This tool was written by Aron Griffis . Bugs +found should be filed against me at http://bugs.gentoo.org/ diff --git a/gentoolkit-dev/src/imlate/Makefile b/gentoolkit-dev/src/imlate/Makefile new file mode 100644 index 0000000..dd88d2b --- /dev/null +++ b/gentoolkit-dev/src/imlate/Makefile @@ -0,0 +1,18 @@ +# Copyright 1999-2009 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +include ../../makedefs.mak + +.PHONY: all + +all: + +dist: + mkdir -p ../../$(distdir)/src/imlate/ + cp Makefile imlate imlate.1 ../../$(distdir)/src/imlate/ + +install: all + install -m 0755 imlate $(bindir)/ + install -m 0644 imlate.1 $(mandir)/ + diff --git a/gentoolkit-dev/src/imlate/imlate b/gentoolkit-dev/src/imlate/imlate new file mode 100755 index 0000000..ed019cc --- /dev/null +++ b/gentoolkit-dev/src/imlate/imlate @@ -0,0 +1,484 @@ +#!/usr/bin/python + +# Copyright 1999-2009 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +# author: Christian Ruppert + +VERSION = "0.0.4" + +# works just with stable keywords! +MAIN_ARCH = "auto" # can be overridden by -m ARCH +TARGET_ARCH = "auto" # can be overridden by -t ARCH +# auto means e.g.: +# MAIN_ARCH = amd64 +# TARGET_ARCH = ~amd64 +# That will show you general stable candidates for amd64. +# The arch will be taken from your portage settings (e.g. make.conf). + +################################ +# do not change anything below # +################################ + +from os.path import join, basename +from sys import stderr, stdout +from os import stat +from time import time +from xml.dom import minidom, NotFoundErr +from xml.parsers.expat import ExpatError +# TODO: just import needed stuff to safe memory and maybe use "as foo" +import portage +import portage.versions + +if __name__ == "__main__": + from optparse import OptionParser + from time import gmtime, strftime + +# portage < 2.1.6 needs portage_const instead of portage.const, +# which is not the problem... +# the problem is the keyword handling (ACCEPT_KEYWORDS) +# portage < 2.1.6 does not support -* +# but -* is needed to ensure that we just check for arch +if portage.versions.vercmp(portage.VERSION, "2.1.6") < 0: + raise StandardError, "imlate requires portage >=2.1.6" + +# override/change portage module settings +def _portage_settings( var, value, settings = None ): + if not settings: + settings = portage.settings + + settings.unlock() + settings[var] = value + # backup_changes is very important since it can cause trouble, + # if we do not backup our changes! + settings.backup_changes( var ) + settings.lock() + +# add stuff to our imlate dict +def _add_ent( imlate, cat, pkg, ver, our_ver ): + if not cat in imlate.keys(): + imlate[cat] = {} + if not pkg in imlate[cat].keys(): + imlate[cat][pkg] = [] + + imlate[cat][pkg].append( ver ) + imlate[cat][pkg].append( our_ver ) + + return imlate + +def _fill( width, line, fill = " " ): + while len( line ) < width: + line = "%s%s" % ( str( line ), str( fill ) ) + return line + +# create a hopefully pretty result +def show_result( conf, pkgs ): + # X - len(colX) = space to fill + col1 = 40 + col2 = 20 + + _header = "%s candidates for 'gentoo' on '%s'" + _helper = "category/package[:SLOT] our version best version" + _cand = "" + header = "" + + if conf["FILE"] == "stdout": + out = stdout + elif conf["FILE"] == "stderr": + out = stderr + else: + out = open( conf["FILE"], "w" ) + + if conf["STABLE"] and conf["KEYWORD"]: + _cand = "%i Stable and %i Keyword(~)" % ( conf["STABLE_SUM"], + conf["KEYWORD_SUM"] ) + elif conf["STABLE"]: + _cand = "%i Stable" % conf["STABLE_SUM"] + elif conf["KEYWORD"]: + _cand = "%i Keyword(~)" % conf["KEYWORD_SUM"] + + header = _header % ( _cand, conf["MAIN_ARCH"] ) + + print >> out, "Generated on: %s" % conf["TIME"] + print >> out, _fill( len( header ), "", "=" ) + print >> out, header + print >> out, _fill( len( header ), "", "=" ) + print >> out + + print >> out, _helper + print >> out, _fill( len( _helper ), "", "-" ) + + for cat in sorted( pkgs.keys() ): + print >> out, "%s/" % cat + for pkg in sorted( pkgs[cat].keys() ): + print >> out, "%s%s%s" % ( _fill( col1, ( " %s" % pkg ) ), + _fill( col2, pkgs[cat][pkg][1] ), + pkgs[cat][pkg][0] ) + + if conf["FILE"] != "stdout": + out.close() + +def _get_metadata(metadata, element, tag): + values = [] + + try: + metadatadom = minidom.parse(metadata) + except ExpatError, e: + raise ExpatError("%s: %s" % (metadata, e,)) + + try: + elements = metadatadom.getElementsByTagName(element) + if not elements: + return values + except NotFoundErr: + return values + + try: + for _element in elements: + node = _element.getElementsByTagName(tag) + + if tag == "herd" and (not node or not node[0].childNodes): +# print >> stderr, "'%s' is missing a tag or it is empty," % metadata +# print >> stderr, "please file a bug at https://bugs.gentoo.org and refer to http://www.gentoo.org/proj/en/devrel/handbook/handbook.xml?part=2&chap=4" + values.append("no-herd") + continue + + values.append(node[0].childNodes[0].data) + except NotFoundErr: + raise NotFoundErr("%s: Malformed input: missing 'flag' tag(s)" % (metadata)) + + metadatadom.unlink() + return values + +def is_maintainer(maintainer, metadata): + data = [] + + if maintainer == None: + return True + + mtainer = maintainer.split(",") + + data = _get_metadata(metadata, "maintainer", "email") + + if not data and len(maintainer) == 0: + return True + elif not data and len(maintainer) > 0: + return False + else: + for addy in data: + for contact in mtainer: + if addy == contact: + return True + if addy.startswith(contact): + return True + return False + +def is_herd(herd, metadata): + data = [] + + if herd == None: + return True + + hrd = herd.split(",") + data = _get_metadata(metadata, "pkgmetadata", "herd") + + if not data and len(herd) == 0: + return True + elif not data and len(herd) > 0: + return False + else: + for hd in data: + for hd2 in hrd: + if hd == hd2: + return True + if hd.startswith(hd2): + return True + + return False + + +# fetch a list of arch (just stable) packages +# -* is important to be sure that just arch is used +def get_packages( conf ): + _pkgs = {} + + _portage_settings( "ACCEPT_KEYWORDS", ( "-* %s" % str( conf["TARGET_ARCH"] ) ), + conf["portdb"].settings ) + + for cp in conf["portdb"].dbapi.cp_all(): + cpvrs = [] + slots = {} + + if conf["USER_PKGS"]: + if not cp in conf["USER_PKGS"]: + continue + + # None is important to match also on empty string + if conf["MAINTAINER"] != None: + if not is_maintainer(conf["MAINTAINER"], join(conf["PORTDIR"], cp, "metadata.xml")): + continue + if conf["HERD"] != None: + if not is_herd(conf["HERD"], join(conf["PORTDIR"], cp, "metadata.xml")): + continue + + cpvrs = conf["portdb"].dbapi.match( cp ) + + for cpvr in cpvrs: + slot = conf["portdb"].dbapi.aux_get( cpvr, ["SLOT"] )[0] + if not slot in slots: + slots[slot] = [] + slots[slot].append(cpvr) + + for slot in sorted(slots): + cpvr = portage.versions.best( slots[slot] ) + + if cpvr: + ( cat, pkg, ver, rev ) = portage.versions.catpkgsplit( cpvr ) + + if not cat in _pkgs.keys(): + _pkgs[cat] = {} + if not pkg in _pkgs[cat].keys(): + _pkgs[cat][pkg] = [] + + if rev != "r0": + ver = "%s-%s" % ( ver, rev ) + + _pkgs[cat][pkg].append( ver ) + + return _pkgs + +# compare get_packages() against MAIN_ARCH +def get_imlate( conf, pkgs ): + _portage_settings( "ACCEPT_KEYWORDS", ( "-* %s" % str( conf["MAIN_ARCH"] ) ), + conf["portdb"].settings ) + + stable = str( conf["MAIN_ARCH"].lstrip("~") ) + testing = "~%s" % stable + exclude = "-%s" % stable + exclude_all = "-*" + + imlate = {} + + for cat in sorted( pkgs.keys() ): + for pkg in sorted( pkgs[cat].keys() ): + for vr in pkgs[cat][pkg]: + cpvr = "" + abs_pkg = "" + kwds = "" + our = "" + our_ver = "" + mtime = 0 + slot = 0 + + # 0 = none(default), 1 = testing(~arch), 2 = stable(arch), + # 3 = exclude(-arch), 4 = exclude_all(-*) + # -* would be overridden by ~arch or arch + kwd_type = 0 + + cpvr = "%s/%s-%s" % ( cat, pkg, vr ) + + # absolute ebuild path for mtime check + abs_pkg = join( conf["PORTDIR"], cat, pkg, basename( cpvr ) ) + abs_pkg = "%s.ebuild" % str( abs_pkg ) + + kwds = conf["portdb"].dbapi.aux_get( cpvr, ["KEYWORDS"] )[0] + + # FIXME: %s is bad.. maybe even cast it, else there are issues because its unicode + slot = ":%s" % conf["portdb"].dbapi.aux_get( cpvr, ["SLOT"] )[0] + if slot == ":0": + slot = "" + + # sorted() to keep the right order + # e.g. -* first, -arch second, arch third and ~arch fourth + # -* -foo ~arch + # example: -* would be overridden by ~arch + for kwd in sorted( kwds.split() ): + if kwd == stable: + kwd_type = 2 + break + elif kwd == exclude: + kwd_type = 3 + break + elif kwd == exclude_all: + kwd_type = 4 + elif kwd == testing: + kwd_type = 1 + break + + # ignore -arch and already stabilized packages + if kwd_type == 3 or kwd_type == 2: + continue + # drop packages with -* and without ~arch or arch + # even if there is another version which includes arch or ~arch + if kwd_type == 4: + continue + # drop "stable candidates" with mtime < 30 days + # Shall we use gmtime/UTC here? + if kwd_type == 1: + mtime = int( ( time() - stat( abs_pkg ).st_mtime ) / 60 / 60 / 24 ) + if mtime < conf["MTIME"]: + continue + + # look for an existing stable version + our = portage.versions.best( conf["portdb"].dbapi.match( "%s/%s%s" % ( cat, pkg, slot ) ) ) + if our: + _foo = portage.versions.pkgsplit( our ) + our_ver = _foo[1] + if _foo[2] != "r0": + our_ver = "%s-%s" % ( our_ver, _foo[2] ) + else: + our_ver = "" + + # we just need the version if > our_ver + if our_ver: + if portage.versions.vercmp( our_ver, vr ) >= 0: + continue + + if kwd_type == 1 and conf["STABLE"]: + imlate = _add_ent( imlate, cat, ("%s%s" % (pkg, slot)), vr, our_ver ) + conf["STABLE_SUM"] += 1 + elif kwd_type == 0 and conf["KEYWORD"]: + conf["KEYWORD_SUM"] += 1 + imlate = _add_ent( imlate, cat, ( "~%s%s" % (pkg, slot) ), + vr, our_ver ) + + return imlate + +# fetch portage related settings +def get_settings( conf = None ): + if not isinstance( conf, dict ) and conf: + raise TypeError, "conf must be dict() or None" + if not conf: + conf = {} + + # TODO: maybe we should improve it a bit ;) + mysettings = portage.config( config_incrementals = portage.const.INCREMENTALS, local_config = False ) + + if conf["MAIN_ARCH"] == "auto": + conf["MAIN_ARCH"] = "%s" % mysettings["ACCEPT_KEYWORDS"].split(" ")[0].lstrip("~") + if conf["TARGET_ARCH"] == "auto": + conf["TARGET_ARCH"] = "~%s" % mysettings["ACCEPT_KEYWORDS"].split(" ")[0].lstrip("~") + + # TODO: exclude overlay categories from check + if conf["CATEGORIES"]: + _mycats = [] + for _cat in conf["CATEGORIES"].split(","): + _cat = _cat.strip() + _mycats.append(_cat ) + if _cat not in mysettings.categories: + raise ValueError, "invalid category for -C switch '%s'" % _cat + mysettings.categories = _mycats + + # maybe thats not necessary because we override porttrees below.. + _portage_settings( "PORTDIR_OVERLAY", "", mysettings ) + trees = portage.create_trees() + trees["/"]["porttree"].settings = mysettings + portdb = trees["/"]["porttree"] + portdb.dbapi.mysettings = mysettings + portdb.dbapi.porttrees = [portage.portdb.porttree_root] + # does it make sense to remove _all_ useless stuff or just leave it as it is? + #portdb.dbapi._aux_cache_keys.clear() + #portdb.dbapi._aux_cache_keys.update(["EAPI", "KEYWORDS", "SLOT"]) + + conf["PORTDIR"] = portage.settings["PORTDIR"] + conf["portdb"] = portdb + + return conf + + +# just for standalone +def main(): + conf = {} + pkgs = {} + + parser = OptionParser( version = "%prog " + VERSION ) + parser.usage = "%prog [options] [category/package] ..." + parser.disable_interspersed_args() + + parser.add_option( "-f", "--file", dest = "filename", action = "store", type = "string", + help = "write result into FILE [default: %default]", metavar = "FILE", default = "stdout" ) + parser.add_option( "-m", "--main", dest = "main_arch", action = "store", type = "string", + help = "set main ARCH (e.g. your arch) [default: %default]", metavar = "ARCH", default = MAIN_ARCH ) + parser.add_option( "-t", "--target", dest = "target_arch", action = "store", type = "string", + help = "set target ARCH (e.g. x86) [default: %default]", metavar = "ARCH", default = TARGET_ARCH ) + parser.add_option( "--mtime", dest = "mtime", action = "store", type = "int", + help = "set minimum MTIME in days [default: %default]", metavar = "MTIME", default = 30 ) + + # TODO: leave a good comment here (about True/False) :) + parser.add_option( "-s", "--stable", dest = "stable", action = "store_true", default = False, + help = "just show stable candidates (e.g. -s and -k is the default result) [default: True]" ) + parser.add_option( "-k", "--keyword", dest = "keyword", action = "store_true", default = False, + help = "just show keyword candidates (e.g. -s and -k is the default result) [default: True]" ) + + parser.add_option( "-M", "--maintainer", dest = "maintainer", action = "store", type = "string", + help = "Show only packages from the specified maintainer", metavar = "MAINTAINER", default = None) + + parser.add_option( "-H", "--herd", dest = "herd", action = "store", type = "string", + help = "Show only packages from the specified herd", metavar = "HERD", default = None) + +# # EXPERIMENTAL +# parser.add_option( "-e", "--experimental", dest = "experimental", action = "store_true", default = False, +# help = "enables experimental functions/features (have a look for # EXPERIMENTAL comments in the source) [default: %default]" ) + + parser.add_option( "-C", "--category", "--categories", dest = "categories", action = "store", default = None, + metavar = "CATEGORIES", + help = "just check in the specified category/categories (comma separated) [default: %default]") + + ( options, args ) = parser.parse_args() + + if len( args ) > 0: + conf["USER_PKGS"] = args + else: + conf["USER_PKGS"] = [] + + # cleanup optparse + try: + parser.destroy() + except AttributeError: + # to be at least python 2.4 compatible + del parser._short_opt + del parser._long_opt + del parser.defaults + + # generated timestamp (UTC) + conf["TIME"] = strftime( "%a %b %d %H:%M:%S %Z %Y", gmtime() ) + + # package counter + conf["KEYWORD_SUM"] = 0 + conf["STABLE_SUM"] = 0 + + if not options.main_arch in portage.archlist and options.main_arch != "auto": + raise ValueError, "invalid MAIN ARCH defined!" + if not options.target_arch in portage.archlist and options.target_arch != "auto": + raise ValueError, "invalid TARGET ARCH defined!" + + conf["MAIN_ARCH"] = options.main_arch + conf["TARGET_ARCH"] = options.target_arch + + conf["FILE"] = options.filename + conf["MTIME"] = options.mtime + + if not options.stable and not options.keyword: + conf["STABLE"] = True + conf["KEYWORD"] = True + else: + conf["STABLE"] = options.stable + conf["KEYWORD"] = options.keyword + +# conf["EXPERIMENTAL"] = options.experimental + conf["CATEGORIES"] = options.categories + + conf["MAINTAINER"] = options.maintainer + conf["HERD"] = options.herd + + # append to our existing + conf = get_settings( conf ) + pkgs = get_packages( conf ) + pkgs = get_imlate( conf, pkgs ) + + show_result( conf, pkgs ) + +if __name__ == "__main__": + main() + diff --git a/gentoolkit-dev/src/imlate/imlate.1 b/gentoolkit-dev/src/imlate/imlate.1 new file mode 100644 index 0000000..d4a1dc2 --- /dev/null +++ b/gentoolkit-dev/src/imlate/imlate.1 @@ -0,0 +1,48 @@ +.TH "imlate" "1" "0.0.4" "Christian Ruppert" "gentoolkit-dev" +.SH "NAME" +.LP +imlate \- Displays candidates for keywords for an architecture based upon a target architecture. +.SH "SYNTAX" +.LP +imlate [options] + + +.SH "OPTIONS" +.TP +.B \-\-version +show program's version number and exit +.TP +.B \-h, \-\-help +show this help message and exit +.TP +.B \-f FILE, \-\-file=FILE +write result into FILE [default: stdout] +.TP +.B \-m ARCH, \-\-main=ARCH +set main ARCH (e.g. your arch) [default: amd64] +.TP +.B \-t ARCH, \-\-target=ARCH +set target ARCH (e.g. x86) [default: x86] +.TP +.B \-\-mtime=MTIME +set minimum MTIME in days [default: 30] +.TP +.B \-s, \-\-stable +just show stable candidates (e.g. \-s and \-k is the default result) [default: True] +.TP +.B \-k, \-\-keyword +just show keyword candidates (e.g. \-s and \-k is the default result) [default: True] +.TP +.B \-M MAINTAINER, \-\-maintainer=MAINTAINER +Show only packages from the specified maintainer +.TP +.B \-H HERD, \-\-herd=HERD +Show only packages from the specified herd +.TP +.B \-C CATEGORIES, \-\-category=CATEGORIES, \-\-categories=CATEGORIES +just check in the specified category/categories (comma separated) [default: none] +.SH "AUTHORS" +.LP +Christian Ruppert +.SH "BUGS" +Please report any bugs to http://bugs.gentoo.org diff --git a/gentoolkit/AUTHORS b/gentoolkit/AUTHORS new file mode 100644 index 0000000..c8b89aa --- /dev/null +++ b/gentoolkit/AUTHORS @@ -0,0 +1,28 @@ +* gentoolkit + Original author: Karl Trygve Kalleberg + Library additions and refactor: Douglas Anderson + Current maintainer: Paul Varner + +* eclean + Original author: Thomas de Grenier de Latour (tgl) + +* epkginfo + Author: Ned Ludd + earch: Eldad Zack + metadata: Olinger + +* equery + Original author: Karl Trygve Kalleberg + 0.3.0 author: Douglas Anderson + +* eread + Original author: Donnie Berkholz + Updated by: Uwe Klosa + +* euse + Original perl version: Arun Bhanu + New bash version: Marius Mauch + +* revdep-rebuild + Original author: Stanislav Brabec + Rewrite author: Michael A. Smith diff --git a/gentoolkit/COPYING b/gentoolkit/COPYING new file mode 100644 index 0000000..60549be --- /dev/null +++ b/gentoolkit/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/gentoolkit/CREDITS b/gentoolkit/CREDITS new file mode 100644 index 0000000..3f9d6f0 --- /dev/null +++ b/gentoolkit/CREDITS @@ -0,0 +1,16 @@ + + This is an incomplete list of people who have contributed non- + trivial patches to gentoolkit-0.3.0 and later, in the spirit of + the Linux kernel CREDITS file. It is sorted alphabetically by + name (N). Other fields are email (E) and description (D). + We'd like to thank: + +------------------------------------------------------------------------------- + +N: Brian Dolbec +E: dol-sen@users.sourceforge.net +D: Separating dependency gathering functionality from output in depends.py. + + + +# vim: set ts=8 sw=8 tw=80: diff --git a/gentoolkit/ChangeLog b/gentoolkit/ChangeLog new file mode 100644 index 0000000..85f41f8 --- /dev/null +++ b/gentoolkit/ChangeLog @@ -0,0 +1,864 @@ +2009-12-17: Paul Varner + * revdep-rebuild: Fix revdep-rebuild to properly honor + PORTAGE_NICENESS as an incremental to the current nice level (Bug + 297174). + +2009-12-08: Paul Varner + * gentoolkit: Merge rev 113 from djanderson's genscripts repo + +2009-10-30: Christian Ruppert + * revdep-rebuild: Speedup portageq queries. Include FuzzyRay's patch to + respect EMERGE_DEFAULT_OPTS. + +2009-10-27: Christian Ruppert + * revdep-rebuild: Use realpath in get_file_owner to be able to get the + package containing e.g. /lib/libreadline.so.6 on amd64, fixes bug 280341. + +2009-10-27: Christian Ruppert + * revdep-rebuild.1: Fix bug 281050, thanks to Jesús Guerrero + . + +2009-10-26: Christian Ruppert + * euse: Don't add an additional new line at the end of file. + * equery.1: Fix bug 248844, thanks to J M W . + +2009-08-18: Robert Buchholz + * glsa-check: Remove 'new' target from glsa-list, everyone + should use 'affected' or 'all' + * glsa-check: fix getminupgrade API doc and TypeError (Bug 281101) + * glsa-check: Make --pretend output in glsa-check nicer. + Add colors and fix linebreaks. + +2009-06-22: Paul Varner + * glsa-check: Fix traceback with glsa-check -f (Bug 275105) + +2009-06-05: Paul Varner + * epkginfo: Add patch from Sebastian Mingramm to Make epkginfo slot + aware and only print keywords for the highest visible versions in each + slot. (Bug 232635) + +2009-05-20: Paul Varner + * All: Convert from using /etc/gentoolkit-version to + /usr/share/gentoolkit/VERSION + +2009-05-20: Paul Varner + * glsa-check: Add patches from Robert Buchholz to do the following: + Handle unicode encoding better, python tweaks to speedup execution, + change behavior of getMinUpgrade, restructure system affection + detection, and do not inject GLSAs into the checkfile when fixing. + +2009-05-07: Paul Varner + * equery: Add patch from djanderson to make meta get and check package + dirs in a manner similar to other gentoolkit scripts and fix + some docstrings. (Bug 268895) + +2009-05-05: Paul Varner + * equery: Added modular rewrite from djanderson + * gentoolkit: Added modular rewrite from djanderson + * All: converted to setup.py build system + +2009-04-30: Paul Varner + * revdep-rebuild: Add patch from loki_val to check -l dependencies in + .la files (Bug #267898) + +2009-04-24: Paul Varner + * ekeyword: Fix to handle multiline KEYWORDS (Bug #267250) + +2009-01-08: Paul Varner + * equery: Fix package.py to account for PORTDIR being a symbolic link + when checking if a package is in an overlay. (Bug #253968) + +2008-11-25: Paul Varner + * revdep-rebuild: Fixes for non-linux Gentoo systems. Add patch from + igli to fix find command to comply with POSIX. Change awk calls to + gawk. + +2008-11-11: Paul Varner + * echangelog: Add --strict option (Bug 246242). + * echangelog: Fix processing of virtual category (Bug 179530) + +2008-09-17: Paul Varner + * euse: Fix check_sanity function to use get_all_make_defaults + function when checking for the make.defaults files in the profile. + (Bug #233651) + +2008-09-03: Paul Varner + * equery: Fix depgraph function to print out dependencies that don't + resolve to a package (Bug #236492) + +2008-08-26: Paul Varner + * glsa-check: Fix has_key() deprecation message. (Bug #232797) + * revdep-rebuild: Update fix for Bug 232270 to utilize better patch + from Ian Abbott. + +2008-08-22: Paul Varner + * gentoolkit: Fix find_packages and find_installed_packages to print + a warning instead of a traceback when an InvalidAtom exception occurs. + (Bug #234358) + * equery: Fix equery belongs to strip multiple slashes from path + names. (Bug #234584) + +2008-07-24: Paul Varner + * equery: Fix equery check to convert mtime to an integer so that + comparisions always work. Thanks to Alexey Parshin for discovering the + problem and providing a patch. (Bug 232803) + +2008-07-22: Paul Varner + * gentoolkit: Fix gentoolkit.split_package_name to work with + newer portage.catpkgsplit that now returns a tuple instead of a + list. (Bug 232599) + +2008-07-21: Paul Varner + * revdep-rebuild: Fix filtering of masked paths from SEARCH_DIRS + variable. (Bug 232270) + +2008-07-18: Paul Varner + * equery: Remove prefixed '+/-' signs from IUSE for equery uses + command. (Bug 232019) + +2008-07-09: Paul Varner + * revdep-rebuild: Fix revdep-rebuild to use TMPDIR instead of HOME for + temporary files. (Bug 203414) + * revdep-rebuild: Fix revdep-rebuild to not evaluate broken objects + multiple times. (Bug 220761) + +2008-07-09: Paul Varner + * gentoolkit: Fix gentoolkit to work without thread support in + python. (Bug 223255) + +2008-06-16: Marius Mauch + * euse: Add support for multi-parent profiles, account for missing + final newline in make.conf + +2008-03-19: Paul Varner + * glsa-check: Fix imports so mail functionality in glsa-check works + with python versions less than 2.5 (Bug 211706) + +2008-03-13: Paul Varner + * euse: Add --info-installed option from patch provided by Andreas + Waidler. (Bug 212573) + +2008-03-13: Paul Varner + * revdep-rebuild: Fix trying to emerge an empty list of packages. (Bug + 213294) + +2008-02-28: Paul Varner + * gentoolkit: Fix traceback when accessing the portage + db. (Bug #211716) + +2008-02-21: Paul Varner + * revdep-rebuild: "Use /etc/init.d/functions.sh instead of + /sbin/functions.sh. (Bug 210940) + +2008-02-18: Paul Varner + * revdep-rebuild: Apply patch to allow combined short options. + (Bug 188343) + * revdep-rebuild: Don't duplicate broken file output. (Bug 201319) + * revdep-rebuild: unset GREP_OPTIONS to prevent problems with grep. + (Bug 189257) + * revdep-rebuild: Apply patch to prevent false matches of object names. + (Bug 196460) + * revdep-rebuild: Apply patch to better handle masked and removed + packages. (Bug 205227) + * revdep-rebuild: Filter SEARCH_DIRS_MASK paths from SEARCH_DIRS. + (Bug 194993) + * revdep-rebuild: Apply patch for revdep-rebuild portable find function. + (Bug 194234) + * equery: Fix equery list to not generate an internal portage error when + fed input with too many slashes. (Bug 119806) + * equery: Assume the -p flag when equery list -I is used by itself. + (Bug 106278) + + +2007-10-09: Marius Mauch + * glsa-check: Change "affected" target so it's based on "new" instead of + "all" (IOW: exclude already applied/injected GLSAs). + +2007-10-05: Marius Mauch + * glsa-check: Use UTF-8 strings to avoid EncodeErrors if a GLSA contains + non-ascii characters (bug #162493) + +2007-09-19: Paul Varner + * epkginfo: Fix handling of KEYWORDS="" in an ebuild. (Bug #193108) + * revdep-rebuild: Fix handling of /var/db/pkg when it is a symbolic + link. (Bug #179392) + +2007-09-18: Paul Varner + * equery: Apply patch from Carlo Marcelo Arenas Belon to fix incorrect + display of masking status in list command. (Bug #188678) + * revdep-rebuild: Correctly handle LD_LIBRARY_MASK when checking for + "no version information" errors/ (Bug #182882) + +2007-09-12: Paul Varner + * eclean: Fix processing of the long arguments to work correctly. (Bug + #192345) + * revdep-rebuild: Correctly handle the case where an ebuild no longer + exists for a package (Bug #188918) + * eread: Fix eread to not accept invalid input for file selection. + (Bug #189994) + +2007-08-08: Paul Varner + * revdep-rebuild: Fix progress bar to only update when there is a + change (Bug #186945) + * revdep-rebuild: Ensure that we source functions.sh before calling + ewarn, etc. + +2007-08-06: Paul Varner + * revdep-rebuild: Fix processing of .la files (Bug #187453) + * revdep-rebuild: Add -X option back for backwards compatibilty (Bug + #187366) + +2007-07-30: Paul Varner + * revdep-rebuild: Fix grepping for non-existant package-owners file + (Bug #187141) + +2007-07-05: Paul Varner + * revdep-rebuild: Added refactored revdep-rebuild from Michael A. + Smith (Bug #184042) + +2007-05-30: Marius Mauch + * glsa-check: check SLOT when selecting and displaying upgrades + * glsa-check: new --emergelike option to use the best version + within the same SLOT instead of the one with the smallest delta. + * glsa-check: prefer visible upgrades to masked upgrades + * equery: check for and warn about unknown options (bug 119674) + * equery,eclean,glsa-check,epkginfo: Only add /usr/lib/portage/pym + to python search path when necessary + +2007-05-21: Paul Varner + * echangelog: Add patch from genstef to fix issues from Bug 176337 + +2007-05-11: Paul Varner + * eclean: Changed permission check to see if you are either root or + belong to the portage group (Bug #177385) + +2007-05-11: Paul Varner + * eclean: Updated eclean to not delete metadata.dtd by default (Bug + #176951) + +2007-05-10: Marius Mauch + * euse: Fix incorrect flag status display when a flag appears multiple + times in a single location + +2007-04-25: Paul Varner + * echangelog: Re-added subversion/git support with fixes from genstef. + (Bug #136048) + +2007-04-24: Paul Varner + * etcat: Removed from Makefile (deprecated since 04-25-2005) + * qpkg: Removed from Makefile (deprecated since 04-25-2005) + +2007-04-23: Paul Varner + * genpkgindex, epkginfo: Move to /usr/bin from + /usr/lib/gentoolkit/bin (Bug #175759) + +2007-04-10: Paul Varner + * equery: Change equery uses to command to display the best matching + uninstalled package version if an uninstalled package is specified. + Changed the meaning of -a to mean display all versions. (Bug #152325) + +2007-04-01: Alec Warner + * eread: Fix path and fully qualified paths (Bug #172969) + +2007-03-31: Paul Varner + * equery: Fix traceback in equery which (Bug #134053) + +2007-03-29: Paul Varner + * gentoolkit: Change package.get_???_deps() methods to try the portage + tree first, since emerge always uses the portage tree for dependencies. + (Bug #164678) + +2007-03-29: Paul Varner + * equery: Convert deprecated strings functions to str methods (Bug + #172694) + +2007-03-25: Paul Varner + * echangelog: Remove subversion/git patch due to many bugs. + +2007-03-18 Paul Varner + * revdep-rebuild: Change --no-color to --nocolor for consistency + within gentoolkit. (Bug #165165) + +2007-03-16 Paul Varner + * gentoolkit: Fix typo in package.py (Bug #168347) + +2007-03-15 Paul Varner + * equery: Fix equery check to not fail for symlinks prefixed with ./ + (Bug #170702) + +2007-03-14 Paul Varner + * equery: Trim trailing slash from query for equery belongs command + (Bug #170981) + +2007-03-13 Paul Varner + * revdep-rebuild: Fix bug with --package-names option not rebuilding + packages (Bug #169761) + +2007-03-10 Paul Varner + * equery: Add --depth option to equery depgraph to limit the depth of + the dependency graph. (Bug #115807) + +2007-03-09 Paul Varner + * revdep-rebuild: Add support to detect "no version information + available" message from ldd (Bug #169973) + +2007-03-08 Paul Varner + * equery: Improved handling of KeyError in equery depends command + (Bug #169929) + +2007-03-07 Paul Varner + * revdep-rebuild: Change ordering algorithm to use --deep instead of + --emptytree on the advice of zmedico + +2007-02-26 Marius Mauch + * glsa-check: Display access information in verbose list mode (bug 168482) + +2007-02-19 Paul Varner + * echangelog: Updated to support git and subversion (Bug #136048) + +2007-01-10 Paul Varner + * epkgmove: removed epkgmove command due to popular demand. (Bug + 161360) + * gensync: Deprecated gensync in favor of app-portage/layman (multiple + bugs) + +2007-01-02 Paul Varner + * equery: Fix equery depends --indirect command. (Bug #124552) + +2006-12-31 Paul Varner + * equery: Reworked equery depends command to be more accurate. + +2006-12-13 Paul Varner + * revdep-rebuild: Fix handling of /etc/portage/package.mask (Bug + #158025) Thanks to Wolfram Schlich for the patch. + +2006-12-12 Paul Varner + * equery: Add --tree option to equery files command. (Bug #62898) + Thanks to scope for the patch. + +2006-12-06 Paul Varner + * equery: Modify equery size command to work like the equery list + command for pkgspec arguments + +2006-11-27 Paul Varner + * eclean: Fix typographical error in help and man page. (Bug #156243) + +2006-10-11 Paul Varner + * equery: Fix fileAsStr to understand device files. + (http://forums.gentoo.org/viewtopic-p-3639575.html) + +2006-10-07 Paul Varner + * euse: Fix quoting bug in get_real_path() (Bug #150335). + +2006-09-21 Paul Varner + * eread: Add eread script for reading and managing portage ELOG files. + Thanks to Donnie Berkholz for writing this. + +2006-09-03 Paul Varner + * revdep-rebuild: Remove unused environment variables before calling + emerge (Bug #142074). Check for permissions to write temporary files + (Bug #142308) + +2006-08-12 Marius Mauch + * glsa-check: Add new --mail option to send out vulnerability reports + (output of --list plus --dump for each matched glsa as attachment), + using elog configuration. + +2006-07-31 Paul Varner + * euse: Replace calls to readlink with bash function for Gentoo/ALT + compatibility. (Bugs #140477, #128960) + +2006-07-28 Paul Varner + * revdep-rebuild: Fix revdep-rebuild to correctly handle --ask being + passed to emerge. Thanks to Sal Gonzalez for + the patch. (Bug #37485) + +2006-07-07 Paul Varner + * revdep-rebuild: Rename --no-path to --no-ld-path and change + functionality to not set LD_LIBRARY_PATH. This fixes bug #96946 as + well as bug #137313 + * revdep-rebuild: Apply patch from truedfx to fix bug #38751 + +2006-07-05 Paul Varner + * revdep-rebuild: Add --no-path option to revdep-rebuild for bug + #137313 + +2006-06-25 Marius Mauch + * glsa-check: update cve code for bug 128115 + +2006-06-14 Paul Varner + * gentoolkit: Fix package.py to honor $ROOT. (bug #136811) + +2006-05-22 Paul Varner + * revdep-rebuild: Use qfile to locate packages if portage-utils is + installed (Bug #128374). Be even more paranoid about extra slashes in + path names (Bug #128108). Remove unused code. Update configuration + section of manpage (Bug #126038). + +2006-04-02 Paul Varner + * revdep-rebuild: Remove double-slashes from path names (Bug #128108) + +2006-04-01 Paul Varner + * revdep-rebuild: Add fix so that packages no longer in the tree cause + errors (Bug #128174). Fix case where masked packages cause + revdep-rebuild to not rebuild any packages (Bug #128085) + +2006-03-29 Marius Mauch + * euse: Add support for special %active argument as placeholder for + active use flags + +2006-03-26 Aron Griffis + * echangelog: Don't warn about missing ebuilds when updating + copyrights #120061 + +2006-03-25 Aron Griffis + * eviewcvs: Update for sources.gentoo.org, add subversion support + +2006-03-21 Paul Varner + * revdep-rebuild: Fix to clear environment before portageq call. (Bug + #126038) + +2006-03-08 Paul Varner + * genpkgindex: Add binary package indexing utility. (Bug 82132) + +2006-03-01 Paul Varner + * gentoolkit: Fix depends parsing to properly handle conjunction. (bug + #123725). Thanks to tgl for the patch. + * gentoolkit: Added function to get post-merge dependencies (PDEPEND) + (bug #99191) + * gentoolkit: Change get_dependency functions to always use the + portage tree + * equery: Added post-merge dependencies to depends and depgraph + actions. (bug #99191) + * equery: Removed requirement for package to be installed to use + depgraph action. + +2006-02-16 Marius Mauch + * euse: add/remove use flags even if there is no USE= statement in make.conf + (bug #95432) + +2006-02-16 Marius Mauch + * glsa-check: Fix bug causing the wrong summary to be displayed + for --test --verbose (bug #123084) + +2006-02-06 Paul Varner + * revdep-rebuild: Reset PORTAGE_NICENESS, so that emerge is not niced + twice. Thanks to Lukas Reck for the patch. (Bug 121482) + +2006-01-24 Marius Mauch + * glsa-check: Use vbd information in verbose list mode (patch by solar) + +2006-01-18 Paul Varner + * revdep-rebuild: Add capability to check libtool .la files for + non-existant references. + +2006-01-06 Paul Varner + * revdep-rebuild: Fix revdep-rebuild to play nicely with portage-2.1 + (Bug 118124) + +2005-12-28 Paul Varner + * revdep-rebuild: Fix to automatically determine how to call find (Bug 111203) + +2005-12-19 Paul Varner + * eclean: Add regular expression matching for exclude files (Bug 114365) + +2005-12-13 Paul Varner + * equery: Fix USE flag parsing. (Bug 115294) + +2005-12-07 Paul Varner + * revdep-rebuild: Fix revdep-rebuild to work with findutils-4.2.27. + (bug 111203) + * equery: Added note to error message about quoting redirection + characters. (Bug 113423) + * gentoolkit: Removed python-config call from make file. (Bug 113386) + +2005-11-23 Paul Varner + * equery: Changed default behavior for equery list to search for + partial name matches. Added equery list examples to the equery man + page. (Bugs 113032, 113134) + +2005-11-15 Marius Mauch + * glsa-check: Changed several messages to stderr instead of stdout + * glsa-check: Added new --cve option as requested by solar (bug 98589) + * glsa-check: Added support for a EMERGE_OPTS env variable to modify the emerge call of glsa-check --fix + * glsa-check: Added a new target "affected" + * glsa-check: Removed the warning message as it is now pretty much tested + * glsa-check: Show GLSA title on --test if --verbose is also used + +2005-11-11 Paul Varner + * equery: Added sanity check to equery files (Bug 75983) + * equery: Fix string matching for equery depends (Bug 85653) + * gentoolkit: Fix package.size() to report correct size for symbolic + links (Bug 90384) + * equery: Fix equery depgraph to show all dependencies (Bug 99191) + * equery: Fix traceback with invalid regular expression for equery + list (Bug 109392) + +2005-11-04 Paul Varner + * equery: Fix equery belongs to correctly work when passed an argument + list of multiple files (Bug 111501) + +2005-11-02 Paul Varner + * revdep-rebuild: Fix to work with findutils-4.2.25 (Bug 111203) + +2005-10-18 Paul Varner + * equery: Make equery look at both DEPEND and RDEPEND for dependencies + * gentoolkit: Fix _parse_deps to understand || syntax (Bug 101377) + +2005-10-14 Paul Varner + * equery: Add qpkg --dups functionality to equery list command (bug + 109156) + +2005-10-13 Paul Varner + * equery: equery depgraph shows USE flags (Bug 74554) + * equery: equery should properly parse use.local.desc (Bug 74569) + * equery: equery list escapes regular expressions (Bug 77113) + * equery: equery uses displays flags correctly (Bug 86633) + * equery: equery -N option to disable pipe detection (Bug 90046) + * equery: equery list properly detects version string (Bug 91286) + * equery: equery belongs now requires a filename (Bug 94618) + * equery: equery files over a pipe only prints file names (Bug 100148) + * revdep-rebuild: Fix typo in man page (Bug 109147) + +2005-09-25 Paul Varner + * revdep-rebuild: Update to read configuration files from + /etc/revdep-rebuild + +2005-09-23 Paul Varner + * equery: Sort output from equery list (bug 67152) + * equery: Update man page (Bugs 73893, 74944) + * equery: equery which returns best-visible ebuild (bug 78687) + * equery: equery --quiet is actually quiet (bug 78921) + * equery: Fixed typo in equery -h (bug 82352) + * gentoolkit: gentoolkit now uses a single portage.config object (bug + 90680) + * equery: equery uses returns unique, sorted list (bug 91623) + * equery: equery always honors nocolor flag and settings (bug 98634) + +2005-09-08 Paul Varner + * eclean: Inital commit of eclean 0.4.1 from Thomas de Grenier de + Latour (tgl) (bug 33877) + +2005-06-28 Paul Varner + * revdep-rebuild: Revert fix for bug 93574 as it can cause packages to + be missed. (bug 97171) + +2005-06-07 Paul Varner + * revdep-rebuild: Delete temporary files if the environment does not + match the previous environment (bug 95274) + +2005-06-05 Paul Varner + * revdep-rebuild: Imported revdep-rebuild release from bug 62644 + * revdep-rebuild: Major changes to the functionality when using + --package-names/-X The script should now update slotted packages + correctly. (bug 22161) + * revdep-rebuild: Customizable searching controlled through environment + variables. This removes the need for end users to directly modify the + script. (bugs 32276, 38011, 59803) + * revdep-rebuild: The directories to search are no longer hard coded + into the script. revdep-rebuild now determines the directories to + search based upon /etc/profile.env and /etc/ld.so.conf. (bugs 32276, + 38011, 89781) + * revdep-rebuild: --ignore option to ignore temporary files left from + previous runs. Automatically ignore temporary files older than 24 hours. + (bug 34052) + * revdep-rebuild: Always return an exit status based upon success or + failure. (bug 38472) + * revdep-rebuild: Fixed to only emerge packages with direct missing + dependencies. (bug 38487) + * revdep-rebuild: New man page. (bug 40042) + * revdep-rebuild: emerge is no longer called with --nodeps. This allows + for needed dependencies to be pulled in. (bug 62893) + * revdep-rebuild: Cleaned up grammatical errors (bug 85278) + * revdep-rebuild: Added support for revdep-rebuild --soname + /path/to/library.so (bug 91503) + * revdep-rebuild: Removed symbolically linked directories from search + (bug 93574) + * revdep-rebuild: --nocolor option to turn off colored output, the + script also obeys the NOCOLOR setting from /etc/make.conf. + * revdep-rebuild: Removed dependency on qpkg + * revdep-rebuild: Script uses PORTAGE_NICENESS from /etc/make.conf + * revdep-rebuild: Undocumented --keep-temp option. This is primarily + for debugging/testing. This option prevents temporary files from being + deleted. + * revdep-rebuild: Changed --soname --soname-regexp options to --library + and treat all arguments as basic regular expressions. --soname and + --soname-regexp can still be used as options for backwards + compatability. + * revdep-rebuild: Removed requirement to keep revdep-rebuild and emerge + options distinct. Options that are unrecognized by revdep-rebuild are + passed directly to emerge. + +2005-04-30 Marius Mauch + * glsa-check: add V to short option list so it actually works + * equery: added new option --name-only to belongs command to make it + "emerge-compatible" + +2005-04-26 Marius Mauch + * gentoolkit: fix broken Makefile + * gentoolkit: add some sticky tape to get the stupid thing working again + * equery: fix a few minor problems + +2005-04-25 Marius Mauch + * qpkg: moving to /usr/share/doc/gentoolkit-*/deprecated + * etcat: moving to /usr/share/doc/gentoolkit-*/deprecated + * revdep-rebuild: replacing qpkg call with equivalent grep/sed call + +2005-04-07 Marius Mauch + * euse: fixed bugs 74344, 75525 and 84521 + * euse: add better support for cascaded profiles + * glsa-check: use --oneshot (bug 79819) + * glsa.py: fix stupid revision comparison bug (bug 75233) + +2005-03-12 Aron Griffis + * Added eviewcvs to -dev, utility for generating viewcvs URLs + +2005-03-01 Karl Trygve Kalleberg + * Dropped epkgmove from the -dev + * Released gentoolkit-dev-0.2.3 + +2005-03-01 Karl Trygve Kalleberg + * Released gentookit-dev-0.2.2 + +2004-12-09 Marius Mauch + * glsa.py: Another stupid bug, this time revisionMatch() broke as + ~foobar-rN isn't valid anymore + +2004-12-08 Marius Mauch + * equery: implemented the --category option + * glsa-check: fixed the bug where it wanted to unnecessary merge masked + packages + * glsa-check: added a check to verify that all non-option arguments are + valid GLSAs + * glsa.py: changed the outfile parameter in Glsa.dump() to outstream so + we don't have to open/close a file which breaks pipes + * glsa.py: checks now for python versions below 2.3 and throws an + exception + +2004-11-29 Karl Trygve Kalleberg + * branched v0-3-0: major rework in equery is in progess. the main + branch is reserved for minor and incremental fixups. + +2004-10-20 Karl Trygve Kalleberg + * release.sh: New script that automates the relase of a new gentoolkit + relase. Only works for gentoolkit-dev at the moment. + * src/echangelog/Makefile: Fixed spurious '}' + * Released gentoolkit-dev-0.2.1 + +2004-10-31 Marius Mauch + * qpkg: security fix for bug #68846 + +2004-10-20 Karl Trygve Kalleberg + * etcat: fixed get_use_vars to get_use_flags, fixes #67349. + +2004-10-18 Karl Trygve Kalleberg + * gentoolkit: collapsed ChangeLog into base ChangeLog + * gentoolkit: reverted indenting back to tabs, due to loud protests + from Marius;) + * equery: collapsed ChangeLog into base ChangeLog + * equery: reverted indenting back to tabs, due to loud protests from + Marius;) + * equery: minor syntactical cleanups. + * equery: minor documentation improvements + * equery: added errors module that will hold various types of internal + errors raised. + * equery: added try block around on md5sum check, which fails on various + conditions like insufficient permission or stale temporary checksum + files. + +2004-10-17 Marius Mauch + * equery: fix for bug #67473 (checking md5sums of prelinked binaries) + * equery: fix for bug #67275 (--nocolor didn't work as configure was + called before parsing the arguments + * equery: changed defaults for `equery depends` as making a depgraph for + the full portage tree isn't a good idea and find_all_packages() uses way + to much memory currently + * euse: replaced the old perl version with a newly written bash version. + +2004-10-12 Marius Mauch + * equery: fix for bug #67210 + +2004-10-10 Marius Mauch + * Removed old-scripts directory from gentoolkit + * euse: added a errormessage that it doesn't support cascading profiles + * equery: small bugfixes + * equery: performance speedup for `equery belongs` by using portage + directly + * equery: added MD5 verification to `equery check` + * equery: renamed 'hasuses' to 'hasuse' + * equery: added filter patch for `equery files` from bug 43422, thanks + to degrenier@easyconnect.fr + * Released gentoolkit-0.2.0_pre10 + +2004-10-10 Karl Trygve Kalleberg + * equery: Added unit tests for all supported commands + * equery: Fixed printing order and recognition of overlay, #53432. + +2004-10-11 Karl Trygve Kalleberg + * gentoolkit: Split gentoolkit.py into helpers.py and package.py + +2004-10-10 Karl Trygve Kalleberg + * gentoolkit: Fixed Makefiles to work with posix-compatible shells + * gentoolkit: Fixed is_overlay() to report properly, #53432. + +2004-10-06 Marius Mauch + * glsa.py: Convert Unicode strings to ascii before passing them to + portage + * glsa.py: Some formatting fixes for dump() + * glsa.py: changed the matching routines so the reports are hopefully + more accurate + * glsa-check: added color support + * glsa-check: added a --verbose option to show the warnings about + invalid GLSAs + +2004-09-30 Karl Trygve Kalleberg + * equery: Added unit tests for --help + * equery: Added unit tests for 'files' + +2004-09-27 Karl Trygve Kalleberg + * gentoolkit: Added find_installed_packages + * equery: Added short commands + * equery: Fixed copyright dates + * equery: Fixed belongs to search only installed packages + * equery: Fixed reporting bug in uses command + * equery: Fixed reference to cppv + * equery: Added import of die + * equery: Added searching header to uses + * equery: Fixed hasuses to report properly + * Released gentoolkit-0.2.0_pre9 + * Released gentoolkit-dev-0.2.0_pre4 + +2004-09-08 Karl Trygve Kalleberg + * equery: Added man page rewrites by Katerina Barone-Adesi + , fixes #63045 + * equery: Fixed spacing issues with files, fixes #63036. + * equery: Added depends command by Olivier Crete , + fixes #40830. + * equery: Reworked output yet again. + * equery: Belongs handles multiple files on the command line, partially + fixes #62361. + * gentoolkit: Reworked printing functions + +2004-08-29 Karl Trygve Kalleberg + * gentoolkit: Added printing functions + * equery: Added check for bad regexp in belongs, fixes #58494 + * equery: Added proper error reporting to stderr, fixes #57580 + +2004-08-22 Karl Trygve Kalleberg + * gentoolkit: Fixed Package.get_env_var to use the correct tree db. + * gentoolkit: Renamed Package.get_use_vars to Package.get_use_flags + * equery: Searches now include masked packages, when installed. + * equery: Fixed output to be piping-friendly + * equery: Added -N option to force non-piping output + * equery: Added hasuses command + +2004-08-01 Marius Mauch + * Fixed grep expression for `qpkg -f` + +2004-05-04 Karl Trygve Kalleberg + * equery: Added a -f/--full-regex option to belongs and some logic so + users can do belongs ant, belongs /usr/bin/ant and belongs -f ".*ant.*" + while getting sensible results. Fixes #37637. + +2004-04-14 Karl Trygve Kalleberg + * Released gentoolkit-dev-0.2.0_pre3 + +2004-03-31 Marius Mauch + * glsa-check: updates, fixing #45528 and #45522, adding support for rXX + operators and passing filenames as arguments to Glsa() + +2004-03-13 Marius Mauch + * Added glsa-check and glsa.py, please note: + - they are only temporary for testing, so no manpage/ChangeLog + - their CVS home is in gentoo-projects + * fixed bugs #42160, #40935, #43389 + * equery: fixing descriptions for local USE flags + * equery: more checking on exceptions + +2004-02-08 Karl Trygve Kalleberg + * Added ebump + * Added gensync + * Added epkgmove, closes #36663. + +2004-02-06 Marius Mauch + * fixed bugs #40159, #39798, #39652, #39596, #39293 + * changed etcat and equery behavior for ambigous package names, + they now return values for all matching packages rather + than erroring out + * added "will be phased out" messages to etcat and qpkg + +2004-01-23 Marius Mauch + * lots of bugfixes + * equery: now catches Exceptions thrown by portage + * equery: minor bugfixes + +2004-01-14 Karl Trygve Kalleberg + * Added src/ego to gentoolkit-dev + +2004-01-12 Marius Mauch + * equery: added mask, keyword and slot information to list command + * equery: fixed traceback in equery + * equery: added more information on "equery list" + +2004-01-10 Karl Trygve Kalleberg + * Added src/ego + +2004-01-07 Karl Trygve Kalleberg + * equery: Added Makefile + * Added new build system + * Added src/old-scripts, the scripts from app-portage/gentoolkit + * Renamed gentool to equery + * Released 0.2.0_pre1 + +2003-12-31 Karl Trygve Kalleberg + * equery: Added which command + * equery: Added check command (not finished) + +2003-12-12 Karl Trygve Kalleberg + * equery: Added size command + * equery: Added depgraph command + +2003-12-11 Karl Trygve Kalleberg + * equery: Added list command + * equery: Added uses command + +2003-12-08 Karl Trygve Kalleberg + * Removed emerge-rsync, emerge-webrsync + * Added moo + * Added skeleton man pages to all packages + * Added Makefile + +2003-10-05 Karl Trygve Kalleberg + * equery: Added files command + * equery: Added belongs command + +2003-10-04 Karl Trygve Kalleberg + * Rewrote dep-clean to python + +2003-06-31 Karl Trygve Kalleberg + * Rewrote more of etcat; many of the functions now employ + gentoolkit. + * Replaced qpkg with stubs of a reimplementation in python. + +2003-06-27 Karl Trygve Kalleberg + * Added patch to echangelog to consider PORTDIR, fixes #23881. + +2003-06-26 Karl Trygve Kalleberg + * Added echangelog, by agenkin + * Added ekeyword, by agenkin + * Added gentoolkit, the common python library for all Gentoolkit tools. + * Revived pkg-size as a testbed for the gentoolkit library + * Fixed some minor issues in qpkg + * Added revdep-rebuild-1 + * Added revdep-rebuild-2 + * Restructuring etcat + * Fixed some minor issues in dep-clean + +2002-11-21 Karl Trygve Kalleberg + * Renamed pkg-size to gentool-package-size + * Renamed pst-package-count to gentool-package-count + * Retired rest of pst-* stuff + +2002-08-06 Karl Trygve Kalleberg + * Created separate CVS module for Gentoolkit + * Restructured directory hierarchy diff --git a/gentoolkit/DEVELOPING b/gentoolkit/DEVELOPING new file mode 100644 index 0000000..e8b7ab3 --- /dev/null +++ b/gentoolkit/DEVELOPING @@ -0,0 +1,161 @@ +Python Code Guidelines +---------------------- +These are a few guidelines to stick to when modifying or adding code to +Gentoolkit. These guidelines do not apply to pym/gentoolkit/test/*. + +First, read Python's PEP 8: http://www.python.org/dev/peps/pep-0008/ +Next, read Portage's DEVELOPING file. +Next, read Portage's Docstring specs: + http://www.gentoo.org/proj/en/portage/doc/policies/docstring-spec.xml + +(Portage DEVELOPING overrides PEP 8, so we use tabs instead of spaces.) + +Here are a few clarifications and changes to the above: + +Line-Wrapping +------------- +- Do NOT space out to an opening paren (etc). Different tab settings make this + difficult to read: + + BAD: + foo = get_foo(keyword1=default, + keyword2=default, + ...) + + OK: + foo = get_foo(keyword1=default, keyword2=default, keyword3=default, + keyword4=default, ...) + + OK: + foo = get_foo( + keyword1=default, + keyword2=default, + ... + ) + +- Preferred line length is 80 characters with a tab length of 4 characters. +- "The preferred way of wrapping long lines is by using Python's implied line + continuation inside parentheses, brackets and braces" rather than using '\' + (PEP 8). + Even better than that is pre-defining a snippet of the long line in a + variable. So: + + BAD: (too long) + self._descriptions = [e.text for e in self._xml_tree.findall("longdescription")] + + OK: + self._descriptions = \ + [e.text for e in self._xml_tree.findall("longdescription")] + + OK: + self._descriptions = [ + e.text for e in self._xml_tree.findall("longdescription") + ] + + OK: (easiest to read and test) + long_descriptions = self._xml_tree.findall("longdescription") + self._descriptions = [e.text for e in long_descriptions] + +Imports: +-------- +Same as PEP 8 and Portage's DEVELOPING spec, but make sure to split python +default libraries, Gentoo system libraries (like portage) and lastly local +modules (gentoolkit), so: + + GOOD: + import os + import re + + import portage + from portage.versions import catpkgsplit, pkgcmp + + from gentoolkit import CONFIG + from gentoolkit import pprinter as pp + ... + +Exceptions: +----------- +Always raise exceptions and catch them at the last possible moment. This allows +API consumers to catch them and decide what to do with them. Do not print an +error to stderr from inside a consumable. Never "print" an error string, always +write it to stderr. + +Lastly, if an error is fatal (should be raised all the way up), try to make +sure it is an errors.Gentoolkit* error. That allows API consumers to catch all +fatal errors with: except 'gentoolkit.errors.GentoolkitException'. See +bin/equery to see how we catch those exceptions before they hit the user. + + BAD: + try: + result = tree.aux_get(str(self.cpv), [var]) + except KeyError: + sys.stderr.write("aux_get returned unexpected results") + + BETTER: + # This line raises KeyError if self.cpv not found: + result = tree.aux_get(str(self.cpv), [var]) + + BEST: + try: + result = tree.aux_get(str(self.cpv), [var]) + except KeyError: + err = "aux_get returned unexpected results" + raise errors.GentoolkitFatalError(err) + +Docstrings: +----------- +Follow this example for any complicated function or method. Don't worry about +docstring for private methods (like _foo) or methods like __this__. It's +definitely OK to write docstrings for these methods as well if there's +something tricky about them, though. + + def graph_reverse_depends(...): + # A ONE-LINE sentence describing the function in simplest terms: + """Graph direct reverse dependencies for self. + + # An optional second paragraph to give more detailed information. + # Sometimes an 'Example usage' here can be worth more than a lengthy + # description. Examples should be an ACTUAL interpreter session: + Example usage: + >>> from gentoolkit.dependencies import Dependencies + >>> ffmpeg = Dependencies('media-video/ffmpeg-0.5_p20373') + >>> # I only care about installed packages that depend on me: + ... from gentoolkit.helpers import get_installed_cpvs + >>> # I want to pass in a sorted list. We can pass strings or + ... # Package or Atom types, so I'll use Package to sort: + ... from gentoolkit.package import Package + >>> installed = sorted(Package(x) for x in get_installed_cpvs()) + >>> deptree = ffmpeg.graph_reverse_depends( + ... only_direct=False, # Include indirect revdeps + ... pkgset=installed) # from installed pkgset + >>> len(deptree) + 44 + + # Lastly use epydoc's special fields to document further. + # See: http://epydoc.sourceforge.net/fields.html + @type pkgset: iterable + @keyword pkgset: sorted pkg cpv strings or anything sublassing + L{gentoolkit.cpv.CPV} to use for calculate our revdep graph. + @type max_depth: int + @keyword max_depth: Maximum depth to recurse if only_direct=False. + -1 means no maximum depth; + 0 is the same as only_direct=True; + >0 means recurse only this many times; + @type only_direct: bool + @keyword only_direct: to recurse or not to recurse + @type printer_fn: callable + @keyword printer_fn: If None, no effect. If set, it will be applied to + each L{gentoolkit.atom.Atom} object as it is added to the results. + @rtype: list + @return: L{gentoolkit.dependencies.Dependencies} objects + """ + +Other concerns: +--------------- +- Choose names which are full, clear words (not necessary in small loops). +- It is NEVER necessary to prefix names with "my". It adds no useful + information. +- Comment and document in simple, unambiguous and non-repetitive English. +- When adding a TODO, FIXME or XXX comment, please date it and add your name so + that other devs know who to ask about the proposed change. +- Be careful of spelling. diff --git a/gentoolkit/MANIFEST.in b/gentoolkit/MANIFEST.in new file mode 100644 index 0000000..8f26bea --- /dev/null +++ b/gentoolkit/MANIFEST.in @@ -0,0 +1,13 @@ +include AUTHORS +include ChangeLog +include COPYING +include CREDITS +include DEVELOPING +include NEWS +include README +include TODO +include setup.py +recursive-include data * +recursive-include bin * +recursive-include man * +recursive-include pym *.py *.txt diff --git a/gentoolkit/NEWS b/gentoolkit/NEWS new file mode 100644 index 0000000..5e349be --- /dev/null +++ b/gentoolkit/NEWS @@ -0,0 +1,40 @@ +News (new features/major bug fixes) + +gentoolkit-0.3.0 +---------------- + +epkginfo: + * is now a link to equery meta and has all the features equery meta has + +equery: + * --help menus cleaned up, using notations (b)elongs instead of belongs(b). + * man page has been rewritten. + * --quiet effects more modules. + * 2 new modules: + * changes - Gentoo ChangeLog viewer, try: + `equery changes portage` to see entry for portage version that emerge + wants to install; + `equery changes portage --from=2.2_rc20 --to=2.2_rc30` to see all entries + between the specified versions. + * meta - Displays information available in metadata.xml and keyword info. + Try `equery meta boost` to list herd, maintainers, keywords, and more. + * Modules which are meant to run on multiple packages (check, list, size) now + allow category and package name globbing, (so no more need for --exact-name + or --category). + + # Exact name matching by default: + $ equery l zilla + * Searching for zilla ... + + # Use globs to fuzzy match + $ equery l *zilla* + * Searching for *zilla* ... + [IP-] [ ] www-client/mozilla-firefox-3.5.4:0 + + # Use globs to 'category filter' + $ equery l www-client/* + * Searching for * in www-client ... + [I--] [XX] www-client/chromium-4.0.223.5:0 + [IP-] [ ] www-client/epiphany-2.26.3-r2:0 + [IP-] [ ] www-client/links-2.2:2 + [IP-] [ ] www-client/mozilla-firefox-3.5.4:0 diff --git a/gentoolkit/README b/gentoolkit/README new file mode 100644 index 0000000..5c785d3 --- /dev/null +++ b/gentoolkit/README @@ -0,0 +1,46 @@ +Package: gentoolkit/gentoolkit-dev +Authors: Aron Griffis + Brandon Low + Ian Leitch + Karl Trygve Kalleberg + Marius Mauch + Paul Varner + See src//AUTHORS for tool-specific authors + +MOTIVATION + +The gentoolkit and gentoolkit-dev packages contain a collection of useful +administration scripts particular to the Gentoo Linux distribution. It contains +rough drafts and implementations of features that may in time make it into +Portage, or into full-fledged tools in their own right. + +The gentoolkit-dev package is intended primarily for Gentoo developers. + +CONTENTS + +gentoolkit +========== +eclean - tool to clean up outdated distfiles and packages +equery - replacement for etcat and qpkg +etcat - extracts auxillary information from portage (deprecated) +euse - tool to manage USE flags +glsa-check - tool to manage GLSA's (Gentoo Linux Security Advisory) +qpkg - convient package query tool (deprecated) +revdep-rebuild - scans/fixes broken shared libs and binaries + +gentoolkit-dev +============== +ebump - Ebuild revision bumper +echangelog - update portage ChangeLogs +ego - +ekeyword - modify package KEYWORDS +epkgmove - tool for moving and renaming packages in CVS +eviewcvs - generate viewcvs URLs +gensync - Overlay Sync Tool + +IMPROVEMENTS + +Any suggestions for improvements should be sent to tools-portage@gentoo.org, or +added as a bug assigned to us. + +We only accept new contributions if they are written in bash or python. diff --git a/gentoolkit/README.dev b/gentoolkit/README.dev new file mode 100644 index 0000000..feefe47 --- /dev/null +++ b/gentoolkit/README.dev @@ -0,0 +1,40 @@ +Adding or modifying code: +========================= +- If you add new code, best practice is to write a test for it. +- If you're modifying code that doesn't have a test and you can write a test + for it, please do. +- Before committing your changes to a python file, please make sure it passes + pylint with: +pylint --rcfile=pylintrc yourfile.py +- If pylint raises a warning or error that you don't agree with, it's probably + better to just change your code. If you're sure you have a good reason for + doing what you're doing, you can add an exception to our pylintrc. + +Creating a release: +=================== +Note: We are using VERSION="0.3.0" simply as an example. + +- Run Gentoolkit's test suite, make sure it passes: +Note: requires dev-python/snakeoil +./setup.py test + +- Create a tag for the release +svn copy svn+ssh://@svn.gentoo.org/var/svnroot/gentoolkit/trunk \ + svn+ssh://@svn.gentoo.org/var/svnroot/gentoolkit/tags/gentoolkit-0.3.0 \ + -m "Tagging the release of gentoolkit." +svn update to pull the tag from subversion +cd to the local tags/gentoolkit-0.3.0 directory + +- Set the version of the release: +VERSION="0.3.0" ./setup.py set_version + +- Create a source distribution (you need to add VERSION here, too): +VERSION="0.3.0" ./setup.py sdist +Transfer dist/gentoolkit-0.3.0.tar.gz to dev.gentoo.org:/space/distfiles-local + +- Reset svn version to 'svn' (default): +./setup.py set_version + +- Clean up temporary files: +./setup.py clean -a + diff --git a/gentoolkit/THANKS b/gentoolkit/THANKS new file mode 100644 index 0000000..d958556 --- /dev/null +++ b/gentoolkit/THANKS @@ -0,0 +1,8 @@ +* eclean + The starting point ideas were found here: + http://forums.gentoo.org/viewtopic.php?t=3011 + + Thanks to eswanson and far for their contributions, and to wolf31o2 for his + support. Thanks also to karltk, some of this code was at some point inspired + by his "equery" tool. And thanks to people who had a look on bug #33877: + Benjamin Braatz, fuzzyray, genone, etc. diff --git a/gentoolkit/TODO b/gentoolkit/TODO new file mode 100644 index 0000000..161546b --- /dev/null +++ b/gentoolkit/TODO @@ -0,0 +1,60 @@ +- equery: + - add --overlay, --portdir to uses + - add glsa pkgspec + - query for current GLSAs on installed package(s) +- rewrite ekeywords and echangelog to use gentoolkit +- fully deprecate qpkg +- fully deprecate pkg-size +- merge change and echangelog +- merge useflag and euse, have _one_ command line tool + - update ufed to rely on the CLI tool + - update ufed to rely on generate-use + - merge generate-use and ufed? +- rewrite revdep-rebuild to use gentoolkit + - drop qpkg dependency; use equery instead +- write efeatures for turning on/off FEATURES in make.conf +- look at ekeys, ewatch +- revision bump tool + - bump versioned files in filesdir + - -m for changelog entry + - use ~/.gentoo/gentoolkit/ebump.conf + - use /etc/gentoolkit/ebump.conf + +equery: + Tests: + +helpers2 (FileOwner._extend_realpaths test probably doesn't clean up) + Run pylint and write test to run pylint + Write test to compile all modules (full syntax check). Take from portage. + Add more --debug stuff + Write tests for Dependencies._parser + Refactor each module to be useful for import. Done modules: + +depends + +belongs + +meta + +changes + +depgraph + +Ebuild changes: + - Add: + src_test() { + "${python}" setup.py test || die "testing returned non zero" + } + - Add: + DEPEND on python 2.5 (needed for 'from __future__ import with_statement' and others) + +For Next Release: + - write NEWS file + - make CPV.__init__ more strict, it allows some silly stuff + - $ equery uses '>=sys-apps/portage-2' + * Searching for >=sys-apps/portage-2 ... + * Found these USE flags for sys-apps/portage-2.1.6.13: + - belongs doesn't properly match atom syntax + + +For following release: + - transition package query backend to using Query class. + Query class should accept any kind package of input accepted by equery. + Most of the functions in helpers should be able to moved out, either in + to query (many of those functions pertain to finding packages matching a + query) or into other appropriate modules (split_cpv, + compare_package_strings into cpv, as they also requires a cpv string) diff --git a/gentoolkit/bin/eclean b/gentoolkit/bin/eclean new file mode 100755 index 0000000..6fee381 --- /dev/null +++ b/gentoolkit/bin/eclean @@ -0,0 +1,834 @@ +#!/usr/bin/python +# Copyright 2003-2005 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +from __future__ import with_statement + +############################################################################### +# Meta: +__author__ = "Thomas de Grenier de Latour (tgl)" +__email__ = "degrenier@easyconnect.fr" +__version__ = "svn" +__productname__ = "eclean" +__description__ = "A cleaning tool for Gentoo distfiles and binaries." + + +############################################################################### +# Python imports: + +import sys +import os, stat +import re +import time +import getopt +import fpformat +import signal + +import portage +from portage.output import * + +listdir = portage.listdir + +############################################################################### +# Misc. shortcuts to some portage stuff: +port_settings = portage.settings +distdir = port_settings["DISTDIR"] +pkgdir = port_settings["PKGDIR"] + + +############################################################################### +# printVersion: +def printVersion(): + print "%s (%s) - %s" \ + % (__productname__, __version__, __description__) + print + print "Author: %s <%s>" % (__author__,__email__) + print "Copyright 2003-2009 Gentoo Foundation" + print "Distributed under the terms of the GNU General Public License v2" + + +############################################################################### +# printUsage: print help message. May also print partial help to stderr if an +# error from {'options','actions'} is specified. +def printUsage(error=None,help=None): + out = sys.stdout + if error: out = sys.stderr + if not error in ('actions', 'global-options', \ + 'packages-options', 'distfiles-options', \ + 'merged-packages-options', 'merged-distfiles-options', \ + 'time', 'size'): + error = None + if not error and not help: help = 'all' + if error == 'time': + eerror("Wrong time specification") + print >>out, "Time specification should be an integer followed by a"+ \ + " single letter unit." + print >>out, "Available units are: y (years), m (months), w (weeks), "+ \ + "d (days) and h (hours)." + print >>out, "For instance: \"1y\" is \"one year\", \"2w\" is \"two"+ \ + " weeks\", etc. " + return + if error == 'size': + eerror("Wrong size specification") + print >>out, "Size specification should be an integer followed by a"+ \ + " single letter unit." + print >>out, "Available units are: G, M, K and B." + print >>out, "For instance: \"10M\" is \"ten megabytes\", \"200K\" "+ \ + "is \"two hundreds kilobytes\", etc." + return + if error in ('global-options', 'packages-options', 'distfiles-options', \ + 'merged-packages-options', 'merged-distfiles-options',): + eerror("Wrong option on command line.") + print >>out + elif error == 'actions': + eerror("Wrong or missing action name on command line.") + print >>out + print >>out, white("Usage:") + if error in ('actions','global-options', 'packages-options', \ + 'distfiles-options') or help == 'all': + print >>out, " "+turquoise(__productname__), \ + yellow("[global-option] ..."), \ + green(""), \ + yellow("[action-option] ...") + if error == 'merged-distfiles-options' or help in ('all','distfiles'): + print >>out, " "+turquoise(__productname__+'-dist'), \ + yellow("[global-option, distfiles-option] ...") + if error == 'merged-packages-options' or help in ('all','packages'): + print >>out, " "+turquoise(__productname__+'-pkg'), \ + yellow("[global-option, packages-option] ...") + if error in ('global-options', 'actions'): + print >>out, " "+turquoise(__productname__), \ + yellow("[--help, --version]") + if help == 'all': + print >>out, " "+turquoise(__productname__+"(-dist,-pkg)"), \ + yellow("[--help, --version]") + if error == 'merged-packages-options' or help == 'packages': + print >>out, " "+turquoise(__productname__+'-pkg'), \ + yellow("[--help, --version]") + if error == 'merged-distfiles-options' or help == 'distfiles': + print >>out, " "+turquoise(__productname__+'-dist'), \ + yellow("[--help, --version]") + print >>out + if error in ('global-options', 'merged-packages-options', \ + 'merged-distfiles-options') or help: + print >>out, "Available global", yellow("options")+":" + print >>out, yellow(" -C, --nocolor")+ \ + " - turn off colors on output" + print >>out, yellow(" -d, --destructive")+ \ + " - only keep the minimum for a reinstallation" + print >>out, yellow(" -e, --exclude-file=")+ \ + " - path to the exclusion file" + print >>out, yellow(" -i, --interactive")+ \ + " - ask confirmation before deletions" + print >>out, yellow(" -n, --package-names")+ \ + " - protect all versions (when --destructive)" + print >>out, yellow(" -p, --pretend")+ \ + " - only display what would be cleaned" + print >>out, yellow(" -q, --quiet")+ \ + " - be as quiet as possible" + print >>out, yellow(" -t, --time-limit=

  • elements for a given
      or
        node. + + @type listnode: xml.dom.Node + @param listnode:
          or
            list to get the elements for + @rtype: List of Strings + @return: a list that contains the value of the
          1. elements + """ + if not listnode.nodeName in ["ul", "ol"]: + raise GlsaFormatException("Invalid function call: listnode is not
              or
                ") + rValue = [getText(li, format="strip") \ + for li in listnode.childNodes \ + if li.nodeType == xml.dom.Node.ELEMENT_NODE] + return rValue + +def getText(node, format, textfd = None): + """ + This is the main parser function. It takes a node and traverses + recursive over the subnodes, getting the text of each (and the + I{link} attribute for and ). Depending on the I{format} + parameter the text might be formatted by adding/removing newlines, + tabs and spaces. This function is only useful for the GLSA DTD, + it's not applicable for other DTDs. + + @type node: xml.dom.Node + @param node: the root node to start with the parsing + @type format: String + @param format: this should be either I{strip}, I{keep} or I{xml} + I{keep} just gets the text and does no formatting. + I{strip} replaces newlines and tabs with spaces and + replaces multiple spaces with one space. + I{xml} does some more formatting, depending on the + type of the encountered nodes. + @type textfd: writable file-like object + @param textfd: the file-like object to write the output to + @rtype: String + @return: the (formatted) content of the node and its subnodes + except if textfd was not none + """ + if not textfd: + textfd = StringIO() + returnNone = False + else: + returnNone = True + if format in ["strip", "keep"]: + if node.nodeName in ["uri", "mail"]: + textfd.write(node.childNodes[0].data+": "+node.getAttribute("link")) + else: + for subnode in node.childNodes: + if subnode.nodeName == "#text": + textfd.write(subnode.data) + else: + getText(subnode, format, textfd) + else: # format = "xml" + for subnode in node.childNodes: + if subnode.nodeName == "p": + for p_subnode in subnode.childNodes: + if p_subnode.nodeName == "#text": + textfd.write(p_subnode.data.strip()) + elif p_subnode.nodeName in ["uri", "mail"]: + textfd.write(p_subnode.childNodes[0].data) + textfd.write(" ( "+p_subnode.getAttribute("link")+" )") + textfd.write(NEWLINE_ESCAPE) + elif subnode.nodeName == "ul": + for li in getListElements(subnode): + textfd.write("-"+SPACE_ESCAPE+li+NEWLINE_ESCAPE+" ") + elif subnode.nodeName == "ol": + i = 0 + for li in getListElements(subnode): + i = i+1 + textfd.write(str(i)+"."+SPACE_ESCAPE+li+NEWLINE_ESCAPE+" ") + elif subnode.nodeName == "code": + textfd.write(getText(subnode, format="keep").lstrip().replace("\n", NEWLINE_ESCAPE)) + textfd.write(NEWLINE_ESCAPE) + elif subnode.nodeName == "#text": + textfd.write(subnode.data) + else: + raise GlsaFormatException("Invalid Tag found: ", subnode.nodeName) + if returnNone: + return None + rValue = textfd.getvalue() + if format == "strip": + rValue = rValue.strip(" \n\t") + rValue = re.sub("[\s]{2,}", " ", rValue) + return rValue + +def getMultiTagsText(rootnode, tagname, format): + """ + Returns a list with the text of all subnodes of type I{tagname} + under I{rootnode} (which itself is not parsed) using the given I{format}. + + @type rootnode: xml.dom.Node + @param rootnode: the node to search for I{tagname} + @type tagname: String + @param tagname: the name of the tags to search for + @type format: String + @param format: see L{getText} + @rtype: List of Strings + @return: a list containing the text of all I{tagname} childnodes + """ + rValue = [getText(e, format) \ + for e in rootnode.getElementsByTagName(tagname)] + return rValue + +def makeAtom(pkgname, versionNode): + """ + creates from the given package name and information in the + I{versionNode} a (syntactical) valid portage atom. + + @type pkgname: String + @param pkgname: the name of the package for this atom + @type versionNode: xml.dom.Node + @param versionNode: a or Node that + contains the version information for this atom + @rtype: String + @return: the portage atom + """ + rValue = opMapping[versionNode.getAttribute("range")] \ + + pkgname \ + + "-" + getText(versionNode, format="strip") + try: + slot = versionNode.getAttribute("slot").strip() + except KeyError: + pass + else: + if slot and slot != "*": + rValue += ":" + slot + return str(rValue) + +def makeVersion(versionNode): + """ + creates from the information in the I{versionNode} a + version string (format ). + + @type versionNode: xml.dom.Node + @param versionNode: a or Node that + contains the version information for this atom + @rtype: String + @return: the version string + """ + rValue = opMapping[versionNode.getAttribute("range")] \ + +getText(versionNode, format="strip") + try: + slot = versionNode.getAttribute("slot").strip() + except KeyError: + pass + else: + if slot and slot != "*": + rValue += ":" + slot + return rValue + +def match(atom, portdbname, match_type="default"): + """ + wrapper that calls revisionMatch() or portage.dbapi.match() depending on + the given atom. + + @type atom: string + @param atom: a <~ or >~ atom or a normal portage atom that contains the atom to match against + @type portdb: portage.dbapi + @param portdb: one of the portage databases to use as information source + @type match_type: string + @param match_type: if != "default" passed as first argument to dbapi.xmatch + to apply the wanted visibility filters + + @rtype: list of strings + @return: a list with the matching versions + """ + db = portage.db["/"][portdbname].dbapi + if atom[2] == "~": + return revisionMatch(atom, db, match_type=match_type) + elif match_type == "default" or not hasattr(db, "xmatch"): + return db.match(atom) + else: + return db.xmatch(match_type, atom) + +def revisionMatch(revisionAtom, portdb, match_type="default"): + """ + handler for the special >~, >=~, <=~ and <~ atoms that are supposed to behave + as > and < except that they are limited to the same version, the range only + applies to the revision part. + + @type revisionAtom: string + @param revisionAtom: a <~ or >~ atom that contains the atom to match against + @type portdb: portage.dbapi + @param portdb: one of the portage databases to use as information source + @type match_type: string + @param match_type: if != "default" passed as first argument to portdb.xmatch + to apply the wanted visibility filters + + @rtype: list of strings + @return: a list with the matching versions + """ + if match_type == "default" or not hasattr(portdb, "xmatch"): + if ":" in revisionAtom: + mylist = portdb.match(re.sub(r'-r[0-9]+(:[^ ]+)?$', r'\1', revisionAtom[2:])) + else: + mylist = portdb.match(re.sub("-r[0-9]+$", "", revisionAtom[2:])) + else: + if ":" in revisionAtom: + mylist = portdb.xmatch(match_type, re.sub(r'-r[0-9]+(:[^ ]+)?$', r'\1', revisionAtom[2:])) + else: + mylist = portdb.xmatch(match_type, re.sub("-r[0-9]+$", "", revisionAtom[2:])) + rValue = [] + for v in mylist: + r1 = portage.pkgsplit(v)[-1][1:] + r2 = portage.pkgsplit(revisionAtom[3:])[-1][1:] + if eval(r1+" "+revisionAtom[0:2]+" "+r2): + rValue.append(v) + return rValue + + +def getMinUpgrade(vulnerableList, unaffectedList, minimize=True): + """ + Checks if the systemstate is matching an atom in + I{vulnerableList} and returns string describing + the lowest version for the package that matches an atom in + I{unaffectedList} and is greater than the currently installed + version. It will return an empty list if the system is affected, + and no upgrade is possible or None if the system is not affected. + Both I{vulnerableList} and I{unaffectedList} should have the + same base package. + + @type vulnerableList: List of Strings + @param vulnerableList: atoms matching vulnerable package versions + @type unaffectedList: List of Strings + @param unaffectedList: atoms matching unaffected package versions + @type minimize: Boolean + @param minimize: True for a least-change upgrade, False for emerge-like algorithm + + @rtype: String | None + @return: the lowest unaffected version that is greater than + the installed version. + """ + rValue = "" + v_installed = reduce(operator.add, [match(v, "vartree") for v in vulnerableList], []) + u_installed = reduce(operator.add, [match(u, "vartree") for u in unaffectedList], []) + + # remove all unaffected atoms from vulnerable list + v_installed = list(set(v_installed).difference(set(u_installed))) + + if not v_installed: + return None + + # this tuple holds all vulnerable atoms, and the related upgrade atom + vuln_update = [] + avail_updates = set() + for u in unaffectedList: + # TODO: This had match_type="match-all" before. I don't think it should + # since we disregarded masked items later anyway (match(=rValue, "porttree")) + avail_updates.update(match(u, "porttree")) + # if an atom is already installed, we should not consider it for upgrades + avail_updates.difference_update(u_installed) + + for vuln in v_installed: + update = "" + for c in avail_updates: + c_pv = portage.catpkgsplit(c) + i_pv = portage.catpkgsplit(vuln) + if portage.pkgcmp(c_pv[1:], i_pv[1:]) > 0 \ + and (update == "" \ + or (minimize ^ (portage.pkgcmp(c_pv[1:], portage.catpkgsplit(update)[1:]) > 0))) \ + and portage.db["/"]["porttree"].dbapi.aux_get(c, ["SLOT"]) == portage.db["/"]["vartree"].dbapi.aux_get(vuln, ["SLOT"]): + update = c_pv[0]+"/"+c_pv[1]+"-"+c_pv[2] + if c_pv[3] != "r0": # we don't like -r0 for display + update += "-"+c_pv[3] + vuln_update.append([vuln, update]) + + return vuln_update + +def format_date(datestr): + """ + Takes a date (announced, revised) date from a GLSA and formats + it as readable text (i.e. "January 1, 2008"). + + @type date: String + @param date: the date string to reformat + @rtype: String + @return: a reformatted string, or the original string + if it cannot be reformatted. + """ + splitdate = datestr.split("-", 2) + if len(splitdate) != 3: + return datestr + + # This cannot raise an error as we use () instead of [] + splitdate = (int(x) for x in splitdate) + + from datetime import date + try: + d = date(*splitdate) + except ValueError: + return datestr + + # TODO We could format to local date format '%x' here? + return d.strftime("%B %d, %Y") + +# simple Exception classes to catch specific errors +class GlsaTypeException(Exception): + def __init__(self, doctype): + Exception.__init__(self, "wrong DOCTYPE: %s" % doctype) + +class GlsaFormatException(Exception): + pass + +class GlsaArgumentException(Exception): + pass + +# GLSA xml data wrapper class +class Glsa: + """ + This class is a wrapper for the XML data and provides methods to access + and display the contained data. + """ + def __init__(self, myid, myconfig): + """ + Simple constructor to set the ID, store the config and gets the + XML data by calling C{self.read()}. + + @type myid: String + @param myid: String describing the id for the GLSA object (standard + GLSAs have an ID of the form YYYYMM-nn) or an existing + filename containing a GLSA. + @type myconfig: portage.config + @param myconfig: the config that should be used for this object. + """ + if re.match(r'\d{6}-\d{2}', myid): + self.type = "id" + elif os.path.exists(myid): + self.type = "file" + else: + raise GlsaArgumentException("Given ID "+myid+" isn't a valid GLSA ID or filename.") + self.nr = myid + self.config = myconfig + self.read() + + def read(self): + """ + Here we build the filename from the config and the ID and pass + it to urllib to fetch it from the filesystem or a remote server. + + @rtype: None + @return: None + """ + if self.config["CHECKMODE"] == "local": + repository = "file://" + self.config["GLSA_DIR"] + else: + repository = self.config["GLSA_SERVER"] + if self.type == "file": + myurl = "file://"+self.nr + else: + myurl = repository + self.config["GLSA_PREFIX"] + str(self.nr) + self.config["GLSA_SUFFIX"] + self.parse(urllib.urlopen(myurl)) + return None + + def parse(self, myfile): + """ + This method parses the XML file and sets up the internal data + structures by calling the different helper functions in this + module. + + @type myfile: String + @param myfile: Filename to grab the XML data from + @rtype: None + @returns: None + """ + self.DOM = xml.dom.minidom.parse(myfile) + if not self.DOM.doctype: + raise GlsaTypeException(None) + elif self.DOM.doctype.systemId == "http://www.gentoo.org/dtd/glsa.dtd": + self.dtdversion = 0 + elif self.DOM.doctype.systemId == "http://www.gentoo.org/dtd/glsa-2.dtd": + self.dtdversion = 2 + else: + raise GlsaTypeException(self.DOM.doctype.systemId) + myroot = self.DOM.getElementsByTagName("glsa")[0] + if self.type == "id" and myroot.getAttribute("id") != self.nr: + raise GlsaFormatException("filename and internal id don't match:" + myroot.getAttribute("id") + " != " + self.nr) + + # the simple (single, required, top-level, #PCDATA) tags first + self.title = getText(myroot.getElementsByTagName("title")[0], format="strip") + self.synopsis = getText(myroot.getElementsByTagName("synopsis")[0], format="strip") + self.announced = format_date(getText(myroot.getElementsByTagName("announced")[0], format="strip")) + + count = 1 + # Support both formats of revised: + # December 30, 2007: 02 + # 2007-12-30 + revisedEl = myroot.getElementsByTagName("revised")[0] + self.revised = getText(revisedEl, format="strip") + if (revisedEl.attributes.has_key("count")): + count = revisedEl.getAttribute("count") + elif (self.revised.find(":") >= 0): + (self.revised, count) = self.revised.split(":") + + self.revised = format_date(self.revised) + + try: + self.count = int(count) + except ValueError: + # TODO should this rais a GlsaFormatException? + self.count = 1 + + # now the optional and 0-n toplevel, #PCDATA tags and references + try: + self.access = getText(myroot.getElementsByTagName("access")[0], format="strip") + except IndexError: + self.access = "" + self.bugs = getMultiTagsText(myroot, "bug", format="strip") + self.references = getMultiTagsText(myroot.getElementsByTagName("references")[0], "uri", format="keep") + + # and now the formatted text elements + self.description = getText(myroot.getElementsByTagName("description")[0], format="xml") + self.workaround = getText(myroot.getElementsByTagName("workaround")[0], format="xml") + self.resolution = getText(myroot.getElementsByTagName("resolution")[0], format="xml") + self.impact_text = getText(myroot.getElementsByTagName("impact")[0], format="xml") + self.impact_type = myroot.getElementsByTagName("impact")[0].getAttribute("type") + try: + self.background = getText(myroot.getElementsByTagName("background")[0], format="xml") + except IndexError: + self.background = "" + + # finally the interesting tags (product, affected, package) + self.glsatype = myroot.getElementsByTagName("product")[0].getAttribute("type") + self.product = getText(myroot.getElementsByTagName("product")[0], format="strip") + self.affected = myroot.getElementsByTagName("affected")[0] + self.packages = {} + for p in self.affected.getElementsByTagName("package"): + name = p.getAttribute("name") + if not self.packages.has_key(name): + self.packages[name] = [] + tmp = {} + tmp["arch"] = p.getAttribute("arch") + tmp["auto"] = (p.getAttribute("auto") == "yes") + tmp["vul_vers"] = [makeVersion(v) for v in p.getElementsByTagName("vulnerable")] + tmp["unaff_vers"] = [makeVersion(v) for v in p.getElementsByTagName("unaffected")] + tmp["vul_atoms"] = [makeAtom(name, v) for v in p.getElementsByTagName("vulnerable")] + tmp["unaff_atoms"] = [makeAtom(name, v) for v in p.getElementsByTagName("unaffected")] + self.packages[name].append(tmp) + # TODO: services aren't really used yet + self.services = self.affected.getElementsByTagName("service") + return None + + def dump(self, outstream=sys.stdout, encoding="utf-8"): + """ + Dumps a plaintext representation of this GLSA to I{outfile} or + B{stdout} if it is ommitted. You can specify an alternate + I{encoding} if needed (default is utf-8). + + @type outstream: File + @param outfile: Stream that should be used for writing + (defaults to sys.stdout) + """ + outstream = codecs.getwriter(encoding)(outstream) + width = int(self.config["PRINTWIDTH"]) + outstream.write(center("GLSA %s: \n%s" % (self.nr, self.title), width)+"\n") + outstream.write((width*"=")+"\n") + outstream.write(wrap(self.synopsis, width, caption="Synopsis: ")+"\n") + outstream.write("Announced on: %s\n" % self.announced) + outstream.write("Last revised on: %s : %02d\n\n" % (self.revised, self.count)) + if self.glsatype == "ebuild": + for k in self.packages.keys(): + pkg = self.packages[k] + for path in pkg: + vul_vers = "".join(path["vul_vers"]) + unaff_vers = "".join(path["unaff_vers"]) + outstream.write("Affected package: %s\n" % k) + outstream.write("Affected archs: ") + if path["arch"] == "*": + outstream.write("All\n") + else: + outstream.write("%s\n" % path["arch"]) + outstream.write("Vulnerable: %s\n" % vul_vers) + outstream.write("Unaffected: %s\n\n" % unaff_vers) + elif self.glsatype == "infrastructure": + pass + if len(self.bugs) > 0: + outstream.write("\nRelated bugs: ") + outstream.write(", ".join(self.bugs)) + outstream.write("\n") + if self.background: + outstream.write("\n"+wrap(self.background, width, caption="Background: ")) + outstream.write("\n"+wrap(self.description, width, caption="Description: ")) + outstream.write("\n"+wrap(self.impact_text, width, caption="Impact: ")) + outstream.write("\n"+wrap(self.workaround, width, caption="Workaround: ")) + outstream.write("\n"+wrap(self.resolution, width, caption="Resolution: ")) + myreferences = " ".join(r.replace(" ", SPACE_ESCAPE)+NEWLINE_ESCAPE for r in self.references) + outstream.write("\n"+wrap(myreferences, width, caption="References: ")) + outstream.write("\n") + + def isVulnerable(self): + """ + Tests if the system is affected by this GLSA by checking if any + vulnerable package versions are installed. Also checks for affected + architectures. + + @rtype: Boolean + @returns: True if the system is affected, False if not + """ + rValue = False + for k in self.packages.keys(): + pkg = self.packages[k] + for path in pkg: + if path["arch"] == "*" or self.config["ARCH"] in path["arch"].split(): + for v in path["vul_atoms"]: + rValue = rValue \ + or (None != getMinUpgrade([v,], path["unaff_atoms"])) + return rValue + + def isInjected(self): + """ + Looks if the GLSA ID is in the GLSA checkfile to check if this + GLSA should be marked as applied. + + @rtype: Boolean + @returns: True if the GLSA is in the inject file, False if not + """ + if not os.access(self.config["CHECKFILE"], os.R_OK): + return False + aList = portage.grabfile(self.config["CHECKFILE"]) + return (self.nr in aList) + + def inject(self): + """ + Puts the ID of this GLSA into the GLSA checkfile, so it won't + show up on future checks. Should be called after a GLSA is + applied or on explicit user request. + + @rtype: None + @returns: None + """ + if not self.isInjected(): + checkfile = open(self.config["CHECKFILE"], "a+") + checkfile.write(self.nr+"\n") + checkfile.close() + return None + + def getMergeList(self, least_change=True): + """ + Returns the list of package-versions that have to be merged to + apply this GLSA properly. The versions are as low as possible + while avoiding downgrades (see L{getMinUpgrade}). + + @type least_change: Boolean + @param least_change: True if the smallest possible upgrade should be selected, + False for an emerge-like algorithm + @rtype: List of Strings + @return: list of package-versions that have to be merged + """ + return list(set(update for (vuln, update) in self.getAffectionTable(least_change) if update)) + + def getAffectionTable(self, least_change=True): + """ + Will initialize the self.systemAffection list of + atoms installed on the system that are affected + by this GLSA, and the atoms that are minimal upgrades. + """ + systemAffection = [] + for pkg in self.packages.keys(): + for path in self.packages[pkg]: + update = getMinUpgrade(path["vul_atoms"], path["unaff_atoms"], minimize=least_change) + if update: + systemAffection.extend(update) + return systemAffection diff --git a/gentoolkit/pym/gentoolkit/helpers.py b/gentoolkit/pym/gentoolkit/helpers.py new file mode 100644 index 0000000..6956f97 --- /dev/null +++ b/gentoolkit/pym/gentoolkit/helpers.py @@ -0,0 +1,709 @@ +# Copyright(c) 2009, Gentoo Foundation +# +# Licensed under the GNU General Public License, v2 or higher +# +# $Header$ + +"""Improved versions of the original helpers functions. + +As a convention, functions ending in '_packages' or '_match{es}' return +Package objects, while functions ending in 'cpvs' return a sequence of strings. +Functions starting with 'get_' return a set of packages by default and can be +filtered, while functions starting with 'find_' return nothing unless the +query matches one or more packages. +""" + +# Move to Imports section after Python 2.6 is stable +from __future__ import with_statement + +__all__ = ( + 'ChangeLog', + 'FileOwner', + 'compare_package_strings', + 'do_lookup', + 'find_best_match', + 'find_installed_packages', + 'find_packages', + 'get_cpvs', + 'get_installed_cpvs', + 'get_uninstalled_cpvs', + 'uniqify', + 'uses_globbing', + 'split_cpv' +) +__docformat__ = 'epytext' + +# ======= +# Imports +# ======= + +import fnmatch +import os +import re +from functools import partial +from itertools import chain + +import portage +from portage.versions import catpkgsplit, pkgcmp + +from gentoolkit import pprinter as pp +from gentoolkit import CONFIG +from gentoolkit import errors +from gentoolkit.atom import Atom +from gentoolkit.cpv import CPV +from gentoolkit.dbapi import PORTDB, VARDB +from gentoolkit.versionmatch import VersionMatch +# This has to be imported below to stop circular import. +#from gentoolkit.package import Package + +# ======= +# Classes +# ======= + +class ChangeLog(object): + """Provides methods for working with a Gentoo ChangeLog file. + + Example usage: + >>> from gentoolkit.helpers import ChangeLog + >>> portage = ChangeLog('/usr/portage/sys-apps/portage/ChangeLog') + >>> print portage.latest.strip() + *portage-2.2_rc50 (15 Nov 2009) + + 15 Nov 2009; Zac Medico +portage-2.2_rc50.ebuild: + 2.2_rc50 bump. This includes all fixes in 2.1.7.5. + >>> len(portage.full) + 75 + >>> len(portage.entries_matching_range( + ... from_ver='2.2_rc40', + ... to_ver='2.2_rc50')) + 11 + + """ + def __init__(self, changelog_path, invalid_entry_is_fatal=False): + if not (os.path.isfile(changelog_path) and + os.access(changelog_path, os.R_OK)): + raise errors.GentoolkitFatalError( + "%s does not exist or is unreadable" % pp.path(changelog_path) + ) + self.changelog_path = changelog_path + self.invalid_entry_is_fatal = invalid_entry_is_fatal + + # Process the ChangeLog: + self.entries = self._split_changelog() + self.indexed_entries = self._index_changelog() + self.full = self.entries + self.latest = self.entries[0] + + def __repr__(self): + return "<%s %r>" % (self.__class__.__name__, self.changelog_path) + + def entries_matching_atom(self, atom): + """Return entries whose header versions match atom's version. + + @type atom: L{gentoolkit.atom.Atom} or str + @param atom: a atom to find matching entries against + @rtype: list + @return: entries matching atom + @raise errors.GentoolkitInvalidAtom: if atom is a string and malformed + """ + result = [] + + if not isinstance(atom, Atom): + atom = Atom(atom) + + for entry_set in self.indexed_entries: + i, entry = entry_set + # VersionMatch doesn't store .cp, so we'll force it to match here: + i.cpv.cp = atom.cpv.cp + if atom.intersects(i): + result.append(entry) + + return result + + def entries_matching_range(self, from_ver=None, to_ver=None): + """Return entries whose header versions are within a range of versions. + + @type from_ver: str + @param from_ver: valid Gentoo version + @type to_ver: str + @param to_ver: valid Gentoo version + @rtype: list + @return: entries between from_ver and to_ver + @raise errors.GentoolkitFatalError: if neither vers are set + @raise errors.GentoolkitInvalidVersion: if either ver is invalid + """ + result = [] + + # Make sure we have at least one version set + if not (from_ver or to_ver): + raise errors.GentoolkitFatalError( + "Need to specifiy 'from_ver' or 'to_ver'" + ) + + # Create a VersionMatch instance out of from_ver + from_restriction = None + if from_ver: + try: + from_ver_rev = CPV("null-%s" % from_ver) + except errors.GentoolkitInvalidCPV: + raise errors.GentoolkitInvalidVersion(from_ver) + from_restriction = VersionMatch(from_ver_rev, op='>=') + + # Create a VersionMatch instance out of to_ver + to_restriction = None + if to_ver: + try: + to_ver_rev = CPV("null-%s" % to_ver) + except errors.GentoolkitInvalidCPV: + raise errors.GentoolkitInvalidVersion(to_ver) + to_restriction = VersionMatch(to_ver_rev, op='<=') + + # Add entry to result if version ranges intersect it + for entry_set in self.indexed_entries: + i, entry = entry_set + if from_restriction and not from_restriction.match(i): + continue + if to_restriction and not to_restriction.match(i): + continue + result.append(entry) + + return result + + def _index_changelog(self): + """Use the output of L{self._split_changelog} to create an index list + of L{gentoolkit.versionmatch.VersionMatch} objects. + + @rtype: list + @return: tuples containing a VersionMatch instance for the release + version of each entry header as the first item and the entire entry + as the second item + @raise ValueError: if self.invalid_entry_is_fatal is True and we hit an + invalid entry + """ + + result = [] + for entry in self.entries: + # Extract the package name from the entry header, ex: + # *xterm-242 (07 Mar 2009) => xterm-242 + pkg_name = entry.split(' ', 1)[0].lstrip('*') + if not pkg_name.strip(): + continue + try: + entry_ver = CPV(pkg_name) + except errors.GentoolkitInvalidCPV: + if self.invalid_entry_is_fatal: + raise ValueError(entry_ver) + continue + + result.append((VersionMatch(entry_ver, op='='), entry)) + + return result + + def _split_changelog(self): + """Split the ChangeLog into individual entries. + + @rtype: list + @return: individual ChangeLog entries + """ + + result = [] + partial_entries = [] + with open(self.changelog_path) as log: + for line in log: + if line.startswith('#'): + continue + elif line.startswith('*'): + # Append last entry to result... + entry = ''.join(partial_entries) + if entry and not entry.isspace(): + result.append(entry) + # ... and start a new entry + partial_entries = [line] + else: + partial_entries.append(line) + else: + # Append the final entry + entry = ''.join(partial_entries) + result.append(entry) + + return result + + +class FileOwner(object): + """Creates a function for locating the owner of filename queries. + + Example usage: + >>> from gentoolkit.helpers import FileOwner + >>> findowner = FileOwner() + >>> findowner(('/usr/bin/vim',)) + [(, '/usr/bin/vim')] + """ + def __init__(self, is_regex=False, early_out=False, printer_fn=None): + """Instantiate function. + + @type is_regex: bool + @param is_regex: funtion args are regular expressions + @type early_out: bool + @param early_out: return when first result is found (safe) + @type printer_fn: callable + @param printer_fn: If defined, will be passed useful information for + printing each result as it is found. + """ + self.is_regex = is_regex + self.early_out = early_out + self.printer_fn = printer_fn + + def __call__(self, queries): + """Run the function. + + @type queries: iterable + @param queries: filepaths or filepath regexes + """ + query_re_string = self._prepare_search_regex(queries) + try: + query_re = re.compile(query_re_string) + except (TypeError, re.error), err: + raise errors.GentoolkitInvalidRegex(err) + + use_match = False + if ((self.is_regex or query_re_string.startswith('^\/')) + and '|' not in query_re_string ): + # If we were passed a regex or a single path starting with root, + # we can use re.match, else use re.search. + use_match = True + + pkgset = get_installed_cpvs() + + return self.find_owners(query_re, use_match=use_match, pkgset=pkgset) + + def find_owners(self, query_re, use_match=False, pkgset=None): + """Find owners and feed data to supplied output function. + + @type query_re: _sre.SRE_Pattern + @param query_re: file regex + @type use_match: bool + @param use_match: use re.match or re.search + @type pkgset: iterable or None + @param pkgset: list of packages to look through + """ + # FIXME: Remove when lazyimport supports objects: + from gentoolkit.package import Package + + if use_match: + query_fn = query_re.match + else: + query_fn = query_re.search + + results = [] + found_match = False + for pkg in sorted([Package(x) for x in pkgset]): + files = pkg.parsed_contents() + for cfile in files: + match = query_fn(cfile) + if match: + results.append((pkg, cfile)) + if self.printer_fn is not None: + self.printer_fn(pkg, cfile) + if self.early_out: + found_match = True + break + if found_match: + break + return results + + @staticmethod + def extend_realpaths(paths): + """Extend a list of paths with the realpaths for any symlinks. + + @type paths: list + @param paths: file path strs + @rtype: list + @return: the original list plus the realpaths for any symlinks + so long as the realpath doesn't already exist in the list + @raise AttributeError: if paths does not have attribute 'extend' + """ + + osp = os.path + paths.extend([osp.realpath(x) for x in paths + if osp.islink(x) and osp.realpath(x) not in paths]) + + return paths + + def _prepare_search_regex(self, queries): + """Create a regex out of the queries""" + + queries = list(queries) + if self.is_regex: + return '|'.join(queries) + else: + result = [] + # Trim trailing and multiple slashes from queries + slashes = re.compile('/+') + queries = self.extend_realpaths(queries) + for query in queries: + query = slashes.sub('/', query).rstrip('/') + if query.startswith('/'): + query = "^%s$" % re.escape(query) + else: + query = "/%s$" % re.escape(query) + result.append(query) + result = "|".join(result) + return result + +# ========= +# Functions +# ========= + +def compare_package_strings(pkg1, pkg2): + """Similar to the builtin cmp, but for package strings. Usually called + as: package_list.sort(compare_package_strings) + + An alternative is to use the CPV descriptor from gentoolkit.cpv: + >>> cpvs = sorted(CPV(x) for x in package_list) + + @see: >>> help(cmp) + """ + + pkg1 = catpkgsplit(pkg1) + pkg2 = catpkgsplit(pkg2) + if pkg1[0] != pkg2[0]: + return cmp(pkg1[0], pkg2[0]) + elif pkg1[1] != pkg2[1]: + return cmp(pkg1[1], pkg2[1]) + else: + return pkgcmp(pkg1[1:], pkg2[1:]) + + +def do_lookup(query, query_opts): + """A high-level wrapper around gentoolkit package-finder functions. + + @type query: str + @param query: pkg, cat/pkg, pkg-ver, cat/pkg-ver, atom, glob or regex + @type query_opts: dict + @param query_opts: user-configurable options from the calling module + Currently supported options are: + + includeInstalled = bool + includePortTree = bool + includeOverlayTree = bool + isRegex = bool + printMatchInfo = bool # Print info about the search + + @rtype: list + @return: Package objects matching query + """ + + if query_opts["includeInstalled"]: + if query_opts["includePortTree"] or query_opts["includeOverlayTree"]: + simple_package_finder = partial(find_packages, include_masked=True) + complex_package_finder = get_cpvs + else: + simple_package_finder = find_installed_packages + complex_package_finder = get_installed_cpvs + elif query_opts["includePortTree"] or query_opts["includeOverlayTree"]: + simple_package_finder = partial(find_packages, include_masked=True) + complex_package_finder = get_uninstalled_cpvs + else: + raise errors.GentoolkitFatalError( + "Not searching in installed, Portage tree, or overlay. " + "Nothing to do." + ) + + is_simple_query = True + if query_opts["isRegex"] or uses_globbing(query): + is_simple_query = False + + if is_simple_query: + matches = _do_simple_lookup(query, simple_package_finder, query_opts) + else: + matches = _do_complex_lookup(query, complex_package_finder, query_opts) + + return matches + + +def _do_complex_lookup(query, package_finder, query_opts): + """Find matches for a query which is a regex or includes globbing.""" + + # FIXME: Remove when lazyimport supports objects: + from gentoolkit.package import Package + + result = [] + + if query_opts["printMatchInfo"] and not CONFIG["piping"]: + print_query_info(query, query_opts) + + cat = split_cpv(query)[0] + + pre_filter = [] + # The "get_" functions can pre-filter against the whole package key, + # but since we allow globbing now, we run into issues like: + # >>> portage.dep.dep_getkey("sys-apps/portage-*") + # 'sys-apps/portage-' + # So the only way to guarantee we don't overrun the key is to + # prefilter by cat only. + if cat: + if query_opts["isRegex"]: + cat_re = cat + else: + cat_re = fnmatch.translate(cat) + # [::-1] reverses a sequence, so we're emulating an ".rreplace()" + # except we have to put our "new" string on backwards + cat_re = cat_re[::-1].replace('$', '*./', 1)[::-1] + predicate = lambda x: re.match(cat_re, x) + pre_filter = package_finder(predicate=predicate) + + # Post-filter + if query_opts["isRegex"]: + predicate = lambda x: re.search(query, x) + else: + if cat: + query_re = fnmatch.translate(query) + else: + query_re = fnmatch.translate("*/%s" % query) + predicate = lambda x: re.search(query_re, x) + if pre_filter: + result = [x for x in pre_filter if predicate(x)] + else: + result = package_finder(predicate=predicate) + + return [Package(x) for x in result] + + +def _do_simple_lookup(query, package_finder, query_opts): + """Find matches for a query which is an atom or string.""" + + result = [] + + if query_opts["printMatchInfo"] and CONFIG['verbose']: + print_query_info(query, query_opts) + + result = package_finder(query) + if not query_opts["includeInstalled"]: + result = [x for x in result if not x.is_installed()] + + return result + + +def find_best_match(query): + """Return the highest unmasked version of a package matching query. + + @type query: str + @param query: can be of the form: pkg, pkg-ver, cat/pkg, cat/pkg-ver, atom + @rtype: str or None + @raise portage.exception.InvalidAtom: if query is not valid input + """ + # FIXME: Remove when lazyimport supports objects: + from gentoolkit.package import Package + + try: + match = PORTDB.xmatch("bestmatch-visible", query) + except portage.exception.InvalidAtom, err: + raise errors.GentoolkitInvalidAtom(err) + + return Package(match) if match else None + + +def find_installed_packages(query): + """Return a list of Package objects that matched the search key.""" + # FIXME: Remove when lazyimport supports objects: + from gentoolkit.package import Package + + try: + matches = VARDB.match(query) + # catch the ambiguous package Exception + except portage.exception.AmbiguousPackageName, err: + matches = [] + for pkgkey in err[0]: + matches.extend(VARDB.match(pkgkey)) + except portage.exception.InvalidAtom, err: + raise errors.GentoolkitInvalidAtom(err) + + return [Package(x) for x in matches] + + +def find_packages(query, include_masked=False): + """Returns a list of Package objects that matched the query. + + @type query: str + @param query: can be of the form: pkg, pkg-ver, cat/pkg, cat/pkg-ver, atom + @type include_masked: bool + @param include_masked: include masked packages + @rtype: list + @return: matching Package objects + """ + # FIXME: Remove when lazyimport supports objects: + from gentoolkit.package import Package + + if not query: + return [] + + try: + if include_masked: + matches = PORTDB.xmatch("match-all", query) + else: + matches = PORTDB.match(query) + matches.extend(VARDB.match(query)) + except portage.exception.InvalidAtom, err: + raise errors.GentoolkitInvalidAtom(str(err)) + + return [Package(x) for x in set(matches)] + + +def get_cpvs(predicate=None, include_installed=True): + """Get all packages in the Portage tree and overlays. Optionally apply a + predicate. + + Example usage: + >>> from gentoolkit.helpers import get_cpvs + >>> len(set(get_cpvs())) + 26065 + >>> fn = lambda x: x.startswith('app-portage') + >>> len(get_cpvs(fn, include_installed=False)) + 112 + + @type predicate: function + @param predicate: a function to filter the package list with + @type include_installed: bool + @param include_installed: + If True: Return the union of all_cpvs and all_installed_cpvs + If False: Return the difference of all_cpvs and all_installed_cpvs + @rtype: generator + @return: a generator that yields unsorted cat/pkg-ver strings from the + Portage tree + """ + + if predicate: + all_cps = iter(x for x in PORTDB.cp_all() if predicate(x)) + else: + all_cps = PORTDB.cp_all() + + all_cpvs = chain.from_iterable(PORTDB.cp_list(x) for x in all_cps) + all_installed_cpvs = get_installed_cpvs(predicate) + + if include_installed: + for cpv in chain(all_cpvs, all_installed_cpvs): + yield cpv + else: + # Consume the smaller pkg set: + installed_cpvs = set(all_installed_cpvs) + for cpv in all_cpvs: + if cpv not in installed_cpvs: + yield cpv + + +# pylint thinks this is a global variable +# pylint: disable-msg=C0103 +get_uninstalled_cpvs = partial(get_cpvs, include_installed=False) + + +def get_installed_cpvs(predicate=None): + """Get all installed packages. Optionally apply a predicate. + + @type predicate: function + @param predicate: a function to filter the package list with + @rtype: generator + @return: a generator that yields unsorted installed cat/pkg-ver strings + from VARDB + """ + + if predicate: + installed_cps = iter(x for x in VARDB.cp_all() if predicate(x)) + else: + installed_cps = VARDB.cp_all() + + for cpv in chain.from_iterable(VARDB.cp_list(x) for x in installed_cps): + yield cpv + + +def print_query_info(query, query_opts): + """Print info about the query to the screen.""" + + cat, pkg = split_cpv(query)[:2] + if cat and not query_opts["isRegex"]: + cat_str = "in %s " % pp.emph(cat.lstrip('><=~!')) + else: + cat_str = "" + + if query_opts["isRegex"]: + pkg_str = query + else: + pkg_str = pkg + + print " * Searching for %s %s..." % (pp.emph(pkg_str), cat_str) + + +def print_file(path): + """Display the contents of a file.""" + + with open(path) as open_file: + lines = open_file.read() + print lines.strip() + + +def print_sequence(seq): + """Print every item of a sequence.""" + + for item in seq: + print item + + +def split_cpv(query): + """Split a cpv into category, name, version and revision. + + @type query: str + @param query: pkg, cat/pkg, pkg-ver, cat/pkg-ver, atom or regex + @rtype: tuple + @return: (category, pkg_name, version, revision) + Each tuple element is a string or empty string (""). + """ + + result = catpkgsplit(query) + + if result: + result = list(result) + if result[0] == 'null': + result[0] = '' + if result[3] == 'r0': + result[3] = '' + else: + result = query.split("/") + if len(result) == 1: + result = ['', query, '', ''] + else: + result = result + ['', ''] + + if len(result) != 4: + raise errors.GentoolkitInvalidPackageName(query) + + return tuple(result) + + +def uniqify(seq, preserve_order=True): + """Return a uniqified list. Optionally preserve order.""" + + if preserve_order: + seen = set() + result = [x for x in seq if x not in seen and not seen.add(x)] + else: + result = list(set(seq)) + + return result + + +def uses_globbing(query): + """Check the query to see if it is using globbing. + + @type query: str + @param query: user input package query + @rtype: bool + @return: True if query uses globbing, else False + """ + + if set('!*?[]').intersection(query): + # Is query an atom such as '=sys-apps/portage-2.2*'? + if query[0] != '=': + return True + + return False + +# vim: set ts=4 sw=4 tw=79: diff --git a/gentoolkit/pym/gentoolkit/metadata.py b/gentoolkit/pym/gentoolkit/metadata.py new file mode 100644 index 0000000..792e65f --- /dev/null +++ b/gentoolkit/pym/gentoolkit/metadata.py @@ -0,0 +1,302 @@ +#!/usr/bin/python +# +# Copyright(c) 2009, Gentoo Foundation +# +# Licensed under the GNU General Public License, v2 +# +# $Header$ + +"""Provides an easy-to-use python interface to Gentoo's metadata.xml file. + + Example usage: + >>> from gentoolkit.metadata import MetaData + >>> pkg_md = MetaData('/usr/portage/app-misc/gourmet/metadata.xml') + >>> pkg_md + + >>> pkg_md.herds() + ['no-herd'] + >>> for maint in pkg_md.maintainers(): + ... print "{0} ({1})".format(maint.email, maint.name) + ... + nixphoeni@gentoo.org (Joe Sapp) + >>> for flag in pkg_md.use(): + ... print flag.name, "->", flag.description + ... + rtf -> Enable export to RTF + gnome-print -> Enable printing support using gnome-print + >>> upstream = pkg_md.upstream() + >>> upstream + [<_Upstream {'docs': [], 'remoteid': [], 'maintainer': + [<_Maintainer 'Thomas_Hinkle@alumni.brown.edu'>], 'bugtracker': [], + 'changelog': []}>] + >>> upstream[0].maintainer[0].name + 'Thomas Mills Hinkle' +""" + +# Move to Imports section after Python-2.6 is stable +from __future__ import with_statement + +__all__ = ('MetaData',) +__docformat__ = 'epytext' + +# ======= +# Imports +# ======= + +import re +import os +import xml.etree.cElementTree as etree + +from portage import settings + +# ======= +# Classes +# ======= + +class _Maintainer(object): + """An object for representing one maintainer. + + @type email: str or None + @ivar email: Maintainer's email address. Used for both Gentoo and upstream. + @type name: str or None + @ivar name: Maintainer's name. Used for both Gentoo and upstream. + @type description: str or None + @ivar description: Description of what a maintainer does. Gentoo only. + @type restrict: str or None + @ivar restrict: e.g. >=portage-2.2 means only maintains versions + of Portage greater than 2.2. + @type status: str or None + @ivar status: If set, either 'active' or 'inactive'. Upstream only. + """ + + def __init__(self, node): + self.email = None + self.name = None + self.description = None + self.restrict = node.get('restrict') + self.status = node.get('status') + maint_attrs = node.getchildren() + for attr in maint_attrs: + setattr(self, attr.tag, attr.text) + + def __repr__(self): + return "<%s %r>" % (self.__class__.__name__, self.email) + + +class _Useflag(object): + """An object for representing one USE flag. + + @todo: Is there any way to have a keyword option to leave in + and for later processing? + @type name: str or None + @ivar name: USE flag + @type restrict: str or None + @ivar restrict: e.g. >=portage-2.2 means flag is only avaiable in + versions greater than 2.2 + @type description: str + @ivar description: description of the USE flag + """ + + def __init__(self, node): + self.name = node.get('name') + self.restrict = node.get('restrict') + _desc = '' + if node.text: + _desc = node.text + for child in node.getchildren(): + _desc += child.text if child.text else '' + _desc += child.tail if child.tail else '' + # This takes care of tabs and newlines left from the file + self.description = re.sub('\s+', ' ', _desc) + + def __repr__(self): + return "<%s %r>" % (self.__class__.__name__, self.name) + + +class _Upstream(object): + """An object for representing one package's upstream. + + @type maintainers: list + @ivar maintainers: L{_Maintainer} objects for each upstream maintainer + @type changelogs: list + @ivar changelogs: URLs to upstream's ChangeLog file in str format + @type docs: list + @ivar docs: Sequence of tuples containing URLs to upstream documentation + in the first slot and 'lang' attribute in the second, e.g., + [('http.../docs/en/tut.html', None), ('http.../doc/fr/tut.html', 'fr')] + @type bugtrackers: list + @ivar bugtrackers: URLs to upstream's bugtracker. May also contain an email + address if prepended with 'mailto:' + @type remoteids: list + @ivar remoteids: Sequence of tuples containing the project's hosting site + name in the first slot and the project's ID name or number for that + site in the second, e.g., [('sourceforge', 'systemrescuecd')] + """ + + def __init__(self, node): + self.node = node + self.maintainers = self.upstream_maintainers() + self.changelogs = self.upstream_changelogs() + self.docs = self.upstream_documentation() + self.bugtrackers = self.upstream_bugtrackers() + self.remoteids = self.upstream_remoteids() + + def __repr__(self): + return "<%s %r>" % (self.__class__.__name__, self.__dict__) + + def upstream_bugtrackers(self): + """Retrieve upstream bugtracker location from xml node.""" + return [e.text for e in self.node.findall('bugs-to')] + + def upstream_changelogs(self): + """Retrieve upstream changelog location from xml node.""" + return [e.text for e in self.node.findall('changelog')] + + def upstream_documentation(self): + """Retrieve upstream documentation location from xml node.""" + result = [] + for elem in self.node.findall('doc'): + lang = elem.get('lang') + result.append((elem.text, lang)) + return result + + def upstream_maintainers(self): + """Retrieve upstream maintainer information from xml node.""" + return [_Maintainer(m) for m in self.node.findall('maintainer')] + + def upstream_remoteids(self): + """Retrieve upstream remote ID from xml node.""" + return [(e.text, e.get('type')) for e in self.node.findall('remote-id')] + + +class MetaData(object): + """Access metadata.xml""" + + def __init__(self, metadata_path): + """Parse a valid metadata.xml file. + + @type metadata_path: str + @param metadata_path: path to a valid metadata.xml file + @raise IOError: if C{metadata_path} can not be read + """ + + self.metadata_path = metadata_path + self._xml_tree = etree.parse(metadata_path) + + # Used for caching + self._herdstree = None + self._descriptions = None + self._maintainers = None + self._useflags = None + self._upstream = None + + def __repr__(self): + return "<%s %r>" % (self.__class__.__name__, self.metadata_path) + + def _get_herd_email(self, herd): + """Get a herd's email address. + + @type herd: str + @param herd: herd whose email you want + @rtype: str or None + @return: email address or None if herd is not in herds.xml + @raise IOError: if $PORTDIR/metadata/herds.xml can not be read + """ + + if self._herdstree is None: + herds_path = os.path.join(settings['PORTDIR'], 'metadata/herds.xml') + self._herdstree = etree.parse(herds_path) + + # Some special herds are not listed in herds.xml + if herd in ('no-herd', 'maintainer-wanted', 'maintainer-needed'): + return None + + for node in self._herdstree.getiterator('herd'): + if node.findtext('name') == herd: + return node.findtext('email') + + def herds(self, include_email=False): + """Return a list of text nodes for . + + @type include_email: bool + @keyword include_email: if True, also look up the herd's email + @rtype: list + @return: if include_email is False, return a list of string; + if include_email is True, return a list of tuples containing: + [('herd1', 'herd1@gentoo.org'), ('no-herd', None); + """ + + result = [] + for elem in self._xml_tree.findall('herd'): + if include_email: + herd_mail = self._get_herd_email(elem.text) + result.append((elem.text, herd_mail)) + else: + result.append(elem.text) + + return result + + def descriptions(self): + """Return a list of text nodes for . + + @rtype: list + @return: package description in string format + @todo: Support the C{lang} attribute + """ + + if self._descriptions is not None: + return self._descriptions + + long_descriptions = self._xml_tree.findall("longdescription") + self._descriptions = [e.text for e in long_descriptions] + return self._descriptions + + def maintainers(self): + """Get maintainers' name, email and description. + + @rtype: list + @return: a sequence of L{_Maintainer} objects in document order. + """ + + if self._maintainers is not None: + return self._maintainers + + self._maintainers = [] + for node in self._xml_tree.findall('maintainer'): + self._maintainers.append(_Maintainer(node)) + + return self._maintainers + + def use(self): + """Get names and descriptions for USE flags defined in metadata. + + @rtype: list + @return: a sequence of L{_Useflag} objects in document order. + """ + + if self._useflags is not None: + return self._useflags + + self._useflags = [] + for node in self._xml_tree.getiterator('flag'): + self._useflags.append(_Useflag(node)) + + return self._useflags + + def upstream(self): + """Get upstream contact information. + + @rtype: list + @return: a sequence of L{_Upstream} objects in document order. + """ + + if self._upstream is not None: + return self._upstream + + self._upstream = [] + for node in self._xml_tree.findall('upstream'): + self._upstream.append(_Upstream(node)) + + return self._upstream + +# vim: set ts=4 sw=4 tw=79: diff --git a/gentoolkit/pym/gentoolkit/package.py b/gentoolkit/pym/gentoolkit/package.py new file mode 100644 index 0000000..c020f63 --- /dev/null +++ b/gentoolkit/pym/gentoolkit/package.py @@ -0,0 +1,459 @@ +#!/usr/bin/python +# +# Copyright(c) 2004, Karl Trygve Kalleberg +# Copyright(c) 2004-2009, Gentoo Foundation +# +# Licensed under the GNU General Public License, v2 +# +# $Header$ + +"""Provides an interface to package information stored by package managers. + +The Package class is the heart of much of Gentoolkit. Given a CPV +(category/package-version) string, it can reveal the package's status in the +tree and VARDB (/var/db/), provide rich comparison and sorting, and expose +important parts of Portage's back-end. + +Example usage: + >>> portage = Package('sys-apps/portage-2.1.6.13') + >>> portage.ebuild_path() + '/usr/portage/sys-apps/portage/portage-2.1.6.13.ebuild' + >>> portage.is_masked() + False + >>> portage.is_installed() + True +""" + +__all__ = ( + 'Package', + 'PackageFormatter' +) + +# ======= +# Imports +# ======= + +import os + +import portage +from portage import settings + +import gentoolkit.pprinter as pp +from gentoolkit import errors +from gentoolkit.cpv import CPV +from gentoolkit.dbapi import PORTDB, VARDB +from gentoolkit.dependencies import Dependencies +from gentoolkit.metadata import MetaData + +# ======= +# Classes +# ======= + +class Package(CPV): + """Exposes the state of a given CPV.""" + + def __init__(self, cpv): + if isinstance(cpv, CPV): + self.cpv = cpv + else: + self.cpv = CPV(cpv) + del cpv + + if not all(getattr(self.cpv, x) for x in ('category', 'version')): + # CPV allows some things that Package must not + raise errors.GentoolkitInvalidPackage(str(self.cpv)) + + # Set dynamically + self._package_path = None + self._dblink = None + self._metadata = None + self._deps = None + self._portdir_path = None + + def __repr__(self): + return "<%s %r>" % (self.__class__.__name__, str(self.cpv)) + + def __eq__(self, other): + if not hasattr(other, 'cpv'): + return False + return self.cpv == other.cpv + + def __ne__(self, other): + return not self == other + + def __lt__(self, other): + return self.cpv < other.cpv + + def __gt__(self, other): + return self.cpv > other.cpv + + def __hash__(self): + return hash(str(self.cpv)) + + def __contains__(self, key): + return key in str(self.cpv) + + def __str__(self): + return str(self.cpv) + + @property + def metadata(self): + """Instantiate a L{gentoolkit.metadata.MetaData} object here.""" + + if self._metadata is None: + metadata_path = os.path.join( + self.package_path(), 'metadata.xml' + ) + self._metadata = MetaData(metadata_path) + + return self._metadata + + @property + def dblink(self): + """Instantiate a L{portage.dbapi.vartree.dblink} object here.""" + + if self._dblink is None: + self._dblink = portage.dblink( + self.cpv.category, + "%s-%s" % (self.cpv.name, self.cpv.fullversion), + settings["ROOT"], + settings + ) + + return self._dblink + + @property + def deps(self): + """Instantiate a L{gentoolkit.dependencies.Dependencies} object here.""" + + if self._deps is None: + self._deps = Dependencies(self.cpv) + + return self._deps + + def environment(self, envvars, prefer_vdb=True, no_fallback=False): + """Returns one or more of the predefined environment variables. + + Available envvars are: + ---------------------- + BINPKGMD5 COUNTER FEATURES LICENSE SRC_URI + CATEGORY CXXFLAGS HOMEPAGE PDEPEND USE + CBUILD DEFINED_PHASES INHERITED PF + CFLAGS DEPEND IUSE PROVIDE + CHOST DESCRIPTION KEYWORDS RDEPEND + CONTENTS EAPI LDFLAGS SLOT + + Example usage: + >>> pkg = Package('sys-apps/portage-2.1.6.13') + >>> pkg.environment('USE') + 'elibc_glibc kernel_linux userland_GNU x86' + >>> pkg.environment(('USE', 'IUSE')) + ['elibc_glibc kernel_linux userland_GNU x86', + 'build doc epydoc selinux linguas_pl'] + + @type envvars: str or array + @param envvars: one or more of (DEPEND, SRC_URI, etc.) + @type prefer_vdb: bool + @keyword prefer_vdb: if True, look in the vardb before portdb, else + reverse order. Specifically KEYWORDS will get more recent + information by preferring portdb. + @type no_fallback: bool + @keyword no_fallback: query only the preferred db + @rtype: str or list + @return: str if envvars is str, list if envvars is array + @raise KeyError: if key is not found in requested db(s) + """ + + got_string = False + if isinstance(envvars, basestring): + got_string = True + envvars = (envvars,) + if prefer_vdb: + try: + result = VARDB.aux_get(str(self.cpv), envvars) + except KeyError: + try: + if no_fallback: + raise KeyError + result = PORTDB.aux_get(str(self.cpv), envvars) + except KeyError: + err = "aux_get returned unexpected results" + raise errors.GentoolkitFatalError(err) + else: + try: + result = PORTDB.aux_get(str(self.cpv), envvars) + except KeyError: + try: + if no_fallback: + raise KeyError + result = VARDB.aux_get(str(self.cpv), envvars) + except KeyError: + err = "aux_get returned unexpected results" + raise errors.GentoolkitFatalError(err) + + if got_string: + return result[0] + return result + + def exists(self): + """Return True if package exists in the Portage tree, else False""" + + return bool(PORTDB.cpv_exists(str(self.cpv))) + + @staticmethod + def settings(key): + """Returns the value of the given key for this package (useful + for package.* files.""" + + if settings.locked: + settings.unlock() + try: + result = settings[key] + finally: + settings.lock() + return result + + def mask_status(self): + """Shortcut to L{portage.getmaskingstatus}. + + @rtype: None or list + @return: a list containing none or some of: + 'profile' + 'package.mask' + license(s) + "kmask" keyword + 'missing keyword' + """ + + if settings.locked: + settings.unlock() + try: + result = portage.getmaskingstatus(str(self.cpv), + settings=settings, + portdb=PORTDB) + except KeyError: + # getmaskingstatus doesn't support packages without ebuilds in the + # Portage tree. + result = None + + return result + + def mask_reason(self): + """Shortcut to L{portage.getmaskingreason}. + + @rtype: None or tuple + @return: empty tuple if pkg not masked OR + ('mask reason', 'mask location') + """ + + try: + result = portage.getmaskingreason(str(self.cpv), + settings=settings, + portdb=PORTDB, + return_location=True) + if result is None: + result = tuple() + except KeyError: + # getmaskingstatus doesn't support packages without ebuilds in the + # Portage tree. + result = None + + return result + + def ebuild_path(self, in_vartree=False): + """Returns the complete path to the .ebuild file. + + Example usage: + >>> pkg.ebuild_path() + '/usr/portage/sys-apps/portage/portage-2.1.6.13.ebuild' + >>> pkg.ebuild_path(in_vartree=True) + '/var/db/pkg/sys-apps/portage-2.1.6.13/portage-2.1.6.13.ebuild' + """ + + if in_vartree: + return VARDB.findname(str(self.cpv)) + return PORTDB.findname(str(self.cpv)) + + def package_path(self, in_vartree=False): + """Return the path to where the ebuilds and other files reside.""" + + if in_vartree: + return self.dblink.getpath() + return os.sep.join(self.ebuild_path().split(os.sep)[:-1]) + + def repo_id(self): + """Using the package path, determine the repository id. + + @rtype: str + @return: /usr/portage/category/name/ + """ + + return self.package_path().split(os.sep)[-3] + + def use(self): + """Returns the USE flags active at time of installation.""" + + return self.dblink.getstring("USE") + + def parsed_contents(self): + """Returns the parsed CONTENTS file. + + @rtype: dict + @return: {'/full/path/to/obj': ['type', 'timestamp', 'md5sum'], ...} + """ + + return self.dblink.getcontents() + + def size(self): + """Estimates the installed size of the contents of this package. + + @rtype: tuple + @return: (size, number of files in total, number of uncounted files) + """ + + contents = self.parsed_contents() + size = n_uncounted = n_files = 0 + for cfile in contents: + try: + size += os.lstat(cfile).st_size + n_files += 1 + except OSError: + n_uncounted += 1 + return (size, n_files, n_uncounted) + + def is_installed(self): + """Returns True if this package is installed (merged)""" + + return self.dblink.exists() + + def is_overlay(self): + """Returns True if the package is in an overlay.""" + + ebuild, tree = PORTDB.findname2(str(self.cpv)) + if not ebuild: + return None + if self._portdir_path is None: + self._portdir_path = os.path.realpath(settings["PORTDIR"]) + return (tree and tree != self._portdir_path) + + def is_masked(self): + """Returns true if this package is masked against installation. + Note: We blindly assume that the package actually exists on disk + somewhere.""" + + unmasked = PORTDB.xmatch("match-visible", str(self.cpv)) + return str(self.cpv) not in unmasked + + +class PackageFormatter(object): + """When applied to a L{gentoolkit.package.Package} object, determine the + location (Portage Tree vs. overlay), install status and masked status. That + information can then be easily formatted and displayed. + + Example usage: + >>> from gentoolkit.helpers import find_packages + >>> from gentoolkit.package import PackageFormatter + >>> pkgs = [PackageFormatter(x) for x in find_packages('gcc')] + >>> for pkg in pkgs: + ... # Only print packages that are installed and from the Portage + ... # tree + ... if set('IP').issubset(pkg.location): + ... print pkg + ... + [IP-] [ ] sys-devel/gcc-4.3.2-r3 (4.3) + + @type pkg: L{gentoolkit.package.Package} + @param pkg: package to format + @type format: L{bool} + @param format: Whether to format the package name or not. + Essentially C{format} should be set to False when piping or when + quiet output is desired. If C{do_format} is False, only the location + attribute will be created to save time. + """ + + def __init__(self, pkg, do_format=True): + self.pkg = pkg + self.do_format = do_format + self.location = self.format_package_location() or '' + + def __repr__(self): + return "<%s %s @%#8x>" % (self.__class__.__name__, self.pkg, id(self)) + + def __str__(self): + if self.do_format: + maskmodes = [' ', ' ~', ' -', 'M ', 'M~', 'M-', 'XX'] + maskmode = maskmodes[self.format_mask_status()[0]] + return "[%(location)s] [%(mask)s] %(package)s:%(slot)s" % { + 'location': self.location, + 'mask': pp.keyword( + maskmode, + stable=not maskmode.strip(), + hard_masked=set(('M', 'X', '-')).intersection(maskmode) + ), + 'package': pp.cpv(str(self.pkg.cpv)), + 'slot': pp.slot(self.pkg.environment("SLOT")) + } + else: + return str(self.pkg.cpv) + + def format_package_location(self): + """Get the install status (in /var/db/?) and origin (from and overlay + and the Portage tree?). + + @rtype: str + @return: one of: + 'I--' : Installed but ebuild doesn't exist on system anymore + '-P-' : Not installed and from the Portage tree + '--O' : Not installed and from an overlay + 'IP-' : Installed and from the Portage tree + 'I-O' : Installed and from an overlay + """ + + result = ['-', '-', '-'] + + if self.pkg.is_installed(): + result[0] = 'I' + + overlay = self.pkg.is_overlay() + if overlay is None: + pass + elif overlay: + result[2] = 'O' + else: + result[1] = 'P' + + return ''.join(result) + + def format_mask_status(self): + """Get the mask status of a given package. + + @rtype: tuple: (int, list) + @return: int = an index for this list: + [" ", " ~", " -", "M ", "M~", "M-", "XX"] + 0 = not masked + 1 = keyword masked + 2 = arch masked + 3 = hard masked + 4 = hard and keyword masked, + 5 = hard and arch masked + 6 = ebuild doesn't exist on system anymore + + list = original output of portage.getmaskingstatus + """ + + result = 0 + masking_status = self.pkg.mask_status() + if masking_status is None: + return (6, []) + + if ("~%s keyword" % self.pkg.settings("ARCH")) in masking_status: + result += 1 + if "missing keyword" in masking_status: + result += 2 + if set(('profile', 'package.mask')).intersection(masking_status): + result += 3 + + return (result, masking_status) + + +# vim: set ts=4 sw=4 tw=79: diff --git a/gentoolkit/pym/gentoolkit/pprinter.py b/gentoolkit/pym/gentoolkit/pprinter.py new file mode 100644 index 0000000..bd5e6cb --- /dev/null +++ b/gentoolkit/pym/gentoolkit/pprinter.py @@ -0,0 +1,131 @@ +#!/usr/bin/python +# +# Copyright 2004 Karl Trygve Kalleberg +# Copyright 2004-2009 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# +# $Header$ + +"""Provides a consistent color scheme for Gentoolkit scripts.""" + +__all__ = ( + 'command', + 'cpv', + 'die', + 'emph', + 'error', + 'globaloption', + 'installedflag', + 'localoption', + 'number', + 'path', + 'path_symlink', + 'pkgquery', + 'productname', + 'regexpquery', + 'section', + 'slot', + 'subsection', + 'useflag', + 'warn' +) + +# ======= +# Imports +# ======= + +import sys + +import portage.output as output + +# ========= +# Functions +# ========= + +# output creates color functions on the fly, which confuses pylint. +# E1101: *%s %r has no %r member* +# pylint: disable-msg=E1101 + +def command(string): + """Returns a program command string.""" + return output.green(string) + +def cpv(string): + """Returns a category/package- string.""" + return output.green(string) + +def die(err, string): + """Returns an error string and die with an error code.""" + sys.stderr.write(error(string)) + sys.exit(err) + +def emph(string): + """Returns a string as emphasized.""" + return output.bold(string) + +def error(string): + """Prints an error string.""" + return output.red("!!! ") + string + "\n" + +def globaloption(string): + """Returns a global option string, i.e. the program global options.""" + return output.yellow(string) + +def localoption(string): + """Returns a local option string, i.e. the program local options.""" + return output.green(string) + +def number(string): + """Returns a number string.""" + return output.turquoise(string) + +def path(string): + """Returns a file or directory path string.""" + return output.bold(string) + +def path_symlink(string): + """Returns a symlink string.""" + return output.turquoise(string) + +def pkgquery(string): + """Returns a package query string.""" + return output.bold(string) + +def productname(string): + """Returns a product name string, i.e. the program name.""" + return output.turquoise(string) + +def regexpquery(string): + """Returns a regular expression string.""" + return output.bold(string) + +def section(string): + """Returns a string as a section header.""" + return output.turquoise(string) + +def slot(string): + """Returns a slot string""" + return output.bold(string) + +def subsection(string): + """Returns a string as a subsection header.""" + return output.turquoise(string) + +def useflag(string, enabled=True): + """Returns a USE flag string.""" + return output.blue(string) if enabled else output.red(string) + +def keyword(string, stable=True, hard_masked=False): + """Returns a keyword string.""" + if stable: + return output.green(string) + if hard_masked: + return output.red(string) + # keyword masked: + return output.blue(string) + +def warn(string): + """Returns a warning string.""" + return "!!! " + string + "\n" + +# vim: set ts=4 sw=4 tw=79: diff --git a/gentoolkit/pym/gentoolkit/query.py b/gentoolkit/pym/gentoolkit/query.py new file mode 100644 index 0000000..24f8c18 --- /dev/null +++ b/gentoolkit/pym/gentoolkit/query.py @@ -0,0 +1,34 @@ +#!/usr/bin/python +# +# Copyright(c) 2004-2009, Gentoo Foundation +# +# Licensed under the GNU General Public License, v2 +# +# $Header$ + +"""Provides common methods on a package query.""" + +__all__ = ( + 'Query', +) + +# ======= +# Imports +# ======= + +from gentoolkit.cpv import CPV +#from gentoolkit.helpers import * + +# ======= +# Classes +# ======= + +class Query(CPV): + """Provides common methods on a package query.""" + + def __init__(self, cpv): + if isinstance(cpv, CPV): + self.cpv = cpv + else: + self.cpv = CPV(cpv) + del cpv diff --git a/gentoolkit/pym/gentoolkit/test/__init__.py b/gentoolkit/pym/gentoolkit/test/__init__.py new file mode 100644 index 0000000..94423e9 --- /dev/null +++ b/gentoolkit/pym/gentoolkit/test/__init__.py @@ -0,0 +1,6 @@ +#!/usr/bin/python +# Copyright 2009 Gentoo Foundation +# +# Distributed under the terms of the GNU General Public License v2 +# +# $Header$ diff --git a/gentoolkit/pym/gentoolkit/test/equery/__init__.py b/gentoolkit/pym/gentoolkit/test/equery/__init__.py new file mode 100644 index 0000000..94423e9 --- /dev/null +++ b/gentoolkit/pym/gentoolkit/test/equery/__init__.py @@ -0,0 +1,6 @@ +#!/usr/bin/python +# Copyright 2009 Gentoo Foundation +# +# Distributed under the terms of the GNU General Public License v2 +# +# $Header$ diff --git a/gentoolkit/pym/gentoolkit/test/equery/test_init.py b/gentoolkit/pym/gentoolkit/test/equery/test_init.py new file mode 100644 index 0000000..98e2648 --- /dev/null +++ b/gentoolkit/pym/gentoolkit/test/equery/test_init.py @@ -0,0 +1,46 @@ +import unittest +from test import test_support + +from gentoolkit import equery + +class TestEqueryInit(unittest.TestCase): + + def setUp(self): + pass + + def tearDown(self): + pass + + def test_expand_module_name(self): + # Test that module names are properly expanded + name_map = { + 'b': 'belongs', + 'c': 'changes', + 'k': 'check', + 'd': 'depends', + 'g': 'depgraph', + 'f': 'files', + 'h': 'hasuse', + 'l': 'list_', + 'm': 'meta', + 's': 'size', + 'u': 'uses', + 'w': 'which' + } + self.failUnlessEqual(equery.NAME_MAP, name_map) + for short_name, long_name in zip(name_map, name_map.values()): + self.failUnlessEqual(equery.expand_module_name(short_name), + long_name) + self.failUnlessEqual(equery.expand_module_name(long_name), + long_name) + unused_keys = set(map(chr, range(0, 256))).difference(name_map.keys()) + for key in unused_keys: + self.failUnlessRaises(KeyError, equery.expand_module_name, key) + + +def test_main(): + test_support.run_unittest(TestEqueryInit) + + +if __name__ == '__main__': + test_main() diff --git a/gentoolkit/pym/gentoolkit/test/test_atom.py b/gentoolkit/pym/gentoolkit/test/test_atom.py new file mode 100644 index 0000000..4a1568b --- /dev/null +++ b/gentoolkit/pym/gentoolkit/test/test_atom.py @@ -0,0 +1,149 @@ +# Copyright(c) 2009, Gentoo Foundation +# Copyright: 2006-2008 Brian Harring +# +# License: GPL2/BSD + +# $Header$ + +import unittest +from test import test_support + +from gentoolkit.atom import * + +"""Atom test suite (verbatim) from pkgcore.""" + +class TestGentoolkitAtom(unittest.TestCase): + + def assertEqual2(self, o1, o2): + # logic bugs hidden behind short circuiting comparisons for metadata + # is why we test the comparison *both* ways. + self.assertEqual(o1, o2) + c = cmp(o1, o2) + self.assertEqual(c, 0, + msg="checking cmp for %r, %r, aren't equal: got %i" % (o1, o2, c)) + self.assertEqual(o2, o1) + c = cmp(o2, o1) + self.assertEqual(c, 0, + msg="checking cmp for %r, %r,aren't equal: got %i" % (o2, o1, c)) + + def assertNotEqual2(self, o1, o2): + # is why we test the comparison *both* ways. + self.assertNotEqual(o1, o2) + c = cmp(o1, o2) + self.assertNotEqual(c, 0, + msg="checking cmp for %r, %r, not supposed to be equal, got %i" + % (o1, o2, c)) + self.assertNotEqual(o2, o1) + c = cmp(o2, o1) + self.assertNotEqual(c, 0, + msg="checking cmp for %r, %r, not supposed to be equal, got %i" + % (o2, o1, c)) + + def test_comparison(self): + self.assertEqual2(Atom('cat/pkg'), Atom('cat/pkg')) + self.assertNotEqual2(Atom('cat/pkg'), Atom('cat/pkgb')) + self.assertNotEqual2(Atom('cata/pkg'), Atom('cat/pkg')) + self.assertNotEqual2(Atom('cat/pkg'), Atom('!cat/pkg')) + self.assertEqual2(Atom('!cat/pkg'), Atom('!cat/pkg')) + self.assertNotEqual2(Atom('=cat/pkg-0.1:0'), + Atom('=cat/pkg-0.1')) + self.assertNotEqual2(Atom('=cat/pkg-1[foon]'), + Atom('=cat/pkg-1')) + self.assertEqual2(Atom('=cat/pkg-0'), Atom('=cat/pkg-0')) + self.assertNotEqual2(Atom('cat/pkg-2')) + self.assertNotEqual2(Atom('=cat/pkg-2*'), Atom('=cat/pkg-2')) + # Portage Atom doesn't have 'negate_version' capability + #self.assertNotEqual2(Atom('=cat/pkg-2', True), Atom('=cat/pkg-2')) + + # use... + self.assertNotEqual2(Atom('cat/pkg[foo]'), Atom('cat/pkg')) + self.assertNotEqual2(Atom('cat/pkg[foo]'), + Atom('cat/pkg[-foo]')) + self.assertEqual2(Atom('cat/pkg[foo,-bar]'), + Atom('cat/pkg[-bar,foo]')) + + # repoid not supported by Portage Atom yet + ## repoid + #self.assertEqual2(Atom('cat/pkg::a'), Atom('cat/pkg::a')) + #self.assertNotEqual2(Atom('cat/pkg::a'), Atom('cat/pkg::b')) + #self.assertNotEqual2(Atom('cat/pkg::a'), Atom('cat/pkg')) + + # slots. + self.assertNotEqual2(Atom('cat/pkg:1'), Atom('cat/pkg')) + self.assertEqual2(Atom('cat/pkg:2'), Atom('cat/pkg:2')) + # http://dev.gentoo.org/~tanderson/pms/eapi-2-approved/pms.html#x1-190002.1.2 + self.assertEqual2(Atom('cat/pkg:AZaz09+_.-'), Atom('cat/pkg:AZaz09+_.-')) + for lesser, greater in (('0.1', '1'), ('1', '1-r1'), ('1.1', '1.2')): + self.assertTrue(Atom('=d/b-%s' % lesser) < + Atom('=d/b-%s' % greater), + msg="d/b-%s < d/b-%s" % (lesser, greater)) + self.assertFalse(Atom('=d/b-%s' % lesser) > + Atom('=d/b-%s' % greater), + msg="!: d/b-%s < d/b-%s" % (lesser, greater)) + self.assertTrue(Atom('=d/b-%s' % greater) > + Atom('=d/b-%s' % lesser), + msg="d/b-%s > d/b-%s" % (greater, lesser)) + self.assertFalse(Atom('=d/b-%s' % greater) < + Atom('=d/b-%s' % lesser), + msg="!: d/b-%s > d/b-%s" % (greater, lesser)) + + #self.assertTrue(Atom("!!=d/b-1", eapi=2) > Atom("!=d/b-1")) + self.assertTrue(Atom("!=d/b-1") < Atom("!!=d/b-1")) + self.assertEqual(Atom("!=d/b-1"), Atom("!=d/b-1")) + + def test_intersects(self): + for this, that, result in [ + ('cat/pkg', 'pkg/cat', False), + ('cat/pkg', 'cat/pkg', True), + ('cat/pkg:1', 'cat/pkg:1', True), + ('cat/pkg:1', 'cat/pkg:2', False), + ('cat/pkg:1', 'cat/pkg[foo]', True), + ('cat/pkg[foo]', 'cat/pkg[-bar]', True), + ('cat/pkg[foo]', 'cat/pkg[-foo]', False), + ('>cat/pkg-3', '>cat/pkg-1', True), + ('>cat/pkg-3', '=cat/pkg-3', 'cat/pkg-2', '=cat/pkg-2*', True), + # Portage vercmp disagrees with this one: + #('cat/pkg-2', False), + ('=cat/pkg-2', '>=cat/pkg-2', True), + ('~cat/pkg-2', '~cat/pkg-2', True), + ('~cat/pkg-2', '~cat/pkg-2.1', False), + ('=cat/pkg-2*', '=cat/pkg-2.3*', True), + ('>cat/pkg-2.4', '=cat/pkg-2*', True), + ('cat/pkg-2-r1', True), + ('~cat/pkg-2', '<=cat/pkg-2', True), + ('=cat/pkg-2-r2*', '<=cat/pkg-2-r20', True), + ('=cat/pkg-2-r2*', 'cat/pkg-2', False), + ('>=cat/pkg-8.4', '=cat/pkg-8.3.4*', False), + # Repos not yet supported by Portage + #('cat/pkg::gentoo', 'cat/pkg', True), + #('cat/pkg::gentoo', 'cat/pkg::foo', False), + ('=sys-devel/gcc-4.1.1-r3', '=sys-devel/gcc-3.3*', False), + ('=sys-libs/db-4*', '~sys-libs/db-4.3.29', True), + ]: + this_atom = Atom(this) + that_atom = Atom(that) + self.assertEqual( + result, this_atom.intersects(that_atom), + '%s intersecting %s should be %s' % (this, that, result)) + self.assertEqual( + result, that_atom.intersects(this_atom), + '%s intersecting %s should be %s' % (that, this, result)) + + +def test_main(): + test_support.run_unittest(TestGentoolkitAtom) + +if __name__ == '__main__': + test_main() diff --git a/gentoolkit/pym/gentoolkit/test/test_cpv.py b/gentoolkit/pym/gentoolkit/test/test_cpv.py new file mode 100644 index 0000000..9b36cc3 --- /dev/null +++ b/gentoolkit/pym/gentoolkit/test/test_cpv.py @@ -0,0 +1,59 @@ +#!/usr/bin/python +# +# Copyright(c) 2009, Gentoo Foundation +# +# Licensed under the GNU General Public License, v2 +# +# $Header$ + +import unittest +from test import test_support + +from gentoolkit.cpv import * + +class TestGentoolkitCPV(unittest.TestCase): + + def assertEqual2(self, o1, o2): + # logic bugs hidden behind short circuiting comparisons for metadata + # is why we test the comparison *both* ways. + self.assertEqual(o1, o2) + c = cmp(o1, o2) + self.assertEqual(c, 0, + msg="checking cmp for %r, %r, aren't equal: got %i" % (o1, o2, c)) + self.assertEqual(o2, o1) + c = cmp(o2, o1) + self.assertEqual(c, 0, + msg="checking cmp for %r, %r,aren't equal: got %i" % (o2, o1, c)) + + def assertNotEqual2(self, o1, o2): + # is why we test the comparison *both* ways. + self.assertNotEqual(o1, o2) + c = cmp(o1, o2) + self.assertNotEqual(c, 0, + msg="checking cmp for %r, %r, not supposed to be equal, got %i" + % (o1, o2, c)) + self.assertNotEqual(o2, o1) + c = cmp(o2, o1) + self.assertNotEqual(c, 0, + msg="checking cmp for %r, %r, not supposed to be equal, got %i" + % (o2, o1, c)) + + def test_comparison(self): + self.assertEqual2(CPV('pkg'), CPV('pkg')) + self.assertNotEqual2(CPV('pkg'), CPV('pkg1')) + self.assertEqual2(CPV('cat/pkg'), CPV('cat/pkg')) + self.assertNotEqual2(CPV('cat/pkg'), CPV('cat/pkgb')) + self.assertNotEqual2(CPV('cata/pkg'), CPV('cat/pkg')) + self.assertEqual2(CPV('cat/pkg-0.1'), CPV('cat/pkg-0.1')) + self.assertNotEqual2(CPV('cat/pkg-1.0'), CPV('cat/pkg-1')) + self.assertEqual2(CPV('cat/pkg-0'), CPV('cat/pkg-0')) + self.assertEqual2(CPV('cat/pkg-1-r1'), CPV('cat/pkg-1-r1')) + self.assertNotEqual2(CPV('cat/pkg-2-r1'), CPV('cat/pkg-2-r10')) + self.assertEqual2(CPV('cat/pkg-1_rc2'), CPV('cat/pkg-1_rc2')) + self.assertNotEqual2(CPV('cat/pkg-2_rc2-r1'), CPV('cat/pkg-2_rc1-r1')) + +def test_main(): + test_support.run_unittest(TestGentoolkitCPV) + +if __name__ == '__main__': + test_main() diff --git a/gentoolkit/pym/gentoolkit/test/test_helpers.py b/gentoolkit/pym/gentoolkit/test/test_helpers.py new file mode 100644 index 0000000..e46e03b --- /dev/null +++ b/gentoolkit/pym/gentoolkit/test/test_helpers.py @@ -0,0 +1,107 @@ +import os +import unittest +import warnings +from tempfile import NamedTemporaryFile +from test import test_support + +from gentoolkit import helpers + + +class TestFileOwner(unittest.TestCase): + + def setUp(self): + pass + + def tearDown(self): + pass + + def test_extend_realpaths(self): + extend_realpaths = helpers.FileOwner.extend_realpaths + + # Test that symlinks's realpaths are extended + f1 = NamedTemporaryFile(prefix='equeryunittest') + f2 = NamedTemporaryFile(prefix='equeryunittest') + f3 = NamedTemporaryFile(prefix='equeryunittest') + with warnings.catch_warnings(): + warnings.simplefilter("ignore") + sym1 = os.tmpnam() + os.symlink(f1.name, sym1) + sym2 = os.tmpnam() + os.symlink(f3.name, sym2) + # We've created 3 files and 2 symlinks for testing. We're going to pass + # in only the first two files and both symlinks. sym1 points to f1. + # Since f1 is already in the list, sym1's realpath should not be added. + # sym2 points to f3, but f3's not in our list, so sym2's realpath + # should be added to the list. + p = [f1.name, f2.name, sym1, sym2] + p_xr = extend_realpaths(p) + + self.failUnlessEqual(p_xr[0], f1.name) + self.failUnlessEqual(p_xr[1], f2.name) + self.failUnlessEqual(p_xr[2], sym1) + self.failUnlessEqual(p_xr[3], sym2) + self.failUnlessEqual(p_xr[4], f3.name) + + # Clean up + os.unlink(sym1) + os.unlink(sym2) + + # Make sure we raise an exception if we don't get acceptable input + self.failUnlessRaises(AttributeError, extend_realpaths, 'str') + self.failUnlessRaises(AttributeError, extend_realpaths, set()) + + +class TestGentoolkitHelpers(unittest.TestCase): + + def test_compare_package_strings(self): + # Test ordering of package strings, Portage has test for vercmp, + # so just do the rest + version_tests = [ + # different categories + ('sys-apps/portage-2.1.6.8', 'sys-auth/pambase-20080318'), + # different package names + ('sys-apps/pkgcore-0.4.7.15-r1', 'sys-apps/portage-2.1.6.8'), + # different package versions + ('sys-apps/portage-2.1.6.8', 'sys-apps/portage-2.2_rc25') + ] + # Check less than + for vt in version_tests: + self.failUnless( + helpers.compare_package_strings(vt[0], vt[1]) == -1 + ) + # Check greater than + for vt in version_tests: + self.failUnless( + helpers.compare_package_strings(vt[1], vt[0]) == 1 + ) + # Check equal + vt = ('sys-auth/pambase-20080318', 'sys-auth/pambase-20080318') + self.failUnless( + helpers.compare_package_strings(vt[0], vt[1]) == 0 + ) + + def test_uses_globbing(self): + globbing_tests = [ + ('sys-apps/portage-2.1.6.13', False), + ('>=sys-apps/portage-2.1.6.13', False), + ('<=sys-apps/portage-2.1.6.13', False), + ('~sys-apps/portage-2.1.6.13', False), + ('=sys-apps/portage-2*', False), + ('sys-*/*-2.1.6.13', True), + ('sys-app?/portage-2.1.6.13', True), + ('sys-apps/[bp]ortage-2.1.6.13', True), + ('sys-apps/[!p]ortage*', True) + ] + + for gt in globbing_tests: + self.failUnless( + helpers.uses_globbing(gt[0]) == gt[1] + ) + + +def test_main(): + test_support.run_unittest(TestGentoolkitHelpers2) + + +if __name__ == '__main__': + test_main() diff --git a/gentoolkit/pym/gentoolkit/test/test_syntax.py b/gentoolkit/pym/gentoolkit/test/test_syntax.py new file mode 100644 index 0000000..bb7dcb4 --- /dev/null +++ b/gentoolkit/pym/gentoolkit/test/test_syntax.py @@ -0,0 +1,33 @@ +import os +import os.path as osp +import unittest +import py_compile + +"""Does a basic syntax check by compiling all modules. From Portage.""" + +pym_dirs = os.walk(osp.dirname(osp.dirname(osp.dirname(__file__)))) +blacklist_dirs = frozenset(('.svn', 'test')) + +class TestForSyntaxErrors(unittest.TestCase): + + def test_compileability(self): + compileables = [] + for thisdir, subdirs, files in pym_dirs: + if os.path.basename(thisdir) in blacklist_dirs: + continue + compileables.extend([ + osp.join(thisdir, f) + for f in files + if osp.splitext(f)[1] == '.py' + ]) + + for c in compileables: + py_compile.compile(c, doraise=True) + + +def test_main(): + test_support.run_unittest(TestGentoolkitHelpers2) + + +if __name__ == '__main__': + test_main() diff --git a/gentoolkit/pym/gentoolkit/textwrap_.py b/gentoolkit/pym/gentoolkit/textwrap_.py new file mode 100644 index 0000000..845ae9d --- /dev/null +++ b/gentoolkit/pym/gentoolkit/textwrap_.py @@ -0,0 +1,99 @@ +"""This modification of textwrap allows it to wrap ANSI colorized text as if +it weren't colorized. It also uses a much simpler word splitting regex to +prevent the splitting of ANSI colors as well as package names and versions.""" + +import re +import textwrap + +class TextWrapper(textwrap.TextWrapper): + """Ignore ANSI escape codes while wrapping text""" + + def _split(self, text): + """_split(text : string) -> [string] + + Split the text to wrap into indivisible chunks. + """ + # Only split on whitespace to avoid mangling ANSI escape codes or + # package names. + wordsep_re = re.compile(r'(\s+)') + chunks = wordsep_re.split(text) + chunks = [x for x in chunks if x is not None] + return chunks + + def _wrap_chunks(self, chunks): + """_wrap_chunks(chunks : [string]) -> [string] + + Wrap a sequence of text chunks and return a list of lines of + length 'self.width' or less. (If 'break_long_words' is false, + some lines may be longer than this.) Chunks correspond roughly + to words and the whitespace between them: each chunk is + indivisible (modulo 'break_long_words'), but a line break can + come between any two chunks. Chunks should not have internal + whitespace; ie. a chunk is either all whitespace or a "word". + Whitespace chunks will be removed from the beginning and end of + lines, but apart from that whitespace is preserved. + """ + lines = [] + if self.width <= 0: + raise ValueError("invalid width %r (must be > 0)" % self.width) + + # Arrange in reverse order so items can be efficiently popped + # from a stack of chunks. + chunks.reverse() + + # Regex to strip ANSI escape codes. It's only used for the + # length calculations of indent and each chuck. + ansi_re = re.compile('\x1b\[[0-9;]*m') + + while chunks: + + # Start the list of chunks that will make up the current line. + # cur_len is just the length of all the chunks in cur_line. + cur_line = [] + cur_len = 0 + + # Figure out which static string will prefix this line. + if lines: + indent = self.subsequent_indent + else: + indent = self.initial_indent + + # Maximum width for this line. Ingore ANSI escape codes. + width = self.width - len(re.sub(ansi_re, '', indent)) + + # First chunk on line is whitespace -- drop it, unless this + # is the very beginning of the text (ie. no lines started yet). + if chunks[-1].strip() == '' and lines: + del chunks[-1] + + while chunks: + # Ignore ANSI escape codes. + chunk_len = len(re.sub(ansi_re, '', chunks[-1])) + + # Can at least squeeze this chunk onto the current line. + if cur_len + chunk_len <= width: + cur_line.append(chunks.pop()) + cur_len += chunk_len + + # Nope, this line is full. + else: + break + + # The current line is full, and the next chunk is too big to + # fit on *any* line (not just this one). + # Ignore ANSI escape codes. + if chunks and len(re.sub(ansi_re, '', chunks[-1])) > width: + self._handle_long_word(chunks, cur_line, cur_len, width) + + # If the last chunk on this line is all whitespace, drop it. + if cur_line and cur_line[-1].strip() == '': + del cur_line[-1] + + # Convert current line back to a string and store it in list + # of all lines (return value). + if cur_line: + lines.append(indent + ''.join(cur_line)) + + return lines + +# vim: set ts=4 sw=4 tw=79: diff --git a/gentoolkit/pym/gentoolkit/versionmatch.py b/gentoolkit/pym/gentoolkit/versionmatch.py new file mode 100644 index 0000000..a11cc9a --- /dev/null +++ b/gentoolkit/pym/gentoolkit/versionmatch.py @@ -0,0 +1,132 @@ +#! /usr/bin/python +# +# Copyright(c) 2009 Gentoo Foundation +# Licensed under the GNU General Public License, v2 +# +# Copyright: 2005-2007 Brian Harring +# License: GPL2/BSD +# +# $Header$ + +"""Gentoo version comparison object from pkgcore.ebuild.atom_restricts.""" + +# ======= +# Imports +# ======= + +from portage.versions import vercmp + +from gentoolkit import errors +from gentoolkit.cpv import CPV + +# ======= +# Classes +# ======= + +class VersionMatch(object): + """Gentoo version comparison object from pkgcore.ebuild.atom_restricts. + + Any overriding of this class *must* maintain numerical order of + self.vals, see intersect for reason why. vals also must be a tuple. + """ + _convert_op2int = {(-1,):"<", (-1, 0): "<=", (0,):"=", + (0, 1):">=", (1,):">"} + + _convert_int2op = dict([(v, k) for k, v in _convert_op2int.iteritems()]) + + def __init__(self, cpv, op='='): + """Initialize a VersionMatch instance. + + @type cpv: L{gentoolkit.cpv.CPV} + @param cpv: cpv object + @type op: str + @keyword op: operator + """ + + if not isinstance(cpv, CPV): + raise ValueError("cpv must be a gentoolkit.cpv.CPV instance") + self.cpv = cpv + self.operator = op + self.version = cpv.version + self.revision = cpv.revision + self.fullversion = cpv.fullversion + + if self.operator != "~" and self.operator not in self._convert_int2op: + raise errors.GentoolkitInvalidVersion( + "invalid operator '%s'" % self.operator) + + if self.operator == "~": + if not self.version: + raise errors.GentoolkitInvalidVersion( + "for ~ op, ver must be specified") + self.droprevision = True + self.values = (0,) + else: + self.droprevision = False + self.values = self._convert_int2op[self.operator] + + def match(self, other): + """See whether a passed in VersionMatch or CPV instance matches self. + + Example usage: + >>> from gentoolkit.versionmatch import VersionMatch + >>> from gentoolkit.cpv import CPV + >>> VersionMatch(CPV('foo/bar-1.5'), op='>').match( + ... VersionMatch(CPV('foo/bar-2.0'))) + True + + @type other: gentoolkit.versionmatch.VersionMatch OR + gentoolkit.cpv.CPV + @param other: version to compare with self's version + @rtype: bool + """ + + if self.droprevision: + ver1, ver2 = self.version, other.version + else: + ver1, ver2 = self.fullversion, other.fullversion + + return vercmp(ver2, ver1) in self.values + + def __str__(self): + operator = self._convert_op2int[self.values] + + if self.droprevision or not self.revision: + return "ver %s %s" % (operator, self.version) + return "ver-rev %s %s-%s" % ( + operator, self.version, self.revision + ) + + def __repr__(self): + return "<%s %r>" % (self.__class__.__name__, str(self)) + + @staticmethod + def _convert_ops(inst): + if inst.droprevision: + return inst.values + return tuple(sorted(set((-1, 0, 1)).difference(inst.values))) + + def __eq__(self, other): + if self is other: + return True + if isinstance(other, self.__class__): + if (self.droprevision != other.droprevision or + self.version != other.version or + self.revision != other.revision): + return False + return self._convert_ops(self) == self._convert_ops(other) + + return False + + def __ne__(self, other): + return not self == other + + def __hash__(self): + return hash(( + self.droprevision, + self.version, + self.revision, + self.values + )) + +# vim: set ts=4 sw=4 tw=79: diff --git a/gentoolkit/setup.py b/gentoolkit/setup.py new file mode 100755 index 0000000..ba06995 --- /dev/null +++ b/gentoolkit/setup.py @@ -0,0 +1,116 @@ +#!/usr/bin/env python + +from __future__ import with_statement + +import os +import re +import sys +import distutils +from distutils import core, log +from glob import glob + +__version__ = os.getenv('VERSION', default='9999') + +cwd = os.getcwd() + +# Bash files that need `VERSION=""` subbed, relative to this dir: +bash_scripts = [os.path.join(cwd, path) for path in ( + 'bin/euse', + 'bin/revdep-rebuild' +)] + +# Python files that need `__version__ = ""` subbed, relative to this dir: +python_scripts = [os.path.join(cwd, path) for path in ( + 'bin/eclean', + 'bin/epkginfo', + 'bin/glsa-check', + 'pym/gentoolkit/equery/__init__.py' +)] + + +class set_version(core.Command): + """Set python __version__ and bash VERSION to our __version__.""" + description = "hardcode scripts' version using VERSION from environment" + user_options = [] # [(long_name, short_name, desc),] + + def initialize_options (self): + pass + + def finalize_options (self): + pass + + def run(self): + ver = 'svn' if __version__ == '9999' else __version__ + def sub(files, pattern): + for f in files: + updated_file = [] + with open(f) as s: + for line in s: + newline = re.sub(pattern, '"%s"' % ver, line, 1) + if newline != line: + log.info("%s: %s" % (f, newline)) + updated_file.append(newline) + with open(f, 'w') as s: + s.writelines(updated_file) + quote = r'[\'"]{1}' + bash_re = r'(?<=VERSION=)' + quote + '[^\'"]*' + quote + sub(bash_scripts, bash_re) + python_re = r'(?<=^__version__ = )' + quote + '[^\'"]*' + quote + sub(python_scripts, python_re) + + +def load_test(): + """Only return the real test class if it's actually being run so that we + don't depend on snakeoil just to install.""" + + desc = "run the test suite" + if 'test' in sys.argv[1:]: + try: + from snakeoil import distutils_extensions + except ImportError: + sys.stderr.write("Error: We depend on dev-python/snakeoil ") + sys.stderr.write("to run tests.\n") + sys.exit(1) + class test(distutils_extensions.test): + description = desc + default_test_namespace = 'gentoolkit.test' + else: + class test(core.Command): + description = desc + + return test + + +packages = [ + '.'.join(root.split(os.sep)[1:]) + for root, dirs, files in os.walk('pym/gentoolkit') + if '__init__.py' in files +] + +core.setup( + name='gentoolkit', + version=__version__, + description='Set of tools that work with and enhance portage.', + author='', + author_email='', + maintainer='Gentoo Portage Tools Team', + maintainer_email='tools-portage@gentoo.org', + url='http://www.gentoo.org/proj/en/portage/tools/index.xml', + download_url='http://distfiles.gentoo.org/distfiles/gentoolkit-%s.tar.gz'\ + % __version__, + package_dir={'': 'pym'}, + packages=packages, + scripts=(glob('bin/*')), + data_files=( + ('/etc/env.d', ['data/99gentoolkit-env']), + ('/etc/revdep-rebuild', ['data/revdep-rebuild/99revdep-rebuild']), + ('/etc/eclean', glob('data/eclean/*')), + ('/usr/share/man/man1', glob('man/*')) + ), + cmdclass={ + 'test': load_test(), + 'set_version': set_version, + }, +) + +# vim: set ts=4 sw=4 tw=79: -- 2.26.2