aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore5
-rw-r--r--.portage_not_installed0
-rw-r--r--DEVELOPING37
-rw-r--r--Makefile33
-rw-r--r--NEWS22
-rw-r--r--README49
-rw-r--r--RELEASE-NOTES57
-rwxr-xr-xbin/archive-conf56
-rwxr-xr-xbin/banned-helper6
-rw-r--r--bin/bashrc-functions.sh63
-rwxr-xr-xbin/binhost-snapshot31
-rwxr-xr-xbin/check-implicit-pointer-usage.py2
-rwxr-xr-xbin/chpathtool.py78
-rwxr-xr-xbin/clean_locks24
-rwxr-xr-xbin/dispatch-conf36
-rwxr-xr-xbin/dohtml.py56
-rw-r--r--bin/eapi.sh145
-rwxr-xr-xbin/ebuild105
l---------bin/ebuild-helpers/4/dodoc1
l---------bin/ebuild-helpers/4/dohard1
l---------bin/ebuild-helpers/4/dosed1
l---------bin/ebuild-helpers/4/prepalldocs1
-rwxr-xr-xbin/ebuild-helpers/bsd/sed (renamed from bin/ebuild-helpers/sed)14
-rwxr-xr-xbin/ebuild-helpers/dobin13
-rwxr-xr-xbin/ebuild-helpers/doconfd2
-rwxr-xr-xbin/ebuild-helpers/dodir9
-rwxr-xr-xbin/ebuild-helpers/dodoc20
-rwxr-xr-xbin/ebuild-helpers/doenvd2
-rwxr-xr-xbin/ebuild-helpers/doexe16
-rwxr-xr-xbin/ebuild-helpers/dohard14
-rwxr-xr-xbin/ebuild-helpers/doheader19
-rwxr-xr-xbin/ebuild-helpers/dohtml11
-rwxr-xr-xbin/ebuild-helpers/doinfo15
-rwxr-xr-xbin/ebuild-helpers/doinitd2
-rwxr-xr-xbin/ebuild-helpers/doins47
-rwxr-xr-xbin/ebuild-helpers/dolib13
-rwxr-xr-xbin/ebuild-helpers/doman13
-rwxr-xr-xbin/ebuild-helpers/domo11
-rwxr-xr-xbin/ebuild-helpers/dosbin13
-rwxr-xr-xbin/ebuild-helpers/dosed14
-rwxr-xr-xbin/ebuild-helpers/dosym9
-rwxr-xr-xbin/ebuild-helpers/ecompress14
-rwxr-xr-xbin/ebuild-helpers/ecompressdir79
-rwxr-xr-xbin/ebuild-helpers/emake2
-rwxr-xr-xbin/ebuild-helpers/fowners12
-rwxr-xr-xbin/ebuild-helpers/fperms9
-rwxr-xr-xbin/ebuild-helpers/keepdir20
l---------[-rwxr-xr-x]bin/ebuild-helpers/newbin23
l---------[-rwxr-xr-x]bin/ebuild-helpers/newconfd23
l---------[-rwxr-xr-x]bin/ebuild-helpers/newdoc23
l---------[-rwxr-xr-x]bin/ebuild-helpers/newenvd23
l---------[-rwxr-xr-x]bin/ebuild-helpers/newexe23
l---------bin/ebuild-helpers/newheader1
l---------[-rwxr-xr-x]bin/ebuild-helpers/newinitd23
-rwxr-xr-xbin/ebuild-helpers/newins67
l---------[-rwxr-xr-x]bin/ebuild-helpers/newlib.a23
l---------[-rwxr-xr-x]bin/ebuild-helpers/newlib.so23
l---------[-rwxr-xr-x]bin/ebuild-helpers/newman23
l---------[-rwxr-xr-x]bin/ebuild-helpers/newsbin23
-rwxr-xr-xbin/ebuild-helpers/portageq6
-rwxr-xr-xbin/ebuild-helpers/prepall7
-rwxr-xr-xbin/ebuild-helpers/prepalldocs14
-rwxr-xr-xbin/ebuild-helpers/prepallinfo7
-rwxr-xr-xbin/ebuild-helpers/prepallman14
-rwxr-xr-xbin/ebuild-helpers/prepallstrip9
-rwxr-xr-xbin/ebuild-helpers/prepinfo11
-rwxr-xr-xbin/ebuild-helpers/preplib31
-rwxr-xr-xbin/ebuild-helpers/prepman16
-rwxr-xr-xbin/ebuild-helpers/prepstrip205
l---------bin/ebuild-helpers/unprivileged/chgrp1
-rwxr-xr-xbin/ebuild-helpers/unprivileged/chown41
-rwxr-xr-xbin/ebuild-helpers/xattr/install12
-rwxr-xr-xbin/ebuild-ipc6
-rwxr-xr-xbin/ebuild-ipc.py177
-rwxr-xr-xbin/ebuild.sh182
-rwxr-xr-xbin/egencache490
-rwxr-xr-xbin/emaint23
-rwxr-xr-xbin/emerge104
-rwxr-xr-xbin/emerge-webrsync178
-rwxr-xr-xbin/emirrordist13
-rwxr-xr-xbin/env-update16
-rwxr-xr-xbin/etc-update19
-rwxr-xr-xbin/filter-bash-environment.py20
-rwxr-xr-xbin/fixpackages24
-rwxr-xr-xbin/glsa-check198
-rw-r--r--bin/helper-functions.sh71
-rwxr-xr-xbin/install.py253
-rw-r--r--bin/isolated-functions.sh168
-rwxr-xr-xbin/lock-helper.py5
-rwxr-xr-xbin/misc-functions.sh356
-rw-r--r--bin/phase-functions.sh412
-rw-r--r--bin/phase-helpers.sh610
-rwxr-xr-xbin/portageq665
-rwxr-xr-xbin/quickpkg37
-rwxr-xr-xbin/regenworld16
-rwxr-xr-xbin/repoman1687
-rw-r--r--bin/save-ebuild-env.sh67
-rwxr-xr-xbin/xattr-helper.py190
-rwxr-xr-xbin/xpak-helper.py11
-rw-r--r--cnf/dispatch-conf.conf1
-rw-r--r--cnf/make.conf.example (renamed from cnf/make.conf)21
-rw-r--r--cnf/make.conf.example.alpha.diff (renamed from cnf/make.conf.alpha.diff)18
-rw-r--r--cnf/make.conf.example.amd64-fbsd.diff (renamed from cnf/make.conf.amd64-fbsd.diff)18
-rw-r--r--cnf/make.conf.example.amd64.diff (renamed from cnf/make.conf.amd64.diff)18
-rw-r--r--cnf/make.conf.example.arm.diff (renamed from cnf/make.conf.arm.diff)12
-rw-r--r--cnf/make.conf.example.hppa.diff (renamed from cnf/make.conf.hppa.diff)28
-rw-r--r--cnf/make.conf.example.ia64.diff (renamed from cnf/make.conf.ia64.diff)10
-rw-r--r--cnf/make.conf.example.m68k.diff (renamed from cnf/make.conf.m68k.diff)14
-rw-r--r--cnf/make.conf.example.mips.diff (renamed from cnf/make.conf.mips.diff)18
-rw-r--r--cnf/make.conf.example.ppc.diff (renamed from cnf/make.conf.ppc.diff)26
-rw-r--r--cnf/make.conf.example.ppc64.diff (renamed from cnf/make.conf.ppc64.diff)24
-rw-r--r--cnf/make.conf.example.s390.diff (renamed from cnf/make.conf.s390.diff)10
-rw-r--r--cnf/make.conf.example.sh.diff (renamed from cnf/make.conf.sh.diff)17
-rw-r--r--cnf/make.conf.example.sparc-fbsd.diff (renamed from cnf/make.conf.sparc-fbsd.diff)12
-rw-r--r--cnf/make.conf.example.sparc.diff (renamed from cnf/make.conf.sparc.diff)18
-rw-r--r--cnf/make.conf.example.x86-fbsd.diff (renamed from cnf/make.conf.x86-fbsd.diff)18
-rw-r--r--cnf/make.conf.example.x86.diff (renamed from cnf/make.conf.x86.diff)18
-rw-r--r--cnf/make.globals44
-rw-r--r--cnf/metadata.dtd7
-rw-r--r--cnf/repos.conf7
-rw-r--r--cnf/sets/portage.conf2
-rw-r--r--doc/config/sets.docbook5
-rw-r--r--doc/package/ebuild.docbook3
-rw-r--r--doc/package/ebuild/eapi/4-python.docbook44
-rw-r--r--doc/package/ebuild/eapi/4-slot-abi.docbook12
-rw-r--r--doc/package/ebuild/eapi/5-hdepend.docbook32
-rw-r--r--doc/package/ebuild/eapi/5-progress.docbook247
-rw-r--r--doc/package/ebuild/eapi/5.docbook232
-rw-r--r--doc/portage.docbook3
-rw-r--r--doc/qa.docbook2
-rw-r--r--make.conf-repatch.sh40
-rwxr-xr-xmake.conf.example-repatch.sh41
-rw-r--r--man/color.map.518
-rw-r--r--man/dispatch-conf.177
-rw-r--r--man/ebuild.136
-rw-r--r--man/ebuild.51173
-rw-r--r--man/egencache.178
-rw-r--r--man/emaint.115
-rw-r--r--man/emerge.1423
-rw-r--r--man/emirrordist.1148
-rw-r--r--man/env-update.121
-rw-r--r--man/etc-update.146
-rw-r--r--man/make.conf.5326
-rw-r--r--man/portage.5664
-rw-r--r--man/quickpkg.134
-rw-r--r--man/repoman.1139
-rw-r--r--man/ru/color.map.5217
-rw-r--r--man/ru/dispatch-conf.1100
-rw-r--r--man/ru/ebuild.1249
-rw-r--r--man/ru/env-update.135
-rw-r--r--man/ru/etc-update.163
-rw-r--r--man/ru/fixpackages.122
-rw-r--r--man/xpak.55
-rwxr-xr-xmisc/emerge-delta-webrsync809
-rwxr-xr-xmkrelease.sh91
-rw-r--r--pym/_emerge/AbstractDepPriority.py5
-rw-r--r--pym/_emerge/AbstractEbuildProcess.py58
-rw-r--r--pym/_emerge/AbstractPollTask.py2
-rw-r--r--pym/_emerge/AsynchronousLock.py66
-rw-r--r--pym/_emerge/AsynchronousTask.py14
-rw-r--r--pym/_emerge/Binpkg.py7
-rw-r--r--pym/_emerge/BinpkgExtractorAsync.py15
-rw-r--r--pym/_emerge/BinpkgFetcher.py18
-rw-r--r--pym/_emerge/BinpkgVerifier.py143
-rw-r--r--pym/_emerge/BlockerCache.py10
-rw-r--r--pym/_emerge/BlockerDB.py12
-rw-r--r--pym/_emerge/CompositeTask.py4
-rw-r--r--pym/_emerge/DepPriority.py29
-rw-r--r--pym/_emerge/DepPrioritySatisfiedRange.py24
-rw-r--r--pym/_emerge/DependencyArg.py10
-rw-r--r--pym/_emerge/EbuildBuild.py36
-rw-r--r--pym/_emerge/EbuildBuildDir.py11
-rw-r--r--pym/_emerge/EbuildExecuter.py13
-rw-r--r--pym/_emerge/EbuildFetcher.py68
-rw-r--r--pym/_emerge/EbuildMetadataPhase.py66
-rw-r--r--pym/_emerge/EbuildPhase.py63
-rw-r--r--pym/_emerge/EbuildProcess.py12
-rw-r--r--pym/_emerge/EbuildSpawnProcess.py10
-rw-r--r--pym/_emerge/FakeVartree.py123
-rw-r--r--pym/_emerge/FifoIpcDaemon.py43
-rw-r--r--pym/_emerge/JobStatusDisplay.py44
-rw-r--r--pym/_emerge/MergeListItem.py18
-rw-r--r--pym/_emerge/MetadataRegen.py93
-rw-r--r--pym/_emerge/MiscFunctionsProcess.py7
-rw-r--r--pym/_emerge/Package.py317
-rw-r--r--pym/_emerge/PackageMerge.py7
-rw-r--r--pym/_emerge/PackageUninstall.py6
-rw-r--r--pym/_emerge/PackageVirtualDbapi.py4
-rw-r--r--pym/_emerge/PipeReader.py37
-rw-r--r--pym/_emerge/PollScheduler.py129
-rw-r--r--pym/_emerge/QueueScheduler.py105
-rw-r--r--pym/_emerge/RootConfig.py13
-rw-r--r--pym/_emerge/Scheduler.py240
-rw-r--r--pym/_emerge/SpawnProcess.py269
-rw-r--r--pym/_emerge/SubProcess.py30
-rw-r--r--pym/_emerge/Task.py9
-rw-r--r--pym/_emerge/TaskScheduler.py26
-rw-r--r--pym/_emerge/UnmergeDepPriority.py27
-rw-r--r--pym/_emerge/UseFlagDisplay.py10
-rw-r--r--pym/_emerge/actions.py1704
-rw-r--r--pym/_emerge/chk_updated_cfg_files.py42
-rw-r--r--pym/_emerge/clear_caches.py4
-rw-r--r--pym/_emerge/countdown.py18
-rw-r--r--pym/_emerge/create_depgraph_params.py23
-rw-r--r--pym/_emerge/create_world_atom.py25
-rw-r--r--pym/_emerge/depgraph.py2451
-rw-r--r--pym/_emerge/emergelog.py12
-rw-r--r--pym/_emerge/getloadavg.py5
-rw-r--r--pym/_emerge/help.py10
-rw-r--r--pym/_emerge/is_valid_package_atom.py7
-rw-r--r--pym/_emerge/main.py1297
-rw-r--r--pym/_emerge/post_emerge.py165
-rw-r--r--pym/_emerge/resolver/backtracking.py38
-rw-r--r--pym/_emerge/resolver/circular_dependency.py24
-rw-r--r--pym/_emerge/resolver/output.py537
-rw-r--r--pym/_emerge/resolver/output_helpers.py95
-rw-r--r--pym/_emerge/resolver/package_tracker.py301
-rw-r--r--pym/_emerge/resolver/slot_collision.py230
-rw-r--r--pym/_emerge/search.py4
-rw-r--r--pym/_emerge/stdout_spinner.py13
-rw-r--r--pym/_emerge/unmerge.py5
-rw-r--r--pym/portage/__init__.py211
-rw-r--r--pym/portage/_emirrordist/Config.py132
-rw-r--r--pym/portage/_emirrordist/DeletionIterator.py83
-rw-r--r--pym/portage/_emirrordist/DeletionTask.py129
-rw-r--r--pym/portage/_emirrordist/FetchIterator.py147
-rw-r--r--pym/portage/_emirrordist/FetchTask.py629
-rw-r--r--pym/portage/_emirrordist/MirrorDistTask.py219
-rw-r--r--pym/portage/_emirrordist/__init__.py2
-rw-r--r--pym/portage/_emirrordist/main.py463
-rw-r--r--pym/portage/_global_updates.py238
-rw-r--r--pym/portage/_legacy_globals.py3
-rw-r--r--pym/portage/_selinux.py55
-rw-r--r--pym/portage/_sets/__init__.py30
-rw-r--r--pym/portage/_sets/base.py7
-rw-r--r--pym/portage/_sets/dbapi.py111
-rw-r--r--pym/portage/_sets/files.py10
-rw-r--r--pym/portage/_sets/libs.py17
-rw-r--r--pym/portage/_sets/security.py4
-rw-r--r--pym/portage/cache/ebuild_xattr.py2
-rw-r--r--pym/portage/cache/flat_hash.py32
-rw-r--r--pym/portage/cache/flat_list.py134
-rw-r--r--pym/portage/cache/fs_template.py6
-rw-r--r--pym/portage/cache/mappings.py6
-rw-r--r--pym/portage/cache/metadata.py6
-rw-r--r--pym/portage/cache/sqlite.py41
-rw-r--r--pym/portage/cache/template.py14
-rw-r--r--pym/portage/checksum.py100
-rw-r--r--pym/portage/const.py198
-rw-r--r--pym/portage/cvstree.py274
-rw-r--r--pym/portage/data.py76
-rw-r--r--pym/portage/dbapi/_MergeProcess.py214
-rw-r--r--pym/portage/dbapi/_SyncfsProcess.py53
-rw-r--r--pym/portage/dbapi/__init__.py110
-rw-r--r--pym/portage/dbapi/_expand_new_virt.py12
-rw-r--r--pym/portage/dbapi/_similar_name_search.py57
-rw-r--r--pym/portage/dbapi/bintree.py338
-rw-r--r--pym/portage/dbapi/cpv_expand.py4
-rw-r--r--pym/portage/dbapi/dep_expand.py6
-rw-r--r--pym/portage/dbapi/porttree.py144
-rw-r--r--pym/portage/dbapi/vartree.py604
-rw-r--r--pym/portage/dbapi/virtual.py7
-rw-r--r--pym/portage/debug.py10
-rw-r--r--pym/portage/dep/__init__.py309
-rw-r--r--pym/portage/dep/_slot_operator.py (renamed from pym/portage/dep/_slot_abi.py)53
-rw-r--r--pym/portage/dep/dep_check.py113
-rw-r--r--pym/portage/dispatch_conf.py326
-rw-r--r--pym/portage/eapi.py64
-rw-r--r--pym/portage/eclass_cache.py26
-rw-r--r--pym/portage/elog/__init__.py3
-rw-r--r--pym/portage/elog/mod_echo.py3
-rw-r--r--pym/portage/elog/mod_save.py24
-rw-r--r--pym/portage/elog/mod_save_summary.py40
-rw-r--r--pym/portage/elog/mod_syslog.py13
-rw-r--r--pym/portage/emaint/__init__.py4
-rw-r--r--pym/portage/emaint/defaults.py11
-rw-r--r--pym/portage/emaint/main.py157
-rw-r--r--pym/portage/emaint/module.py8
-rw-r--r--pym/portage/emaint/modules/__init__.py4
-rw-r--r--pym/portage/emaint/modules/binhost/__init__.py8
-rw-r--r--pym/portage/emaint/modules/binhost/binhost.py12
-rw-r--r--pym/portage/emaint/modules/config/__init__.py8
-rw-r--r--pym/portage/emaint/modules/config/config.py66
-rw-r--r--pym/portage/emaint/modules/logs/__init__.py22
-rw-r--r--pym/portage/emaint/modules/logs/logs.py17
-rw-r--r--pym/portage/emaint/modules/move/__init__.py9
-rw-r--r--pym/portage/emaint/modules/move/move.py42
-rw-r--r--pym/portage/emaint/modules/resume/__init__.py6
-rw-r--r--pym/portage/emaint/modules/world/__init__.py8
-rw-r--r--pym/portage/env/loaders.py26
-rw-r--r--pym/portage/exception.py54
-rw-r--r--pym/portage/getbinpkg.py255
-rw-r--r--pym/portage/glsa.py313
-rw-r--r--pym/portage/localization.py17
-rw-r--r--pym/portage/locks.py104
-rw-r--r--pym/portage/mail.py7
-rw-r--r--pym/portage/manifest.py114
-rw-r--r--pym/portage/news.py10
-rw-r--r--pym/portage/output.py43
-rw-r--r--pym/portage/package/ebuild/_config/KeywordsManager.py56
-rw-r--r--pym/portage/package/ebuild/_config/LocationsManager.py135
-rw-r--r--pym/portage/package/ebuild/_config/MaskManager.py33
-rw-r--r--pym/portage/package/ebuild/_config/UseManager.py290
-rw-r--r--pym/portage/package/ebuild/_config/special_env_vars.py56
-rw-r--r--pym/portage/package/ebuild/_config/unpack_dependencies.py38
-rw-r--r--pym/portage/package/ebuild/_ipc/QueryCommand.py91
-rw-r--r--pym/portage/package/ebuild/_metadata_invalid.py (renamed from pym/portage/package/ebuild/_eapi_invalid.py)13
-rw-r--r--pym/portage/package/ebuild/_parallel_manifest/ManifestProcess.py43
-rw-r--r--pym/portage/package/ebuild/_parallel_manifest/ManifestScheduler.py93
-rw-r--r--pym/portage/package/ebuild/_parallel_manifest/ManifestTask.py186
-rw-r--r--pym/portage/package/ebuild/_parallel_manifest/__init__.py2
-rw-r--r--pym/portage/package/ebuild/_spawn_nofetch.py23
-rw-r--r--pym/portage/package/ebuild/config.py610
-rw-r--r--pym/portage/package/ebuild/deprecated_profile_check.py63
-rw-r--r--pym/portage/package/ebuild/digestcheck.py15
-rw-r--r--pym/portage/package/ebuild/digestgen.py107
-rw-r--r--pym/portage/package/ebuild/doebuild.py546
-rw-r--r--pym/portage/package/ebuild/fetch.py84
-rw-r--r--pym/portage/package/ebuild/getmaskingreason.py30
-rw-r--r--pym/portage/package/ebuild/getmaskingstatus.py32
-rw-r--r--pym/portage/package/ebuild/prepare_build_dirs.py8
-rw-r--r--pym/portage/process.py333
-rw-r--r--pym/portage/proxy/lazyimport.py5
-rw-r--r--pym/portage/proxy/objectproxy.py9
-rw-r--r--pym/portage/repository/config.py552
-rw-r--r--pym/portage/tests/__init__.py93
-rw-r--r--pym/portage/tests/bin/setup_env.py54
-rw-r--r--pym/portage/tests/dbapi/test_fakedbapi.py10
-rw-r--r--pym/portage/tests/dbapi/test_portdb_cache.py183
-rw-r--r--pym/portage/tests/dep/testAtom.py267
-rw-r--r--pym/portage/tests/dep/testCheckRequiredUse.py192
-rw-r--r--pym/portage/tests/dep/testStandalone.py26
-rw-r--r--pym/portage/tests/dep/test_best_match_to_list.py44
-rw-r--r--pym/portage/tests/dep/test_dep_getcpv.py16
-rw-r--r--pym/portage/tests/dep/test_dep_getrepo.py6
-rw-r--r--pym/portage/tests/dep/test_dep_getslot.py10
-rw-r--r--pym/portage/tests/dep/test_dep_getusedeps.py12
-rw-r--r--pym/portage/tests/dep/test_get_operator.py24
-rw-r--r--pym/portage/tests/dep/test_get_required_use_flags.py4
-rw-r--r--pym/portage/tests/dep/test_isjustname.py14
-rw-r--r--pym/portage/tests/dep/test_isvalidatom.py13
-rw-r--r--pym/portage/tests/dep/test_match_from_list.py136
-rw-r--r--pym/portage/tests/dep/test_paren_reduce.py61
-rw-r--r--pym/portage/tests/dep/test_use_reduce.py519
-rw-r--r--pym/portage/tests/ebuild/test_config.py27
-rw-r--r--pym/portage/tests/ebuild/test_doebuild_fd_pipes.py137
-rw-r--r--pym/portage/tests/ebuild/test_doebuild_spawn.py46
-rw-r--r--pym/portage/tests/ebuild/test_ipc_daemon.py78
-rw-r--r--pym/portage/tests/ebuild/test_spawn.py15
-rw-r--r--pym/portage/tests/emerge/test_emerge_slot_abi.py30
-rw-r--r--pym/portage/tests/emerge/test_simple.py116
-rw-r--r--pym/portage/tests/env/config/test_PackageKeywordsFile.py8
-rw-r--r--pym/portage/tests/env/config/test_PackageUseFile.py6
-rw-r--r--pym/portage/tests/env/config/test_PortageModulesFile.py11
-rw-r--r--pym/portage/tests/glsa/__init__.py2
-rw-r--r--pym/portage/tests/glsa/__test__0
-rw-r--r--pym/portage/tests/glsa/test_security_set.py144
-rw-r--r--pym/portage/tests/lazyimport/test_lazy_import_portage_baseline.py4
-rw-r--r--pym/portage/tests/lint/test_bash_syntax.py26
-rw-r--r--pym/portage/tests/lint/test_compile_modules.py32
-rw-r--r--pym/portage/tests/lint/test_import_modules.py2
-rw-r--r--pym/portage/tests/locks/test_asynchronous_lock.py10
-rw-r--r--pym/portage/tests/process/test_PopenProcess.py85
-rw-r--r--pym/portage/tests/process/test_PopenProcessBlockingIO.py63
-rw-r--r--pym/portage/tests/process/test_poll.py35
-rw-r--r--pym/portage/tests/repoman/test_echangelog.py6
-rw-r--r--pym/portage/tests/repoman/test_simple.py83
-rw-r--r--pym/portage/tests/resolver/ResolverPlayground.py390
-rw-r--r--pym/portage/tests/resolver/test_autounmask.py304
-rw-r--r--pym/portage/tests/resolver/test_autounmask_multilib_use.py85
-rw-r--r--pym/portage/tests/resolver/test_backtracking.py48
-rw-r--r--pym/portage/tests/resolver/test_blocker.py48
-rw-r--r--pym/portage/tests/resolver/test_complete_graph.py4
-rw-r--r--pym/portage/tests/resolver/test_complete_if_new_subslot_without_revbump.py74
-rw-r--r--pym/portage/tests/resolver/test_depclean.py100
-rw-r--r--pym/portage/tests/resolver/test_depclean_order.py57
-rw-r--r--pym/portage/tests/resolver/test_depclean_slot_unavailable.py78
-rw-r--r--pym/portage/tests/resolver/test_features_test_use.py68
-rw-r--r--pym/portage/tests/resolver/test_merge_order.py35
-rw-r--r--pym/portage/tests/resolver/test_multirepo.py88
-rw-r--r--pym/portage/tests/resolver/test_onlydeps.py34
-rw-r--r--pym/portage/tests/resolver/test_or_choices.py134
-rw-r--r--pym/portage/tests/resolver/test_package_tracker.py261
-rw-r--r--pym/portage/tests/resolver/test_regular_slot_change_without_revbump.py59
-rw-r--r--pym/portage/tests/resolver/test_slot_abi.py111
-rw-r--r--pym/portage/tests/resolver/test_slot_abi_downgrade.py8
-rw-r--r--pym/portage/tests/resolver/test_slot_change_without_revbump.py69
-rw-r--r--pym/portage/tests/resolver/test_slot_collisions.py106
-rw-r--r--pym/portage/tests/resolver/test_slot_conflict_mask_update.py41
-rw-r--r--pym/portage/tests/resolver/test_slot_conflict_rebuild.py408
-rw-r--r--pym/portage/tests/resolver/test_slot_conflict_update.py98
-rw-r--r--pym/portage/tests/resolver/test_slot_operator_autounmask.py120
-rw-r--r--pym/portage/tests/resolver/test_slot_operator_unsatisfied.py70
-rw-r--r--pym/portage/tests/resolver/test_slot_operator_unsolved.py88
-rw-r--r--pym/portage/tests/resolver/test_targetroot.py85
-rw-r--r--pym/portage/tests/resolver/test_unpack_dependencies.py65
-rw-r--r--pym/portage/tests/resolver/test_use_aliases.py131
-rw-r--r--pym/portage/tests/resolver/test_useflags.py78
-rwxr-xr-xpym/portage/tests/runTests19
-rw-r--r--pym/portage/tests/unicode/test_string_format.py52
-rw-r--r--pym/portage/tests/update/test_move_ent.py6
-rw-r--r--pym/portage/tests/update/test_move_slot_ent.py6
-rw-r--r--pym/portage/tests/update/test_update_dbentry.py101
-rw-r--r--pym/portage/tests/util/test_getconfig.py31
-rw-r--r--pym/portage/tests/util/test_stackDictList.py12
-rw-r--r--pym/portage/tests/util/test_stackDicts.py41
-rw-r--r--pym/portage/tests/util/test_stackLists.py18
-rw-r--r--pym/portage/tests/util/test_uniqueArray.py14
-rw-r--r--pym/portage/tests/util/test_varExpand.py80
-rw-r--r--pym/portage/tests/util/test_whirlpool.py4
-rw-r--r--pym/portage/tests/versions/test_cpv_sort_key.py7
-rw-r--r--pym/portage/tests/versions/test_vercmp.py38
-rw-r--r--pym/portage/update.py137
-rw-r--r--pym/portage/util/ExtractKernelVersion.py6
-rw-r--r--pym/portage/util/SlotObject.py1
-rw-r--r--pym/portage/util/_ShelveUnicodeWrapper.py45
-rw-r--r--pym/portage/util/__init__.py394
-rw-r--r--pym/portage/util/_argparse.py42
-rw-r--r--pym/portage/util/_async/AsyncScheduler.py102
-rw-r--r--pym/portage/util/_async/FileCopier.py17
-rw-r--r--pym/portage/util/_async/FileDigester.py73
-rw-r--r--pym/portage/util/_async/ForkProcess.py65
-rw-r--r--pym/portage/util/_async/PipeLogger.py163
-rw-r--r--pym/portage/util/_async/PipeReaderBlockingIO.py91
-rw-r--r--pym/portage/util/_async/PopenProcess.py33
-rw-r--r--pym/portage/util/_async/SchedulerInterface.py79
-rw-r--r--pym/portage/util/_async/TaskScheduler.py20
-rw-r--r--pym/portage/util/_async/__init__.py2
-rw-r--r--pym/portage/util/_async/run_main_scheduler.py41
-rw-r--r--pym/portage/util/_ctypes.py47
-rw-r--r--pym/portage/util/_desktop_entry.py85
-rw-r--r--pym/portage/util/_dyn_libs/LinkageMapELF.py24
-rw-r--r--pym/portage/util/_dyn_libs/PreservedLibsRegistry.py3
-rw-r--r--pym/portage/util/_dyn_libs/display_preserved_libs.py98
-rw-r--r--pym/portage/util/_eventloop/EventLoop.py364
-rw-r--r--pym/portage/util/_eventloop/PollSelectAdapter.py2
-rw-r--r--pym/portage/util/_get_vm_info.py80
-rw-r--r--pym/portage/util/_info_files.py138
-rw-r--r--pym/portage/util/_path.py27
-rw-r--r--pym/portage/util/_urlopen.py102
-rw-r--r--pym/portage/util/digraph.py46
-rw-r--r--pym/portage/util/env_update.py78
-rw-r--r--pym/portage/util/lafilefixer.py10
-rw-r--r--pym/portage/util/listdir.py128
-rw-r--r--pym/portage/util/movefile.py220
-rw-r--r--pym/portage/util/whirlpool.py2
-rw-r--r--pym/portage/util/writeable_check.py79
-rw-r--r--pym/portage/versions.py85
-rw-r--r--pym/portage/xml/metadata.py15
-rw-r--r--pym/portage/xpak.py8
-rw-r--r--pym/repoman/checks.py235
-rw-r--r--pym/repoman/errors.py6
-rw-r--r--pym/repoman/herdbase.py11
-rw-r--r--pym/repoman/utilities.py146
-rwxr-xr-xruntests.sh47
-rwxr-xr-xtabcheck.py2
456 files changed, 30379 insertions, 13080 deletions
diff --git a/.gitignore b/.gitignore
index 808cc0c58..074bb864d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
*.py[co]
-/pym/portage/public_api.bz2
-/testpath
+__pycache__/
+*.class
+/tags
diff --git a/.portage_not_installed b/.portage_not_installed
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/.portage_not_installed
diff --git a/DEVELOPING b/DEVELOPING
index ebe5d56c3..40b4ca2d4 100644
--- a/DEVELOPING
+++ b/DEVELOPING
@@ -24,7 +24,8 @@ Tabs
----
The current code uses tabs, not spaces. Keep whitespace usage consistent
-between files. New files should use tabs.
+between files. New files should use tabs. Space is sometimes used for
+indentation in Python code. Tab stop should for this reason be set to 4.
Line-Wrapping
-------------
@@ -51,13 +52,13 @@ wrapping is always clear (but you cannot convert spaces as easily as tabwidth).
Comparisons
-----------
-if foo == None
+if foo != None
should be replaced with:
if foo is not None:
-Is not does a reference comparison (address1 = address2 basically) and
+Is not does a reference comparison (address1 = address2 basically) and
the == forces a by value compare (with __eq__())
Dict Lookups
@@ -139,7 +140,7 @@ NO:
Try not to import large numbers of things into the namespace of a module.
I realize this is done all over the place in current code but it really makes it
-a pain to do code reflection when the namespace is cluttered with identifiers
+a pain to do code reflection when the namespace is cluttered with identifiers
from other modules.
YES:
@@ -159,13 +160,29 @@ just COLOR. However it means during introspection of the current namespace
The NO example just imports a set of functions from the output module. It is
somewhat annoying because the import line needs to be modified when functions
are needed and often unused functions are left in the import line until someone
-comes along with a linter to clean up (does not happen often). The color is a
-bit clearer as
+comes along with a linter to clean up (does not happen often).
- print red('blar')
-is shorter than:
+Releases
+--------
- print output.red('blar')
+First update the NEWS and RELEASE-NOTES files and commit.
-Rationale: python -c 'import portage; dir(portage)' (circa 02/2008)
+Second create a git tag for this release:
+ git tag v2.2.8
+
+Then create the tarball and run the tests:
+ ./mkrelease.sh --changelog-rev v2.2.7 --tag --runtests 2.2.8
+Make sure you have all supported python versions installed first
+(see PYTHON_SUPPORTED_VERSIONS in runtests.sh).
+
+Version bump the ebuild and verify it can re-install itself:
+ emerge portage
+ emerge portage
+
+Publish the results (no going back now):
+ - Push the new git tag
+ - Upload the tarball
+ - Commit the new ebuild version
+
+Close the bugs blocking the tracker bug for this release.
diff --git a/Makefile b/Makefile
index f074dcfa3..92ea19562 100644
--- a/Makefile
+++ b/Makefile
@@ -27,13 +27,14 @@ INSMODE = 0644
EXEMODE = 0755
DIRMODE = 0755
SYSCONFDIR_FILES = etc-update.conf dispatch-conf.conf
-PORTAGE_CONFDIR_FILES = make.globals
+PORTAGE_CONFDIR_FILES = make.conf.example make.globals repos.conf
LOGROTATE_FILES = elog-save-summary
BINDIR_FILES = ebuild egencache emerge emerge-webrsync \
- portageq quickpkg repoman
+ emirrordist portageq quickpkg repoman
SBINDIR_FILES = archive-conf dispatch-conf emaint \
env-update etc-update fixpackages regenworld
DOCS = ChangeLog NEWS RELEASE-NOTES
+LINGUAS ?= $(shell cd "$(srcdir)/man" && find -mindepth 1 -type d)
ifdef PYTHONPATH
PYTHONPATH := $(srcdir)/pym:$(PYTHONPATH)
@@ -50,8 +51,6 @@ docbook:
epydoc:
set -e; \
- # workaround for bug 282760 \
- touch "$(srcdir)/pym/pysqlite2.py"; \
env PYTHONPATH="$(PYTHONPATH)" epydoc \
-o "$(WORKDIR)/epydoc" \
--name $(PN) \
@@ -63,9 +62,7 @@ epydoc:
-e s:^pym/:: \
-e s:/:.:g \
| sort); \
- rm -f "$(srcdir)/pym/pysqlite2.py"* \
- "$(WORKDIR)/epydoc/pysqlite2-"* \
- "$(WORKDIR)/epydoc/api-objects.txt"; \
+ rm -f "$(WORKDIR)/epydoc/api-objects.txt"; \
test:
set -e; \
@@ -81,9 +78,6 @@ install:
cd "$(srcdir)/cnf"; \
install -m$(INSMODE) $(PORTAGE_CONFDIR_FILES) \
"$(DESTDIR)$(portage_confdir)"; \
- install -m$(INSMODE) "$(srcdir)/cnf/make.conf" \
- "$(DESTDIR)$(portage_confdir)/make.conf.example"; \
- \
install -d -m$(DIRMODE) "$(DESTDIR)$(portage_setsdir)"; \
cd "$(S)/cnf/sets"; \
install -m$(INSMODE) *.conf "$(DESTDIR)$(portage_setsdir)"; \
@@ -184,10 +178,18 @@ install:
cd "$(srcdir)"; \
install -m $(INSMODE) $(DOCS) "$(DESTDIR)$(docdir)"; \
\
- for x in 1 5 ; do \
- install -d -m$(DIRMODE) "$(DESTDIR)$(mandir)/man$$x"; \
- cd "$(srcdir)/man"; \
- install -m$(INSMODE) *.$$x "$(DESTDIR)$(mandir)/man$$x"; \
+ for x in "" $(LINGUAS); do \
+ for y in 1 5 ; do \
+ if [ -d "$(srcdir)/man/$$x" ]; then \
+ cd "$(srcdir)/man/$$x"; \
+ files=$$(echo *.$$y); \
+ if [ -z "$$files" ] || [ "$$files" = "*.$$y" ]; then \
+ continue; \
+ fi; \
+ install -d -m$(DIRMODE) "$(DESTDIR)$(mandir)/$$x/man$$y"; \
+ install -m$(INSMODE) *.$$y "$(DESTDIR)$(mandir)/$$x/man$$y"; \
+ fi; \
+ done; \
done; \
\
if [ -f "$(srcdir)/doc/portage.html" ] ; then \
@@ -208,7 +210,6 @@ install:
clean:
set -e; \
$(MAKE) -C "$(srcdir)/doc" clean; \
- rm -rf "$(srcdir)/pym/pysqlite2.py"* \
- "$(WORKDIR)/epydoc"; \
+ rm -rf "$(WORKDIR)/epydoc"; \
.PHONY: all clean docbook epydoc install test
diff --git a/NEWS b/NEWS
index 9a2f24f6d..43d1797c2 100644
--- a/NEWS
+++ b/NEWS
@@ -1,22 +1,34 @@
News (mainly features/major bug fixes)
+portage-2.2.1
+-------------
+
+* Add cgroups, ipc-sandbox, and network-sandbox FEATURES.
+
portage-2.2
-------------
-* Add link level dependency awareness to emerge --depclean and --prune actions
- in order to protect against uninstallation of required libraries.
-* Add support for generic package sets (also see RELEASE-NOTES)
+* Add extended set configuration via /etc/portage/sets.conf. See
+ /usr/share/portage/config/sets/portage.conf for examples.
+
+portage-2.1.11.20
+-------------
+* Add support for EAPI 5. Refer to the PMS EAPI Cheat Sheet, portage's html
+ docs installed with USE=doc, or `man 5 ebuild` for more info about EAPI 5.
* Add support for FEATURES=preserve-libs which preserves libraries when the
sonames change during upgrade or downgrade, and the @preserved-rebuild
package set which rebuilds consumers of preserved libraries.
+* Add link level dependency awareness to emerge --depclean and --prune actions
+ in order to protect against uninstallation of required libraries. Refer to
+ the --depclean-lib-check option in the emerge(1) man page.
portage-2.1.11
-------------
* Add support for experimental EAPI "4-slot-abi". Refer to the corresponding
html documentation that is installed with USE=doc, and also to the emerge(1)
- man page for information about the related --ignore-built-slot-abi-deps and
- --rebuild-if-new-slot-abi options.
+ man page for information about the related --ignore-built-slot-operator-deps and
+ --rebuild-if-new-slot options.
portage-2.1.10
-------------
diff --git a/README b/README
new file mode 100644
index 000000000..5558ddead
--- /dev/null
+++ b/README
@@ -0,0 +1,49 @@
+About Portage
+=============
+
+Portage is a package management system based on ports collections. The
+Package Manager Specification Project (PMS) standardises and documents
+the behaviour of Portage so that the Portage tree can be used by other
+package managers.
+
+
+Dependencies
+============
+
+Python and Bash should be the only hard dependencies. Python 2.6 is the
+minimum supported version.
+
+
+Licensing and Legalese
+=======================
+
+Portage is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+version 2 as published by the Free Software Foundation.
+
+Portage 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 Portage; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+02110-1301, USA.
+
+
+More information
+================
+
+-DEVELOPING contains some code guidelines.
+-LICENSE contains the GNU General Public License version 2.
+-NEWS contains new features/major bug fixes for each version.
+-RELEASE NOTES contains mainly upgrade information for each version.
+-TEST-NOTES contains Portage unit test information.
+
+
+Links
+=====
+Gentoo project page: <http://www.gentoo.org/proj/en/portage/>
+PMS: <https://dev.gentoo.org/~ulm/pms/head/pms.html>
+PMS git repo: <http://git.overlays.gentoo.org/gitweb/?p=proj/pms.git>
diff --git a/RELEASE-NOTES b/RELEASE-NOTES
index 93e67ed5a..72aa21934 100644
--- a/RELEASE-NOTES
+++ b/RELEASE-NOTES
@@ -1,30 +1,53 @@
Release Notes; upgrade information mainly.
Features/major bugfixes are listed in NEWS
+portage-2.2.
+==================================
+* Bug Fixes:
+ - Bug # 450372 Russian translation update.
+ - Bug #497238: Fix unnecessary rebuild caused by equal versions
+ in different repositories.
+ - Bug #501360 Only use Atoms with package_tracker.match
+ - For a complete list of bug fixes, changes, See the Changelog installed at
+ /usr/share/doc/portage-2.2.9/ChangeLog.bz2
+
+portage-2.2.8
+==================================
+* Bug Fixes:
+ - Bug 488972 - sys-apps/portage-2.2.7:
+ "egencache --update --rsync" does not create metadata/timestamp.chk
+ - For a complete list of bug fixes, changes, See the Changelog installed at
+ /usr/share/doc/portage-2.2.8/ChangeLog.bz2
+
portage-2.2
==================================
* Portage now warns if an ebuild repository does not have a name, as several
new features in 2.2 make use of or require named repositories. The repository
name is stored in profiles/repo_name in each repository.
-* Package set support: There are several important notes regarding package
- sets:
- - they may currently only include simple and versioned atoms or other sets,
- use conditionals or any-of constructs aren't possible yet
- - sets can be referenced either in other file-based sets or as argument to
- emerge, but not in ebuilds, config files or other tools at this time.
- - packages won't be unmerged if they are referenced by an installed package
- set (with the exception of the world set, and installed being determined
- by the world_sets file).
-* The "selected" package set, which includes packages listed in
- /var/lib/portage/world, has been extended to include nested sets that may
- be listed /var/lib/portage/world_sets.
+
+portage-2.1.13
+==================================
+
+* FEATURES=userpriv and usersandbox are enabled by default.
+* FEATURES=usersync is enabled by default.
+* New sync-cvs-repo, sync-type and sync-uri attributes in repos.conf replace
+ SYNC variable.
+
+portage-2.1.12
+==================================
+
+* FEATURES=preserve-libs is enabled by default.
+* ACCEPT_RESTRICT variable may be used to mask packages based on RESTRICT.
portage-2.1.11
==================================
* User-defined package sets can now be created by placing files in the
/etc/portage/sets/ directory. Refer to the emerge(1) and portage(5) man
pages for more information.
+* The "selected" package set, which includes packages listed in
+ /var/lib/portage/world, has been extended to include nested sets that may
+ be listed /var/lib/portage/world_sets.
portage-2.1.10.61
==================================
@@ -119,7 +142,7 @@ portage-2.1.6
* The python namespace for portage has been sanitized, all portage related code
is now contained within the portage namespace. External script should be
updated accordingly, though links exist for backward compability.
-* -* support in package.keywords was changed as it was inconsistent with
+* -* support in package.keywords was changed as it was inconsistent with
ACCEPT_KEYWORDS behavior (also see
http://dev.gentoo.org/~genone/docs/KEYWORDS.stupid).
Previously having -* in package.keywords matched packages with KEYWORDS="-*",
@@ -225,7 +248,7 @@ portage-2.1.1
* emerge --search doesn't use regular expressions now anymore by default, so
emerge --search dvd+rw-tools now works as expected. Regular expressions can be enabled
- by prefixing the search string with %.
+ by prefixing the search string with %.
* emerge --depclean algorithm is much safer than the old one.
* emerge --newuse detects changes in IUSE that previously went undetected.
@@ -238,9 +261,9 @@ portage-2.1
by the name of --alphabetical. Adding the option to EMERGE_DEFAULT_OPTS
in make.conf will restore the old behaviour permanently.
* The deprecated --inject has been removed, use /etc/portage/profile/package.provided
-* The deprecated --upgradeonly has been removed, use /etc/portage/package.*
+* The deprecated --upgradeonly has been removed, use /etc/portage/package.*
instead.
-* 'emerge sync' has been deprecated, use 'emerge --sync' instead (same
+* 'emerge sync' has been deprecated, use 'emerge --sync' instead (same
for other actions)
* Tools that call emerge should override the EMERGE_DEFAULT_OPTS environment
variable or use the emerge --ignore-default-opts option.
@@ -249,6 +272,6 @@ portage-2.1
* autouse (use.defaults) has been deprecated by specifying USE_ORDER in make.defaults
Users may still turn this back on by specifying USE_ORDER="env:pkg:conf:auto:defaults"
in make.conf. Interested in figuring out what use flags were turned off? Check out
- /usr/portage/profiles/base/use.defaults and other use.defaults files that correspond
+ /usr/portage/profiles/base/use.defaults and other use.defaults files that correspond
to your profile.
diff --git a/bin/archive-conf b/bin/archive-conf
index 797866817..f73ca425e 100755
--- a/bin/archive-conf
+++ b/bin/archive-conf
@@ -1,5 +1,5 @@
-#!/usr/bin/python
-# Copyright 1999-2006 Gentoo Foundation
+#!/usr/bin/python -b
+# Copyright 1999-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
#
@@ -12,43 +12,21 @@
from __future__ import print_function
import sys
-try:
- import portage
-except ImportError:
- from os import path as osp
- sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
- import portage
+from os import path as osp
+pym_path = osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")
+sys.path.insert(0, pym_path)
+import portage
+portage._internal_caller = True
+
+import portage.dispatch_conf
from portage import os
-from portage import dispatch_conf
+from portage.checksum import perform_md5
FIND_EXTANT_CONTENTS = "find %s -name CONTENTS"
MANDATORY_OPTS = [ 'archive-dir' ]
-try:
- import fchksum
- def perform_checksum(filename): return fchksum.fmd5t(filename)
-except ImportError:
- import md5
- def md5_to_hex(md5sum):
- hexform = ""
- for ix in range(len(md5sum)):
- hexform = hexform + "%02x" % ord(md5sum[ix])
- return hexform.lower()
-
- def perform_checksum(filename):
- f = open(filename, 'rb')
- blocksize=32768
- data = f.read(blocksize)
- size = 0
- sum = md5.new()
- while data:
- sum.update(data)
- size = size + len(data)
- data = f.read(blocksize)
- return (md5_to_hex(sum.digest()),size)
-
def archive_conf():
args = []
content_files = []
@@ -63,19 +41,19 @@ def archive_conf():
md5_match_hash[conf] = ''
# Find all the CONTENT files in VDB_PATH.
- content_files += os.popen(FIND_EXTANT_CONTENTS %
- (os.path.join(portage.settings['EROOT'], portage.VDB_PATH))).readlines()
+ with os.popen(FIND_EXTANT_CONTENTS % (os.path.join(portage.settings['EROOT'], portage.VDB_PATH))) as f:
+ content_files += f.readlines()
# Search for the saved md5 checksum of all the specified config files
# and see if the current file is unmodified or not.
try:
todo_cnt = len(args)
- for file in content_files:
- file = file.rstrip()
+ for filename in content_files:
+ filename = filename.rstrip()
try:
- contents = open(file, "r")
+ contents = open(filename, "r")
except IOError as e:
- print('archive-conf: Unable to open %s: %s' % (file, e), file=sys.stderr)
+ print('archive-conf: Unable to open %s: %s' % (filename, e), file=sys.stderr)
sys.exit(1)
lines = contents.readlines()
for line in lines:
@@ -84,7 +62,7 @@ def archive_conf():
for conf in args:
if items[1] == conf:
stored = items[2].lower()
- real = perform_checksum(conf)[0].lower()
+ real = perform_md5(conf).lower()
if stored == real:
md5_match_hash[conf] = conf
todo_cnt -= 1
diff --git a/bin/banned-helper b/bin/banned-helper
deleted file mode 100755
index 17ea9915d..000000000
--- a/bin/banned-helper
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/bash
-# Copyright 2009 Gentoo Foundation
-# Distributed under the terms of the GNU General Public License v2
-
-die "'${0##*/}' has been banned for EAPI '$EAPI'"
-exit 1
diff --git a/bin/bashrc-functions.sh b/bin/bashrc-functions.sh
index 4da558581..503b17224 100644
--- a/bin/bashrc-functions.sh
+++ b/bin/bashrc-functions.sh
@@ -1,9 +1,9 @@
#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
+# Copyright 1999-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
portageq() {
- PYTHONPATH=${PORTAGE_PYM_PATH}${PYTHONPATH:+:}${PYTHONPATH} \
+ PYTHONPATH=${PORTAGE_PYTHONPATH:-${PORTAGE_PYM_PATH}}\
"${PORTAGE_PYTHON:-/usr/bin/python}" "${PORTAGE_BIN_PATH}/portageq" "$@"
}
@@ -23,71 +23,16 @@ register_success_hook() {
done
}
-strip_duplicate_slashes() {
+__strip_duplicate_slashes() {
if [[ -n $1 ]] ; then
local removed=$1
while [[ ${removed} == *//* ]] ; do
removed=${removed//\/\///}
done
- echo ${removed}
+ echo "${removed}"
fi
}
-# this is a function for removing any directory matching a passed in pattern from
-# PATH
-remove_path_entry() {
- save_IFS
- IFS=":"
- stripped_path="${PATH}"
- while [ -n "$1" ]; do
- cur_path=""
- for p in ${stripped_path}; do
- if [ "${p/${1}}" == "${p}" ]; then
- cur_path="${cur_path}:${p}"
- fi
- done
- stripped_path="${cur_path#:*}"
- shift
- done
- restore_IFS
- PATH="${stripped_path}"
-}
-
-# Set given variables unless these variable have been already set (e.g. during emerge
-# invocation) to values different than values set in make.conf.
-set_unless_changed() {
- if [[ $# -lt 1 ]]; then
- die "${FUNCNAME}() requires at least 1 argument: VARIABLE=VALUE"
- fi
-
- local argument value variable
- for argument in "$@"; do
- if [[ ${argument} != *=* ]]; then
- die "${FUNCNAME}(): Argument '${argument}' has incorrect syntax"
- fi
- variable="${argument%%=*}"
- value="${argument#*=}"
- if eval "[[ \${${variable}} == \$(env -u ${variable} portageq envvar ${variable}) ]]"; then
- eval "${variable}=\"\${value}\""
- fi
- done
-}
-
-# Unset given variables unless these variable have been set (e.g. during emerge
-# invocation) to values different than values set in make.conf.
-unset_unless_changed() {
- if [[ $# -lt 1 ]]; then
- die "${FUNCNAME}() requires at least 1 argument: VARIABLE"
- fi
-
- local variable
- for variable in "$@"; do
- if eval "[[ \${${variable}} == \$(env -u ${variable} portageq envvar ${variable}) ]]"; then
- unset ${variable}
- fi
- done
-}
-
KV_major() {
[[ -z $1 ]] && return 1
diff --git a/bin/binhost-snapshot b/bin/binhost-snapshot
index 9d2697d03..c2204f03d 100755
--- a/bin/binhost-snapshot
+++ b/bin/binhost-snapshot
@@ -1,9 +1,8 @@
-#!/usr/bin/python
-# Copyright 2010-2011 Gentoo Foundation
+#!/usr/bin/python -b
+# Copyright 2010-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
import io
-import optparse
import os
import sys
import textwrap
@@ -13,13 +12,12 @@ try:
except ImportError:
from urlparse import urlparse
-try:
- import portage
-except ImportError:
- from os import path as osp
- sys.path.insert(0, osp.join(osp.dirname(osp.dirname(
- osp.realpath(__file__))), "pym"))
- import portage
+from os import path as osp
+pym_path = osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")
+sys.path.insert(0, pym_path)
+import portage
+portage._internal_caller = True
+from portage.util._argparse import ArgumentParser
def parse_args(argv):
prog_name = os.path.basename(argv[0])
@@ -33,7 +31,7 @@ def parse_args(argv):
usage += "\n\n"
for line in textwrap.wrap(prog_desc, 70):
- usage += line + "\n"
+ usage += line + "\n"
usage += "\n"
usage += "Required Arguments:\n\n"
@@ -47,11 +45,12 @@ def parse_args(argv):
"write Packages index with\n" + \
" snapshot_uri"
- parser = optparse.OptionParser(usage=usage)
- parser.add_option('--hardlinks', help='create hardlinks (y or n, default is y)',
- choices=('y', 'n'))
- parser.set_defaults(hardlinks='y')
- options, args = parser.parse_args(argv[1:])
+ parser = ArgumentParser(usage=usage)
+ parser.add_argument('--hardlinks',
+ help='create hardlinks (y or n, default is y)',
+ choices=('y', 'n'),
+ default='y')
+ options, args = parser.parse_known_args(argv[1:])
if len(args) != 4:
parser.error("Required 4 arguments, got %d" % (len(args),))
diff --git a/bin/check-implicit-pointer-usage.py b/bin/check-implicit-pointer-usage.py
index 8822c4504..242436c1d 100755
--- a/bin/check-implicit-pointer-usage.py
+++ b/bin/check-implicit-pointer-usage.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python -b
# Ripped from HP and updated from Debian
# Update by Gentoo to support unicode output
diff --git a/bin/chpathtool.py b/bin/chpathtool.py
index d0d49cb6d..64606623a 100755
--- a/bin/chpathtool.py
+++ b/bin/chpathtool.py
@@ -1,15 +1,26 @@
-#!/usr/bin/python
-# Copyright 2011 Gentoo Foundation
+#!/usr/bin/python -b
+# Copyright 2011-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
+"""Helper tool for converting installed files to custom prefixes.
+
+In other words, eprefixy $D for Gentoo/Prefix."""
+
import io
-import optparse
import os
import stat
import sys
-CONTENT_ENCODING = "utf_8"
-FS_ENCODING = "utf_8"
+from portage.util._argparse import ArgumentParser
+
+# Argument parsing compatibility for Python 2.6 using optparse.
+if sys.hexversion < 0x2070000:
+ from optparse import OptionParser
+
+from optparse import OptionError
+
+CONTENT_ENCODING = 'utf_8'
+FS_ENCODING = 'utf_8'
try:
import magic
@@ -41,7 +52,9 @@ class IsTextFile(object):
def _is_text_magic(self, filename):
mime_type = self._m.file(filename)
- return mime_type.startswith("text/")
+ if isinstance(mime_type, bytes):
+ mime_type = mime_type.decode('ascii', 'replace')
+ return mime_type.startswith('text/')
def _is_text_encoding(self, filename):
try:
@@ -64,7 +77,7 @@ def chpath_inplace(filename, is_text_file, old, new):
try:
orig_mode = stat.S_IMODE(os.lstat(filename).st_mode)
except OSError as e:
- sys.stderr.write("%s: %s\n" % (e, filename))
+ sys.stderr.write('%s: %s\n' % (e, filename))
return
temp_mode = 0o200 | orig_mode
os.chmod(filename, temp_mode)
@@ -121,8 +134,12 @@ def chpath_inplace(filename, is_text_file, old, new):
f.close()
if modified:
- orig_mtime = orig_stat[stat.ST_MTIME]
- os.utime(filename, (orig_mtime, orig_mtime))
+ if sys.hexversion >= 0x3030000:
+ orig_mtime = orig_stat.st_mtime_ns
+ os.utime(filename, ns=(orig_mtime, orig_mtime))
+ else:
+ orig_mtime = orig_stat[stat.ST_MTIME]
+ os.utime(filename, (orig_mtime, orig_mtime))
return modified
def chpath_inplace_symlink(filename, st, old, new):
@@ -135,14 +152,37 @@ def chpath_inplace_symlink(filename, st, old, new):
def main(argv):
- usage = "%s [options] <location> <old> <new>" % (os.path.basename(argv[0],))
- parser = optparse.OptionParser(usage=usage)
- options, args = parser.parse_args(argv[1:])
-
- if len(args) != 3:
- parser.error("3 args required, got %s" % (len(args),))
-
- location, old, new = args
+ parser = ArgumentParser(description=__doc__)
+ try:
+ parser.add_argument('location', default=None,
+ help='root directory (e.g. $D)')
+ parser.add_argument('old', default=None,
+ help='original build prefix (e.g. /)')
+ parser.add_argument('new', default=None,
+ help='new install prefix (e.g. $EPREFIX)')
+ opts = parser.parse_args(argv)
+
+ location, old, new = opts.location, opts.old, opts.new
+ except OptionError:
+ # Argument parsing compatibility for Python 2.6 using optparse.
+ if sys.hexversion < 0x2070000:
+ parser = OptionParser(description=__doc__,
+ usage="usage: %prog [-h] location old new\n\n" + \
+ " location: root directory (e.g. $D)\n" + \
+ " old: original build prefix (e.g. /)\n" + \
+ " new: new install prefix (e.g. $EPREFIX)")
+
+ (opts, args) = parser.parse_args()
+
+ if len(args) != 3:
+ parser.print_usage()
+ print("%s: error: expected 3 arguments, got %i"
+ % (__file__, len(args)))
+ return
+
+ location, old, new = args[0:3]
+ else:
+ raise
is_text_file = IsTextFile()
@@ -178,5 +218,5 @@ def main(argv):
return os.EX_OK
-if __name__ == "__main__":
- sys.exit(main(sys.argv))
+if __name__ == '__main__':
+ sys.exit(main(sys.argv[1:]))
diff --git a/bin/clean_locks b/bin/clean_locks
index 8c4299c92..3e969f2c6 100755
--- a/bin/clean_locks
+++ b/bin/clean_locks
@@ -1,21 +1,17 @@
-#!/usr/bin/python -O
-# Copyright 1999-2006 Gentoo Foundation
+#!/usr/bin/python -bO
+# Copyright 1999-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
from __future__ import print_function
import sys, errno
-try:
- import portage
-except ImportError:
- from os import path as osp
- sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
- import portage
-
-from portage import os
+from os import path as osp
+pym_path = osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")
+sys.path.insert(0, pym_path)
+import portage
+portage._internal_caller = True
if not sys.argv[1:] or "--help" in sys.argv or "-h" in sys.argv:
- import portage
print()
print("You must specify directories with hardlink-locks to clean.")
print("You may optionally specify --force, which will remove all")
@@ -26,11 +22,11 @@ if not sys.argv[1:] or "--help" in sys.argv or "-h" in sys.argv:
print("%s --force %s/.locks" % (sys.argv[0], portage.settings["DISTDIR"]))
print()
sys.exit(1)
-
+
force = False
if "--force" in sys.argv[1:]:
force=True
-
+
for x in sys.argv[1:]:
if x == "--force":
continue
@@ -38,7 +34,7 @@ for x in sys.argv[1:]:
for y in portage.locks.hardlock_cleanup(x, remove_all_locks=force):
print(y)
print()
-
+
except OSError as e:
if e.errno in (errno.ENOENT, errno.ENOTDIR):
print("!!! %s is not a directory or does not exist" % x)
diff --git a/bin/dispatch-conf b/bin/dispatch-conf
index 139a001e8..4b0c0ac8f 100755
--- a/bin/dispatch-conf
+++ b/bin/dispatch-conf
@@ -1,5 +1,5 @@
-#!/usr/bin/python -O
-# Copyright 1999-2011 Gentoo Foundation
+#!/usr/bin/python -bO
+# Copyright 1999-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
#
@@ -16,19 +16,15 @@ from __future__ import print_function
from stat import ST_GID, ST_MODE, ST_UID
from random import random
import atexit, re, shutil, stat, sys
-
-try:
- import portage
-except ImportError:
- from os import path as osp
- sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
- import portage
-
+from os import path as osp
+pym_path = osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")
+sys.path.insert(0, pym_path)
+import portage
+portage._internal_caller = True
from portage import os
-from portage import dispatch_conf
from portage import _unicode_decode
from portage.dispatch_conf import diffstatusoutput
-from portage.process import find_binary
+from portage.process import find_binary, spawn
FIND_EXTANT_CONFIGS = "find '%s' %s -name '._cfg????_%s' ! -name '.*~' ! -iname '.*.bak' -print"
DIFF_CONTENTS = "diff -Nu '%s' '%s'"
@@ -83,7 +79,7 @@ class dispatch:
confs = []
count = 0
- config_root = portage.const.EPREFIX or os.sep
+ config_root = portage.settings["EPREFIX"] or os.sep
self.options = portage.dispatch_conf.read_config(MANDATORY_OPTS)
if "log-file" in self.options:
@@ -411,7 +407,8 @@ class dispatch:
def do_help (self):
- print(); print
+ print()
+ print()
print(' u -- update current config with new config and continue')
print(' z -- zap (delete) new config and continue')
@@ -431,7 +428,7 @@ class dispatch:
def getch ():
# from ASPN - Danny Yoo
#
- import sys, tty, termios
+ import tty, termios
fd = sys.stdin.fileno()
old_settings = termios.tcgetattr(fd)
@@ -456,17 +453,18 @@ def clear_screen():
pass
os.system("clear 2>/dev/null")
-from portage.process import find_binary, spawn
shell = os.environ.get("SHELL")
if not shell or not os.access(shell, os.EX_OK):
shell = find_binary("sh")
def spawn_shell(cmd):
if shell:
+ sys.__stdout__.flush()
+ sys.__stderr__.flush()
spawn([shell, "-c", cmd], env=os.environ,
- fd_pipes = { 0 : sys.stdin.fileno(),
- 1 : sys.stdout.fileno(),
- 2 : sys.stderr.fileno()})
+ fd_pipes = { 0 : portage._get_stdin().fileno(),
+ 1 : sys.__stdout__.fileno(),
+ 2 : sys.__stderr__.fileno()})
else:
os.system(cmd)
diff --git a/bin/dohtml.py b/bin/dohtml.py
index 3e80ef5f6..5359f5e89 100755
--- a/bin/dohtml.py
+++ b/bin/dohtml.py
@@ -1,5 +1,5 @@
-#!/usr/bin/python
-# Copyright 1999-2012 Gentoo Foundation
+#!/usr/bin/python -b
+# Copyright 1999-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
#
@@ -31,13 +31,25 @@
from __future__ import print_function
import os
+import shutil
import sys
+from portage.util import normalize_path
+
+# Change back to original cwd _after_ all imports (bug #469338).
+os.chdir(os.environ["__PORTAGE_HELPER_CWD"])
+
def dodir(path):
- os.spawnlp(os.P_WAIT, "install", "install", "-d", path)
+ try:
+ os.makedirs(path, 0o755)
+ except OSError:
+ if not os.path.isdir(path):
+ raise
+ os.chmod(path, 0o755)
def dofile(src,dst):
- os.spawnlp(os.P_WAIT, "install", "install", "-m0644", src, dst)
+ shutil.copy(src, dst)
+ os.chmod(dst, 0o644)
def eqawarn(lines):
cmd = "source '%s/isolated-functions.sh' ; " % \
@@ -55,14 +67,18 @@ unwarned_skipped_files = os.environ.get("PORTAGE_DOHTML_UNWARNED_SKIPPED_FILES",
def install(basename, dirname, options, prefix=""):
fullpath = basename
if prefix:
- fullpath = prefix + "/" + fullpath
+ fullpath = os.path.join(prefix, fullpath)
if dirname:
- fullpath = dirname + "/" + fullpath
+ fullpath = os.path.join(dirname, fullpath)
if options.DOCDESTTREE:
- destdir = options.ED + "usr/share/doc/" + options.PF + "/" + options.DOCDESTTREE + "/" + options.doc_prefix + "/" + prefix
+ desttree = options.DOCDESTTREE
else:
- destdir = options.ED + "usr/share/doc/" + options.PF + "/html/" + options.doc_prefix + "/" + prefix
+ desttree = "html"
+
+ destdir = os.path.join(options.ED, "usr", "share", "doc",
+ options.PF.lstrip(os.sep), desttree.lstrip(os.sep),
+ options.doc_prefix.lstrip(os.sep), prefix).rstrip(os.sep)
if not os.path.exists(fullpath):
sys.stderr.write("!!! dohtml: %s does not exist\n" % fullpath)
@@ -71,14 +87,15 @@ def install(basename, dirname, options, prefix=""):
ext = os.path.splitext(basename)[1][1:]
if ext in options.allowed_exts or basename in options.allowed_files:
dodir(destdir)
- dofile(fullpath, destdir + "/" + basename)
+ dofile(fullpath, os.path.join(destdir, basename))
elif warn_on_skipped_files and ext not in unwarned_skipped_extensions and basename not in unwarned_skipped_files:
skipped_files.append(fullpath)
elif options.recurse and os.path.isdir(fullpath) and \
basename not in options.disallowed_dirs:
for i in os.listdir(fullpath):
pfx = basename
- if prefix: pfx = prefix + "/" + pfx
+ if prefix:
+ pfx = os.path.join(prefix, pfx)
install(i, dirname, options, pfx)
elif not options.recurse and os.path.isdir(fullpath):
global skipped_directories
@@ -97,16 +114,22 @@ class OptionsClass:
if "PF" in os.environ:
self.PF = os.environ["PF"]
+ if self.PF:
+ self.PF = normalize_path(self.PF)
if "force-prefix" not in os.environ.get("FEATURES", "").split() and \
os.environ.get("EAPI", "0") in ("0", "1", "2"):
self.ED = os.environ.get("D", "")
else:
self.ED = os.environ.get("ED", "")
+ if self.ED:
+ self.ED = normalize_path(self.ED)
if "_E_DOCDESTTREE_" in os.environ:
self.DOCDESTTREE = os.environ["_E_DOCDESTTREE_"]
+ if self.DOCDESTTREE:
+ self.DOCDESTTREE = normalize_path(self.DOCDESTTREE)
self.allowed_exts = ['css', 'gif', 'htm', 'html', 'jpeg', 'jpg', 'js', 'png']
- if os.environ.get("EAPI", "0") in ("4-python",):
+ if os.environ.get("EAPI", "0") in ("4-python", "5-progress"):
self.allowed_exts += ['ico', 'svg', 'xhtml', 'xml']
self.allowed_files = []
self.disallowed_dirs = ['CVS']
@@ -153,6 +176,8 @@ def parse_args():
sys.exit(0)
elif arg == "-p":
options.doc_prefix = sys.argv[x]
+ if options.doc_prefix:
+ options.doc_prefix = normalize_path(options.doc_prefix)
else:
values = sys.argv[x].split(",")
if arg == "-A":
@@ -179,8 +204,17 @@ def main():
print("Allowed files :", options.allowed_files)
success = False
+ endswith_slash = (os.sep, os.sep + ".")
for x in args:
+ trailing_slash = x.endswith(endswith_slash)
+ x = normalize_path(x)
+ if trailing_slash:
+ # Modify behavior of basename and dirname
+ # as noted in bug #425214, causing foo/ to
+ # behave similarly to the way that foo/*
+ # behaves.
+ x += os.sep
basename = os.path.basename(x)
dirname = os.path.dirname(x)
success |= install(basename, dirname, options)
diff --git a/bin/eapi.sh b/bin/eapi.sh
new file mode 100644
index 000000000..623b89fee
--- /dev/null
+++ b/bin/eapi.sh
@@ -0,0 +1,145 @@
+#!/bin/bash
+# Copyright 2012 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+# PHASES
+
+___eapi_has_pkg_pretend() {
+ [[ ! ${1-${EAPI}} =~ ^(0|1|2|3)$ ]]
+}
+
+___eapi_has_src_prepare() {
+ [[ ! ${1-${EAPI}} =~ ^(0|1)$ ]]
+}
+
+___eapi_has_src_configure() {
+ [[ ! ${1-${EAPI}} =~ ^(0|1)$ ]]
+}
+
+___eapi_default_src_test_disables_parallel_jobs() {
+ [[ ${1-${EAPI}} =~ ^(0|1|2|3|4|4-python|4-slot-abi)$ ]]
+}
+
+___eapi_has_S_WORKDIR_fallback() {
+ [[ ${1-${EAPI}} =~ ^(0|1|2|3)$ ]]
+}
+
+# VARIABLES
+
+___eapi_has_prefix_variables() {
+ [[ ! ${1-${EAPI}} =~ ^(0|1|2)$ || " ${FEATURES} " == *" force-prefix "* ]]
+}
+
+___eapi_has_HDEPEND() {
+ [[ ${1-${EAPI}} =~ ^(5-hdepend)$ ]]
+}
+
+___eapi_has_RDEPEND_DEPEND_fallback() {
+ [[ ${1-${EAPI}} =~ ^(0|1|2|3)$ ]]
+}
+
+# HELPERS PRESENCE
+
+___eapi_has_dohard() {
+ [[ ${1-${EAPI}} =~ ^(0|1|2|3)$ ]]
+}
+
+___eapi_has_dosed() {
+ [[ ${1-${EAPI}} =~ ^(0|1|2|3)$ ]]
+}
+
+___eapi_has_docompress() {
+ [[ ! ${1-${EAPI}} =~ ^(0|1|2|3)$ ]]
+}
+
+___eapi_has_nonfatal() {
+ [[ ! ${1-${EAPI}} =~ ^(0|1|2|3)$ ]]
+}
+
+___eapi_has_doheader() {
+ [[ ! ${1-${EAPI}} =~ ^(0|1|2|3|4|4-python|4-slot-abi)$ ]]
+}
+
+___eapi_has_usex() {
+ [[ ! ${1-${EAPI}} =~ ^(0|1|2|3|4|4-python|4-slot-abi)$ ]]
+}
+
+___eapi_has_master_repositories() {
+ [[ ${1-${EAPI}} =~ ^(5-progress)$ ]]
+}
+
+___eapi_has_repository_path() {
+ [[ ${1-${EAPI}} =~ ^(5-progress)$ ]]
+}
+
+___eapi_has_available_eclasses() {
+ [[ ${1-${EAPI}} =~ ^(5-progress)$ ]]
+}
+
+___eapi_has_eclass_path() {
+ [[ ${1-${EAPI}} =~ ^(5-progress)$ ]]
+}
+
+___eapi_has_license_path() {
+ [[ ${1-${EAPI}} =~ ^(5-progress)$ ]]
+}
+
+___eapi_has_package_manager_build_user() {
+ [[ ${1-${EAPI}} =~ ^(5-progress)$ ]]
+}
+
+___eapi_has_package_manager_build_group() {
+ [[ ${1-${EAPI}} =~ ^(5-progress)$ ]]
+}
+
+# HELPERS BEHAVIOR
+
+___eapi_best_version_and_has_version_support_--host-root() {
+ [[ ! ${1-${EAPI}} =~ ^(0|1|2|3|4|4-python|4-slot-abi)$ ]]
+}
+
+___eapi_unpack_supports_xz() {
+ [[ ! ${1-${EAPI}} =~ ^(0|1|2)$ ]]
+}
+
+___eapi_econf_passes_--disable-dependency-tracking() {
+ [[ ! ${1-${EAPI}} =~ ^(0|1|2|3)$ ]]
+}
+
+___eapi_econf_passes_--disable-silent-rules() {
+ [[ ! ${1-${EAPI}} =~ ^(0|1|2|3|4|4-python|4-slot-abi)$ ]]
+}
+
+___eapi_use_enable_and_use_with_support_empty_third_argument() {
+ [[ ! ${1-${EAPI}} =~ ^(0|1|2|3)$ ]]
+}
+
+___eapi_dodoc_supports_-r() {
+ [[ ! ${1-${EAPI}} =~ ^(0|1|2|3)$ ]]
+}
+
+___eapi_doins_and_newins_preserve_symlinks() {
+ [[ ! ${1-${EAPI}} =~ ^(0|1|2|3)$ ]]
+}
+
+___eapi_newins_supports_reading_from_standard_input() {
+ [[ ! ${1-${EAPI}} =~ ^(0|1|2|3|4|4-python|4-slot-abi)$ ]]
+}
+
+___eapi_helpers_can_die() {
+ [[ ! ${1-${EAPI}} =~ ^(0|1|2|3)$ ]]
+}
+
+___eapi_disallows_helpers_in_global_scope() {
+ [[ ${1-${EAPI}} =~ ^(4-python|5-progress)$ ]]
+}
+
+___eapi_unpack_is_case_sensitive() {
+ [[ ${1-${EAPI}} =~ ^(0|1|2|3|4|4-python|4-slot-abi|5|5-hdepend)$ ]]
+}
+
+# OTHERS
+
+___eapi_enables_globstar() {
+ [[ ${1-${EAPI}} =~ ^(4-python|5-progress)$ ]]
+}
diff --git a/bin/ebuild b/bin/ebuild
index 65e5bef63..8f4b103c6 100755
--- a/bin/ebuild
+++ b/bin/ebuild
@@ -1,5 +1,5 @@
-#!/usr/bin/python -O
-# Copyright 1999-2012 Gentoo Foundation
+#!/usr/bin/python -bO
+# Copyright 1999-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
from __future__ import print_function
@@ -10,7 +10,7 @@ import sys
# This block ensures that ^C interrupts are handled quietly.
try:
- def exithandler(signum,frame):
+ def exithandler(signum, _frame):
signal.signal(signal.SIGINT, signal.SIG_IGN)
signal.signal(signal.SIGTERM, signal.SIG_IGN)
sys.exit(128 + signum)
@@ -24,7 +24,7 @@ try:
except KeyboardInterrupt:
sys.exit(128 + signal.SIGINT)
-def debug_signal(signum, frame):
+def debug_signal(_signum, _frame):
import pdb
pdb.set_trace()
@@ -35,51 +35,50 @@ else:
signal.signal(debug_signum, debug_signal)
-import imp
import io
-import optparse
import os
+from os import path as osp
+pym_path = osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")
+sys.path.insert(0, pym_path)
+import portage
+portage._internal_caller = True
+from portage import os
+from portage import _encodings
+from portage import _shell_quote
+from portage import _unicode_decode
+from portage import _unicode_encode
+from portage.const import VDB_PATH
+from portage.util._argparse import ArgumentParser
+from _emerge.Package import Package
+from _emerge.RootConfig import RootConfig
description = "See the ebuild(1) man page for more info"
usage = "Usage: ebuild <ebuild file> <command> [command] ..."
-parser = optparse.OptionParser(description=description, usage=usage)
+parser = ArgumentParser(description=description, usage=usage)
force_help = "When used together with the digest or manifest " + \
"command, this option forces regeneration of digests for all " + \
"distfiles associated with the current ebuild. Any distfiles " + \
"that do not already exist in ${DISTDIR} will be automatically fetched."
-parser.add_option("--force", help=force_help, action="store_true", dest="force")
-parser.add_option("--color", help="enable or disable color output",
- type="choice", choices=("y", "n"))
-parser.add_option("--debug", help="show debug output",
- action="store_true", dest="debug")
-parser.add_option("--version", help="show version and exit",
- action="store_true", dest="version")
-parser.add_option("--ignore-default-opts",
+parser.add_argument("--force", help=force_help, action="store_true")
+parser.add_argument("--color", help="enable or disable color output",
+ choices=("y", "n"))
+parser.add_argument("--debug", help="show debug output",
+ action="store_true")
+parser.add_argument("--version", help="show version and exit",
+ action="store_true")
+parser.add_argument("--ignore-default-opts",
action="store_true",
help="do not use the EBUILD_DEFAULT_OPTS environment variable")
-parser.add_option("--skip-manifest", help="skip all manifest checks",
- action="store_true", dest="skip_manifest")
-
-opts, pargs = parser.parse_args(args=sys.argv[1:])
+parser.add_argument("--skip-manifest", help="skip all manifest checks",
+ action="store_true")
-try:
- import portage
-except ImportError:
- from os import path as osp
- sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
- import portage
+opts, pargs = parser.parse_known_args(args=sys.argv[1:])
-portage.dep._internal_warnings = True
-from portage import os
-from portage import _encodings
-from portage import _shell_quote
-from portage import _unicode_decode
-from portage import _unicode_encode
-from portage.const import VDB_PATH
-from _emerge.Package import Package
-from _emerge.RootConfig import RootConfig
+def err(txt):
+ portage.writemsg('ebuild: %s\n' % (txt,), noiselevel=-1)
+ sys.exit(1)
if opts.version:
print("Portage", portage.VERSION)
@@ -89,8 +88,9 @@ if len(pargs) < 2:
parser.error("missing required args")
if not opts.ignore_default_opts:
- default_opts = portage.settings.get("EBUILD_DEFAULT_OPTS", "").split()
- opts, pargs = parser.parse_args(default_opts + sys.argv[1:])
+ default_opts = portage.util.shlex_split(
+ portage.settings.get("EBUILD_DEFAULT_OPTS", ""))
+ opts, pargs = parser.parse_known_args(default_opts + sys.argv[1:])
debug = opts.debug
force = opts.force
@@ -119,9 +119,7 @@ if ebuild.endswith(".ebuild"):
pf = os.path.basename(ebuild)[:-7]
if pf is None:
- portage.writemsg("'%s' does not end with '.ebuild'.\n" % \
- (ebuild,), noiselevel=-1)
- sys.exit(1)
+ err("%s: does not end with '.ebuild'" % (ebuild,))
if not os.path.isabs(ebuild):
mycwd = os.getcwd()
@@ -160,15 +158,14 @@ if ebuild_portdir != vdb_path and \
encoding=_encodings['content'], errors='strict')
print("Appending %s to PORTDIR_OVERLAY..." % ebuild_portdir)
- imp.reload(portage)
+ portage._reset_legacy_globals()
myrepo = None
if ebuild_portdir != vdb_path:
myrepo = portage.portdb.getRepositoryName(ebuild_portdir)
if not os.path.exists(ebuild):
- print("'%s' does not exist." % ebuild)
- sys.exit(1)
+ err('%s: does not exist' % (ebuild,))
ebuild_split = ebuild.split("/")
cpv = "%s/%s" % (ebuild_split[-3], pf)
@@ -179,8 +176,7 @@ with io.open(_unicode_encode(ebuild, encoding=_encodings['fs'], errors='strict')
if eapi is None:
eapi = "0"
if not portage.catpkgsplit(cpv, eapi=eapi):
- print("!!! %s does not follow correct package syntax." % (cpv))
- sys.exit(1)
+ err('%s: %s: does not follow correct package syntax' % (ebuild, cpv))
if ebuild.startswith(vdb_path):
mytree = "vartree"
@@ -189,8 +185,7 @@ if ebuild.startswith(vdb_path):
portage_ebuild = portage.db[portage.root][mytree].dbapi.findname(cpv, myrepo=myrepo)
if os.path.realpath(portage_ebuild) != ebuild:
- print("!!! Portage seems to think that %s is at %s" % (cpv, portage_ebuild))
- sys.exit(1)
+ err('Portage seems to think that %s is at %s' % (cpv, portage_ebuild))
else:
mytree = "porttree"
@@ -199,12 +194,10 @@ else:
portage_ebuild = portage.portdb.findname(cpv, myrepo=myrepo)
if not portage_ebuild or portage_ebuild != ebuild:
- print("!!! %s does not seem to have a valid PORTDIR structure." % ebuild)
- sys.exit(1)
+ err('%s: does not seem to have a valid PORTDIR structure' % (ebuild,))
if len(pargs) > 1 and "config" in pargs:
- print("config must be called on it's own, not combined with any other phase")
- sys.exit(1)
+ err('"config" must not be called with any other phase')
def discard_digests(myebuild, mysettings, mydbapi):
"""Discard all distfiles digests for the given ebuild. This is useful when
@@ -313,14 +306,16 @@ def stale_env_warning():
if ebuild_changed:
open(os.path.join(tmpsettings['PORTAGE_BUILDDIR'],
- '.ebuild_changed'), 'w')
+ '.ebuild_changed'), 'w').close()
from portage.exception import PermissionDenied, \
PortagePackageException, UnsupportedAPIException
-if 'digest' in tmpsettings.features and \
- not set(["digest", "manifest"]).intersection(pargs):
- pargs = ['digest'] + pargs
+if 'digest' in tmpsettings.features:
+ if pargs and pargs[0] not in ("digest", "manifest"):
+ pargs = ['digest'] + pargs
+ # We only need to build digests on the first pass.
+ tmpsettings.features.discard('digest')
checked_for_stale_env = False
@@ -334,7 +329,7 @@ for arg in pargs:
if arg in ("digest", "manifest") and force:
discard_digests(ebuild, tmpsettings, portage.portdb)
- a = portage.doebuild(ebuild, arg, portage.root, tmpsettings,
+ a = portage.doebuild(ebuild, arg, settings=tmpsettings,
debug=debug, tree=mytree,
vartree=portage.db[portage.root]['vartree'])
except KeyboardInterrupt:
diff --git a/bin/ebuild-helpers/4/dodoc b/bin/ebuild-helpers/4/dodoc
deleted file mode 120000
index 35080ada3..000000000
--- a/bin/ebuild-helpers/4/dodoc
+++ /dev/null
@@ -1 +0,0 @@
-../doins \ No newline at end of file
diff --git a/bin/ebuild-helpers/4/dohard b/bin/ebuild-helpers/4/dohard
deleted file mode 120000
index 1a6b57a39..000000000
--- a/bin/ebuild-helpers/4/dohard
+++ /dev/null
@@ -1 +0,0 @@
-../../banned-helper \ No newline at end of file
diff --git a/bin/ebuild-helpers/4/dosed b/bin/ebuild-helpers/4/dosed
deleted file mode 120000
index 1a6b57a39..000000000
--- a/bin/ebuild-helpers/4/dosed
+++ /dev/null
@@ -1 +0,0 @@
-../../banned-helper \ No newline at end of file
diff --git a/bin/ebuild-helpers/4/prepalldocs b/bin/ebuild-helpers/4/prepalldocs
deleted file mode 120000
index 1a6b57a39..000000000
--- a/bin/ebuild-helpers/4/prepalldocs
+++ /dev/null
@@ -1 +0,0 @@
-../../banned-helper \ No newline at end of file
diff --git a/bin/ebuild-helpers/sed b/bin/ebuild-helpers/bsd/sed
index b21e8569c..01b88471d 100755
--- a/bin/ebuild-helpers/sed
+++ b/bin/ebuild-helpers/bsd/sed
@@ -1,27 +1,27 @@
#!/bin/bash
-# Copyright 2007 Gentoo Foundation
+# Copyright 2007-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
scriptpath=${BASH_SOURCE[0]}
scriptname=${scriptpath##*/}
-if [[ sed == ${scriptname} ]] && [[ -n ${ESED} ]]; then
+if [[ sed == ${scriptname} && -n ${ESED} ]]; then
exec ${ESED} "$@"
elif type -P g${scriptname} > /dev/null ; then
exec g${scriptname} "$@"
else
old_IFS="${IFS}"
IFS=":"
-
+
for path in $PATH; do
- [[ ${path}/${scriptname} == ${scriptpath} ]] && continue
if [[ -x ${path}/${scriptname} ]]; then
- exec ${path}/${scriptname} "$@"
+ [[ ${path}/${scriptname} -ef ${scriptpath} ]] && continue
+ exec "${path}/${scriptname}" "$@"
exit 0
fi
done
-
+
IFS="${old_IFS}"
fi
-
+
exit 1
diff --git a/bin/ebuild-helpers/dobin b/bin/ebuild-helpers/dobin
index f90d8933c..0ba1eb0c4 100755
--- a/bin/ebuild-helpers/dobin
+++ b/bin/ebuild-helpers/dobin
@@ -1,19 +1,20 @@
#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
+# Copyright 1999-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
if [[ $# -lt 1 ]] ; then
- helpers_die "${0##*/}: at least one argument needed"
+ __helpers_die "${0##*/}: at least one argument needed"
exit 1
fi
-[[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) ED=${D} ;; esac
+if ! ___eapi_has_prefix_variables; then
+ ED=${D}
+fi
if [[ ! -d ${ED}${DESTTREE}/bin ]] ; then
- install -d "${ED}${DESTTREE}/bin" || { helpers_die "${0##*/}: failed to install ${ED}${DESTTREE}/bin"; exit 2; }
+ install -d "${ED}${DESTTREE}/bin" || { __helpers_die "${0##*/}: failed to install ${ED}${DESTTREE}/bin"; exit 2; }
fi
ret=0
@@ -28,5 +29,5 @@ for x in "$@" ; do
((ret|=$?))
done
-[[ $ret -ne 0 ]] && helpers_die "${0##*/} failed"
+[[ $ret -ne 0 ]] && __helpers_die "${0##*/} failed"
exit ${ret}
diff --git a/bin/ebuild-helpers/doconfd b/bin/ebuild-helpers/doconfd
index e14600022..a3c09a50e 100755
--- a/bin/ebuild-helpers/doconfd
+++ b/bin/ebuild-helpers/doconfd
@@ -4,7 +4,7 @@
if [[ $# -lt 1 ]] ; then
source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
- helpers_die "${0##*/}: at least one argument needed"
+ __helpers_die "${0##*/}: at least one argument needed"
exit 1
fi
diff --git a/bin/ebuild-helpers/dodir b/bin/ebuild-helpers/dodir
index 90a3efed4..e03ba9a58 100755
--- a/bin/ebuild-helpers/dodir
+++ b/bin/ebuild-helpers/dodir
@@ -1,13 +1,14 @@
#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
+# Copyright 1999-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
-[[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) ED=${D} ;; esac
+if ! ___eapi_has_prefix_variables; then
+ ED=${D}
+fi
install -d ${DIROPTIONS} "${@/#/${ED}/}"
ret=$?
-[[ $ret -ne 0 ]] && helpers_die "${0##*/} failed"
+[[ $ret -ne 0 ]] && __helpers_die "${0##*/} failed"
exit $ret
diff --git a/bin/ebuild-helpers/dodoc b/bin/ebuild-helpers/dodoc
index 1f333a615..99122c443 100755
--- a/bin/ebuild-helpers/dodoc
+++ b/bin/ebuild-helpers/dodoc
@@ -1,16 +1,24 @@
#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
+# Copyright 1999-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+if ___eapi_dodoc_supports_-r; then
+ exec \
+ env \
+ __PORTAGE_HELPER="dodoc" \
+ doins "$@"
+fi
+
if [ $# -lt 1 ] ; then
- helpers_die "${0##*/}: at least one argument needed"
- exit 1
+ __helpers_die "${0##*/}: at least one argument needed"
+ exit 1
fi
-[[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) ED=${D} ;; esac
+if ! ___eapi_has_prefix_variables; then
+ ED=${D}
+fi
dir="${ED}usr/share/doc/${PF}/${_E_DOCDESTTREE_}"
if [ ! -d "${dir}" ] ; then
@@ -30,5 +38,5 @@ for x in "$@" ; do
fi
done
-[[ $ret -ne 0 ]] && helpers_die "${0##*/} failed"
+[[ $ret -ne 0 ]] && __helpers_die "${0##*/} failed"
exit ${ret}
diff --git a/bin/ebuild-helpers/doenvd b/bin/ebuild-helpers/doenvd
index 28ab5d234..9287933a9 100755
--- a/bin/ebuild-helpers/doenvd
+++ b/bin/ebuild-helpers/doenvd
@@ -4,7 +4,7 @@
if [[ $# -lt 1 ]] ; then
source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
- helpers_die "${0##*/}: at least one argument needed"
+ __helpers_die "${0##*/}: at least one argument needed"
exit 1
fi
diff --git a/bin/ebuild-helpers/doexe b/bin/ebuild-helpers/doexe
index fb228f905..c34fcae74 100755
--- a/bin/ebuild-helpers/doexe
+++ b/bin/ebuild-helpers/doexe
@@ -1,23 +1,23 @@
#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
+# Copyright 1999-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
if [[ $# -lt 1 ]] ; then
- helpers_die "${0##*/}: at least one argument needed"
+ __helpers_die "${0##*/}: at least one argument needed"
exit 1
fi
-[[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) ED=${D} ;; esac
+if ! ___eapi_has_prefix_variables; then
+ ED=${D}
+fi
if [[ ! -d ${ED}${_E_EXEDESTTREE_} ]] ; then
install -d "${ED}${_E_EXEDESTTREE_}"
fi
-TMP=$T/.doexe_tmp
-mkdir "$TMP"
+TMP=$(mktemp -d "${T}/.doexe_tmp_XXXXXX")
ret=0
@@ -26,7 +26,7 @@ for x in "$@" ; do
cp "$x" "$TMP"
mysrc=$TMP/${x##*/}
elif [ -d "${x}" ] ; then
- vecho "doexe: warning, skipping directory ${x}"
+ __vecho "doexe: warning, skipping directory ${x}"
continue
else
mysrc="${x}"
@@ -42,5 +42,5 @@ done
rm -rf "$TMP"
-[[ $ret -ne 0 ]] && helpers_die "${0##*/} failed"
+[[ $ret -ne 0 ]] && __helpers_die "${0##*/} failed"
exit $ret
diff --git a/bin/ebuild-helpers/dohard b/bin/ebuild-helpers/dohard
index b52fd7c00..e0a44faf1 100755
--- a/bin/ebuild-helpers/dohard
+++ b/bin/ebuild-helpers/dohard
@@ -1,14 +1,22 @@
#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
+# Copyright 1999-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+if ! ___eapi_has_dohard; then
+ die "'${0##*/}' has been banned for EAPI '$EAPI'"
+ exit 1
+fi
+
if [[ $# -ne 2 ]] ; then
echo "$0: two arguments needed" 1>&2
exit 1
fi
-[[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) ED=${D} ;; esac
+if ! ___eapi_has_prefix_variables; then
+ ED=${D}
+fi
destdir=${2%/*}
[[ ! -d ${ED}${destdir} ]] && dodir "${destdir}"
diff --git a/bin/ebuild-helpers/doheader b/bin/ebuild-helpers/doheader
new file mode 100755
index 000000000..37953658b
--- /dev/null
+++ b/bin/ebuild-helpers/doheader
@@ -0,0 +1,19 @@
+#!/bin/bash
+# Copyright 1999-2012 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+if ! ___eapi_has_doheader; then
+ die "${0##*/} is not supported in EAPI ${EAPI}"
+fi
+
+if [[ $# -lt 1 ]] || [[ $1 == -r && $# -lt 2 ]] ; then
+ __helpers_die "${0##*/}: at least one argument needed"
+ exit 1
+fi
+
+exec \
+env \
+INSDESTTREE="/usr/include/" \
+doins "$@"
diff --git a/bin/ebuild-helpers/dohtml b/bin/ebuild-helpers/dohtml
index 630629a4b..75d3d00ab 100755
--- a/bin/ebuild-helpers/dohtml
+++ b/bin/ebuild-helpers/dohtml
@@ -1,14 +1,19 @@
#!/bin/bash
-# Copyright 2009-2010 Gentoo Foundation
+# Copyright 2009-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
PORTAGE_BIN_PATH=${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}
PORTAGE_PYM_PATH=${PORTAGE_PYM_PATH:-/usr/lib/portage/pym}
-PYTHONPATH=$PORTAGE_PYM_PATH${PYTHONPATH:+:}$PYTHONPATH \
+# Use safe cwd, avoiding unsafe import for bug #469338.
+export __PORTAGE_HELPER_CWD=${PWD}
+cd "${PORTAGE_PYM_PATH}"
+PYTHONPATH=${PORTAGE_PYTHONPATH:-${PORTAGE_PYM_PATH}} \
"${PORTAGE_PYTHON:-/usr/bin/python}" "$PORTAGE_BIN_PATH/dohtml.py" "$@"
ret=$?
-[[ $ret -ne 0 ]] && helpers_die "${0##*/} failed"
+# Restore cwd for display by __helpers_die
+cd "${__PORTAGE_HELPER_CWD}"
+[[ $ret -ne 0 ]] && __helpers_die "${0##*/} failed"
exit $ret
diff --git a/bin/ebuild-helpers/doinfo b/bin/ebuild-helpers/doinfo
index 8fd7d45f8..2edbdc592 100755
--- a/bin/ebuild-helpers/doinfo
+++ b/bin/ebuild-helpers/doinfo
@@ -1,19 +1,20 @@
#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
+# Copyright 1999-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
if [[ -z $1 ]] ; then
- helpers_die "${0##*/}: at least one argument needed"
- exit 1
+ __helpers_die "${0##*/}: at least one argument needed"
+ exit 1
fi
-[[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) ED=${D} ;; esac
+if ! ___eapi_has_prefix_variables; then
+ ED=${D}
+fi
if [[ ! -d ${ED}usr/share/info ]] ; then
- install -d "${ED}usr/share/info" || { helpers_die "${0##*/}: failed to install ${ED}usr/share/info"; exit 1; }
+ install -d "${ED}usr/share/info" || { __helpers_die "${0##*/}: failed to install ${ED}usr/share/info"; exit 1; }
fi
install -m0644 "$@" "${ED}usr/share/info"
@@ -22,6 +23,6 @@ if [ $rval -ne 0 ] ; then
for x in "$@" ; do
[ -e "$x" ] || echo "!!! ${0##*/}: $x does not exist" 1>&2
done
- helpers_die "${0##*/} failed"
+ __helpers_die "${0##*/} failed"
fi
exit $rval
diff --git a/bin/ebuild-helpers/doinitd b/bin/ebuild-helpers/doinitd
index b711e190a..476b858f6 100755
--- a/bin/ebuild-helpers/doinitd
+++ b/bin/ebuild-helpers/doinitd
@@ -4,7 +4,7 @@
if [[ $# -lt 1 ]] ; then
source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
- helpers_die "${0##*/}: at least one argument needed"
+ __helpers_die "${0##*/}: at least one argument needed"
exit 1
fi
diff --git a/bin/ebuild-helpers/doins b/bin/ebuild-helpers/doins
index 443bfdb21..c60e05789 100755
--- a/bin/ebuild-helpers/doins
+++ b/bin/ebuild-helpers/doins
@@ -1,14 +1,17 @@
#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
+# Copyright 1999-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
-if [[ ${0##*/} == dodoc ]] ; then
+helper=${__PORTAGE_HELPER:-${0##*/}}
+
+if [[ ${helper} == dodoc ]] ; then
if [ $# -eq 0 ] ; then
# default_src_install may call dodoc with no arguments
# when DOC is defined but empty, so simply return
# sucessfully in this case.
+ eqawarn "QA Notice: dodoc called with no arguments"
exit 0
fi
export INSOPTIONS=-m0644
@@ -16,7 +19,7 @@ if [[ ${0##*/} == dodoc ]] ; then
fi
if [ $# -lt 1 ] ; then
- helpers_die "${0##*/}: at least one argument needed"
+ __helpers_die "${helper}: at least one argument needed"
exit 1
fi
@@ -27,28 +30,26 @@ else
DOINSRECUR=n
fi
-[[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) export ED="${D}" ;; esac
+if ! ___eapi_has_prefix_variables; then
+ export ED="${D}"
+fi
if [[ ${INSDESTTREE#${ED}} != "${INSDESTTREE}" ]]; then
- vecho "-------------------------------------------------------" 1>&2
- vecho "You should not use \${D} or \${ED} with helpers." 1>&2
- vecho " --> ${INSDESTTREE}" 1>&2
- vecho "-------------------------------------------------------" 1>&2
- helpers_die "${0##*/} used with \${D} or \${ED}"
+ __vecho "-------------------------------------------------------" 1>&2
+ __vecho "You should not use \${D} or \${ED} with helpers." 1>&2
+ __vecho " --> ${INSDESTTREE}" 1>&2
+ __vecho "-------------------------------------------------------" 1>&2
+ __helpers_die "${helper} used with \${D} or \${ED}"
exit 1
fi
-case "$EAPI" in
- 0|1|2|3|3_pre2)
- PRESERVE_SYMLINKS=n
- ;;
- *)
- PRESERVE_SYMLINKS=y
- ;;
-esac
+if ___eapi_doins_and_newins_preserve_symlinks; then
+ PRESERVE_SYMLINKS=y
+else
+ PRESERVE_SYMLINKS=n
+fi
-export TMP=$T/.doins_tmp
+export TMP=$(mktemp -d "${T}/.doins_tmp_XXXXXX")
# Use separate directories to avoid potential name collisions.
mkdir -p "$TMP"/{1,2}
@@ -79,7 +80,7 @@ _doins() {
install ${INSOPTIONS} "${mysrc}" "${ED}${INSDESTTREE}/${mydir}"
rval=$?
[[ -n ${cleanup} ]] && rm -f "${cleanup}"
- [ $rval -ne 0 ] && echo "!!! ${0##*/}: $mysrc does not exist" 1>&2
+ [ $rval -ne 0 ] && echo "!!! ${helper}: $mysrc does not exist" 1>&2
return $rval
}
@@ -99,8 +100,8 @@ for x in "$@" ; do
if [[ $PRESERVE_SYMLINKS = n && -d $x ]] || \
[[ $PRESERVE_SYMLINKS = y && -d $x && ! -L $x ]] ; then
if [ "${DOINSRECUR}" == "n" ] ; then
- if [[ ${0##*/} == dodoc ]] ; then
- echo "!!! ${0##*/}: $x is a directory" 1>&2
+ if [[ ${helper} == dodoc ]] ; then
+ echo "!!! ${helper}: $x is a directory" 1>&2
((failed|=1))
fi
continue
@@ -155,4 +156,4 @@ for x in "$@" ; do
fi
done
rm -rf "$TMP"
-[[ $failed -ne 0 || $success -eq 0 ]] && { helpers_die "${0##*/} failed"; exit 1; } || exit 0
+[[ $failed -ne 0 || $success -eq 0 ]] && { __helpers_die "${helper} failed"; exit 1; } || exit 0
diff --git a/bin/ebuild-helpers/dolib b/bin/ebuild-helpers/dolib
index 9af541890..fd92d7f03 100755
--- a/bin/ebuild-helpers/dolib
+++ b/bin/ebuild-helpers/dolib
@@ -1,11 +1,12 @@
#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
+# Copyright 1999-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
-[[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) ED=${D} ;; esac
+if ! ___eapi_has_prefix_variables; then
+ ED=${D}
+fi
# Setup ABI cruft
LIBDIR_VAR="LIBDIR_${ABI}"
@@ -19,11 +20,11 @@ libdir="${ED}${DESTTREE}/${CONF_LIBDIR}"
if [[ $# -lt 1 ]] ; then
- helpers_die "${0##*/}: at least one argument needed"
+ __helpers_die "${0##*/}: at least one argument needed"
exit 1
fi
if [[ ! -d ${libdir} ]] ; then
- install -d "${libdir}" || { helpers_die "${0##*/}: failed to install ${libdir}"; exit 1; }
+ install -d "${libdir}" || { __helpers_die "${0##*/}: failed to install ${libdir}"; exit 1; }
fi
ret=0
@@ -42,5 +43,5 @@ for x in "$@" ; do
((ret|=$?))
done
-[[ $ret -ne 0 ]] && helpers_die "${0##*/} failed"
+[[ $ret -ne 0 ]] && __helpers_die "${0##*/} failed"
exit ${ret}
diff --git a/bin/ebuild-helpers/doman b/bin/ebuild-helpers/doman
index b4047ce40..d6808597a 100755
--- a/bin/ebuild-helpers/doman
+++ b/bin/ebuild-helpers/doman
@@ -1,16 +1,17 @@
#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
+# Copyright 1999-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
if [[ $# -lt 1 ]] ; then
- helpers_die "${0##*/}: at least one argument needed"
+ __helpers_die "${0##*/}: at least one argument needed"
exit 1
fi
-[[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) ED=${D} ;; esac
+if ! ___eapi_has_prefix_variables; then
+ ED=${D}
+fi
i18n=""
@@ -58,10 +59,10 @@ for x in "$@" ; do
((ret|=1))
fi
else
- vecho "doman: '${x}' is probably not a man page; skipping" 1>&2
+ __vecho "doman: '${x}' is probably not a man page; skipping" 1>&2
((ret|=1))
fi
done
-[[ $ret -ne 0 ]] && helpers_die "${0##*/} failed"
+[[ $ret -ne 0 ]] && __helpers_die "${0##*/} failed"
exit ${ret}
diff --git a/bin/ebuild-helpers/domo b/bin/ebuild-helpers/domo
index d994343a9..9a8dda38a 100755
--- a/bin/ebuild-helpers/domo
+++ b/bin/ebuild-helpers/domo
@@ -1,17 +1,18 @@
#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
+# Copyright 1999-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
mynum=${#}
if [ ${mynum} -lt 1 ] ; then
- helpers_die "${0}: at least one argument needed"
+ __helpers_die "${0}: at least one argument needed"
exit 1
fi
-[[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) ED=${D} ;; esac
+if ! ___eapi_has_prefix_variables; then
+ ED=${D}
+fi
if [ ! -d "${ED}${DESTTREE}/share/locale" ] ; then
install -d "${ED}${DESTTREE}/share/locale/"
@@ -34,5 +35,5 @@ for x in "$@" ; do
((ret|=$?))
done
-[[ $ret -ne 0 ]] && helpers_die "${0##*/} failed"
+[[ $ret -ne 0 ]] && __helpers_die "${0##*/} failed"
exit $ret
diff --git a/bin/ebuild-helpers/dosbin b/bin/ebuild-helpers/dosbin
index d101c8a6d..361ca83ca 100755
--- a/bin/ebuild-helpers/dosbin
+++ b/bin/ebuild-helpers/dosbin
@@ -1,19 +1,20 @@
#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
+# Copyright 1999-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
if [[ $# -lt 1 ]] ; then
- helpers_die "${0##*/}: at least one argument needed"
+ __helpers_die "${0##*/}: at least one argument needed"
exit 1
fi
-[[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) ED=${D} ;; esac
+if ! ___eapi_has_prefix_variables; then
+ ED=${D}
+fi
if [[ ! -d ${ED}${DESTTREE}/sbin ]] ; then
- install -d "${ED}${DESTTREE}/sbin" || { helpers_die "${0##*/}: failed to install ${ED}${DESTTREE}/sbin"; exit 2; }
+ install -d "${ED}${DESTTREE}/sbin" || { __helpers_die "${0##*/}: failed to install ${ED}${DESTTREE}/sbin"; exit 2; }
fi
ret=0
@@ -28,5 +29,5 @@ for x in "$@" ; do
((ret|=$?))
done
-[[ $ret -ne 0 ]] && helpers_die "${0##*/} failed"
+[[ $ret -ne 0 ]] && __helpers_die "${0##*/} failed"
exit ${ret}
diff --git a/bin/ebuild-helpers/dosed b/bin/ebuild-helpers/dosed
index f202df7a7..7db062963 100755
--- a/bin/ebuild-helpers/dosed
+++ b/bin/ebuild-helpers/dosed
@@ -1,14 +1,22 @@
#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
+# Copyright 1999-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+if ! ___eapi_has_dosed; then
+ die "'${0##*/}' has been banned for EAPI '$EAPI'"
+ exit 1
+fi
+
if [[ $# -lt 1 ]] ; then
echo "!!! ${0##*/}: at least one argument needed" >&2
exit 1
fi
-[[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) ED=${D} ;; esac
+if ! ___eapi_has_prefix_variables; then
+ ED=${D}
+fi
ret=0
file_found=0
diff --git a/bin/ebuild-helpers/dosym b/bin/ebuild-helpers/dosym
index 2489e22a2..649b100de 100755
--- a/bin/ebuild-helpers/dosym
+++ b/bin/ebuild-helpers/dosym
@@ -5,12 +5,13 @@
source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
if [[ $# -ne 2 ]] ; then
- helpers_die "${0##*/}: two arguments needed"
+ __helpers_die "${0##*/}: two arguments needed"
exit 1
fi
-[[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) ED=${D} ;; esac
+if ! ___eapi_has_prefix_variables; then
+ ED=${D}
+fi
if [[ ${2} == */ ]] || \
[[ -d ${ED}${2} && ! -L ${ED}${2} ]] ; then
@@ -26,5 +27,5 @@ target="${1}"
ln -snf "${target}" "${ED}${2}"
ret=$?
-[[ $ret -ne 0 ]] && helpers_die "${0##*/} failed"
+[[ $ret -ne 0 ]] && __helpers_die "${0##*/} failed"
exit $ret
diff --git a/bin/ebuild-helpers/ecompress b/bin/ebuild-helpers/ecompress
index b61421b00..71287b4b0 100755
--- a/bin/ebuild-helpers/ecompress
+++ b/bin/ebuild-helpers/ecompress
@@ -5,7 +5,7 @@
source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
if [[ -z $1 ]] ; then
- helpers_die "${0##*/}: at least one argument needed"
+ __helpers_die "${0##*/}: at least one argument needed"
exit 1
fi
@@ -68,7 +68,7 @@ decompress_args() {
case $1 in
--suffix)
- [[ -n $2 ]] && vecho "${0##*/}: --suffix takes no additional arguments" 1>&2
+ [[ -n $2 ]] && __vecho "${0##*/}: --suffix takes no additional arguments" 1>&2
if [[ ! -e ${T}/.ecompress.suffix ]] ; then
set -e
@@ -93,7 +93,7 @@ case $1 in
cat "${T}/.ecompress.suffix"
;;
--bin)
- [[ -n $2 ]] && vecho "${0##*/}: --bin takes no additional arguments" 1>&2
+ [[ -n $2 ]] && __vecho "${0##*/}: --bin takes no additional arguments" 1>&2
echo "${PORTAGE_COMPRESS} ${PORTAGE_COMPRESS_FLAGS}"
;;
@@ -104,18 +104,18 @@ case $1 in
>> "$x"
((ret|=$?))
done
- [[ $ret -ne 0 ]] && helpers_die "${0##*/} failed"
+ [[ $ret -ne 0 ]] && __helpers_die "${0##*/} failed"
exit $ret
;;
--dequeue)
- [[ -n $2 ]] && vecho "${0##*/}: --dequeue takes no additional arguments" 1>&2
+ [[ -n $2 ]] && __vecho "${0##*/}: --dequeue takes no additional arguments" 1>&2
find "${D}" -name '*.ecompress.file' -print0 \
| sed -e 's:\.ecompress\.file::g' \
| ${XARGS} -0 ecompress
find "${D}" -name '*.ecompress.file' -print0 | ${XARGS} -0 rm -f
;;
--*)
- helpers_die "${0##*/}: unknown arguments '$*'"
+ __helpers_die "${0##*/}: unknown arguments '$*'"
exit 1
;;
*)
@@ -155,7 +155,7 @@ case $1 in
# Finally, let's actually do some real work
"${PORTAGE_COMPRESS}" ${PORTAGE_COMPRESS_FLAGS} "$@"
ret=$?
- [[ $ret -ne 0 ]] && helpers_die "${0##*/} failed"
+ [[ $ret -ne 0 ]] && __helpers_die "${0##*/} failed"
exit $ret
;;
esac
diff --git a/bin/ebuild-helpers/ecompressdir b/bin/ebuild-helpers/ecompressdir
index 6801a07d4..eca588869 100755
--- a/bin/ebuild-helpers/ecompressdir
+++ b/bin/ebuild-helpers/ecompressdir
@@ -1,18 +1,21 @@
#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
+# Copyright 1999-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/helper-functions.sh
if [[ -z $1 ]] ; then
- helpers_die "${0##*/}: at least one argument needed"
+ __helpers_die "${0##*/}: at least one argument needed"
exit 1
fi
-[[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) ED=${D} EPREFIX= ;; esac
+if ! ___eapi_has_prefix_variables; then
+ ED=${D} EPREFIX=
+fi
-case $1 in
+SIZE_LIMIT=''
+while [[ $# -gt 0 ]] ; do
+ case $1 in
--ignore)
shift
for skip in "$@" ; do
@@ -27,45 +30,66 @@ case $1 in
set -- "${@/#/${ED}}"
ret=0
for x in "$@" ; do
- >> "$x"
+ # Stash the limit in the .dir file so we can reload it later.
+ printf "${SIZE_LIMIT}" > "${x}"
((ret|=$?))
done
- [[ $ret -ne 0 ]] && helpers_die "${0##*/} failed"
+ [[ $ret -ne 0 ]] && __helpers_die "${0##*/} failed"
exit $ret
;;
--dequeue)
- [[ -n $2 ]] && vecho "${0##*/}: --dequeue takes no additional arguments" 1>&2
+ [[ -n $2 ]] && __vecho "${0##*/}: --dequeue takes no additional arguments" 1>&2
find "${ED}" -name '*.ecompress.dir' -print0 \
| sed -e 's:\.ecompress\.dir::g' -e "s:${ED}:/:g" \
| ${XARGS} -0 ecompressdir
find "${ED}" -name '*.ecompress.skip' -print0 | ${XARGS} -0 rm -f
exit 0
;;
+ --limit)
+ SIZE_LIMIT=$2
+ shift
+ ;;
--*)
- helpers_die "${0##*/}: unknown arguments '$*'"
+ __helpers_die "${0##*/}: unknown arguments '$*'"
exit 1
;;
-esac
+ *)
+ break
+ ;;
+ esac
+ shift
+done
# figure out the new suffix
suffix=$(ecompress --suffix)
-# funk_up_dir(action, suffix, binary)
+# funk_up_dir(action, suffix, binary, [size_limit])
# - action: compress or decompress
# - suffix: the compression suffix to work with
# - binary: the program to execute that'll compress/decompress
+# - size_limit: if compressing, skip files smaller than this
# The directory we act on is implied in the ${dir} variable
funk_up_dir() {
- local act=$1 suffix=$2 binary=$3
+ local act=$1 suffix=$2 binary=$3 size_limit=$4
local negate=""
[[ ${act} == "compress" ]] && negate="!"
local ret=0
# first we act on all the files
- find "${dir}" -type f ${negate} -iname '*'${suffix} -print0 | ${XARGS} -0 ${binary}
+ local args=(
+ -type f
+ ${negate} -iname "*${suffix}"
+ )
+ [[ -n ${size_limit} ]] && args+=( -size "+${size_limit}c" )
+ find "${dir}" "${args[@]}" -print0 | ${XARGS} -0 ${binary}
((ret|=$?))
+ # Repeat until nothing changes, in order to handle multiple
+ # levels of indirection (see bug #470916).
+ local -i indirection=0
+ while true ; do
+ local something_changed=
while read -r -d $'\0' brokenlink ; do
[[ -e ${brokenlink} ]] && continue
olddest=$(readlink "${brokenlink}")
@@ -91,12 +115,22 @@ funk_up_dir() {
else
[[ -f "${dir}/${brokenlink%/*}/${newdest}" ]] || continue
fi
+ something_changed=${brokenlink}
rm -f "${brokenlink}"
[[ ${act} == "compress" ]] \
&& ln -snf "${newdest}" "${brokenlink}${suffix}" \
|| ln -snf "${newdest}" "${brokenlink%${suffix}}"
((ret|=$?))
done < <(find "${dir}" -type l -print0)
+ [[ -n ${something_changed} ]] || break
+ (( indirection++ ))
+ if (( indirection >= 100 )) ; then
+ # Protect against possibility of a bug triggering an endless loop.
+ eerror "ecompressdir: too many levels of indirection for" \
+ "'${actual_dir#${ED}}/${something_changed#./}'"
+ break
+ fi
+ done
return ${ret}
}
@@ -133,13 +167,13 @@ decompressors=(
".lzma" "unxz -f"
)
-multijob_init
+__multijob_init
for dir in "$@" ; do
dir=${dir#/}
dir="${ED}${dir}"
if [[ ! -d ${dir} ]] ; then
- vecho "${0##*/}: /${dir#${ED}} does not exist!"
+ __vecho "${0##*/}: /${dir#${ED}} does not exist!"
continue
fi
cd "${dir}"
@@ -151,24 +185,25 @@ for dir in "$@" ; do
# since we've been requested to compress the whole dir,
# delete any individual queued requests
+ size_limit=${SIZE_LIMIT:-$(<"${actual_dir}.ecompress.dir")}
rm -f "${actual_dir}.ecompress.dir"
find "${dir}" -type f -name '*.ecompress.file' -print0 | ${XARGS} -0 rm -f
# not uncommon for packages to compress doc files themselves
- for (( d = 0; d < ${#decompressors[@]}; d += 2 )) ; do
+ for (( i = 0; i < ${#decompressors[@]}; i += 2 )) ; do
# It's faster to parallelize at this stage than to try to
# parallelize the compressors. This is because the find|xargs
# ends up launching less compressors overall, so the overhead
# of forking children ends up dominating.
(
- multijob_child_init
+ __multijob_child_init
funk_up_dir "decompress" "${decompressors[i]}" "${decompressors[i+1]}"
) &
- multijob_post_fork
+ __multijob_post_fork
: $(( ret |= $? ))
done
- multijob_finish
+ __multijob_finish
: $(( ret |= $? ))
# forcibly break all hard links as some compressors whine about it
@@ -177,8 +212,8 @@ for dir in "$@" ; do
# now lets do our work
if [[ -n ${suffix} ]] ; then
- vecho "${0##*/}: $(ecompress --bin) /${actual_dir#${ED}}"
- funk_up_dir "compress" "${suffix}" "ecompress"
+ __vecho "${0##*/}: $(ecompress --bin) /${actual_dir#${ED}}"
+ funk_up_dir "compress" "${suffix}" "ecompress" "${size_limit}"
: $(( ret |= $? ))
fi
@@ -186,5 +221,5 @@ for dir in "$@" ; do
restore_skip_dirs
done
-[[ $ret -ne 0 ]] && helpers_die "${0##*/} failed"
+[[ $ret -ne 0 ]] && __helpers_die "${0##*/} failed"
exit ${ret}
diff --git a/bin/ebuild-helpers/emake b/bin/ebuild-helpers/emake
index d842781a7..69d836f1a 100755
--- a/bin/ebuild-helpers/emake
+++ b/bin/ebuild-helpers/emake
@@ -24,5 +24,5 @@ fi
${MAKE:-make} ${MAKEOPTS} ${EXTRA_EMAKE} "$@"
ret=$?
-[[ $ret -ne 0 ]] && helpers_die "${0##*/} failed"
+[[ $ret -ne 0 ]] && __helpers_die "${0##*/} failed"
exit $ret
diff --git a/bin/ebuild-helpers/fowners b/bin/ebuild-helpers/fowners
index a213c9eb1..cee4108ce 100755
--- a/bin/ebuild-helpers/fowners
+++ b/bin/ebuild-helpers/fowners
@@ -4,8 +4,9 @@
source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
-[[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) EPREFIX= ED=${D} ;; esac
+if ! ___eapi_has_prefix_variables; then
+ EPREFIX= ED=${D}
+fi
# we can't prefix all arguments because
# chown takes random options
@@ -13,10 +14,5 @@ slash="/"
chown "${@/#${slash}/${ED}${slash}}"
ret=$?
-if [[ ${ret} != 0 && -n ${EPREFIX} && ${EUID} != 0 ]] ; then
- ewarn "fowners failure ignored in Prefix with non-privileged user"
- exit 0
-fi
-
-[[ $ret -ne 0 ]] && helpers_die "${0##*/} failed"
+[[ $ret -ne 0 ]] && __helpers_die "${0##*/} failed"
exit $ret
diff --git a/bin/ebuild-helpers/fperms b/bin/ebuild-helpers/fperms
index a2f77ea00..d854ebbdf 100755
--- a/bin/ebuild-helpers/fperms
+++ b/bin/ebuild-helpers/fperms
@@ -1,16 +1,17 @@
#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
+# Copyright 1999-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
-[[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) ED=${D} ;; esac
+if ! ___eapi_has_prefix_variables; then
+ ED=${D}
+fi
# we can't prefix all arguments because
# chmod takes random options
slash="/"
chmod "${@/#${slash}/${ED}${slash}}"
ret=$?
-[[ $ret -ne 0 ]] && helpers_die "${0##*/} failed"
+[[ $ret -ne 0 ]] && __helpers_die "${0##*/} failed"
exit $ret
diff --git a/bin/ebuild-helpers/keepdir b/bin/ebuild-helpers/keepdir
new file mode 100755
index 000000000..bec2feb77
--- /dev/null
+++ b/bin/ebuild-helpers/keepdir
@@ -0,0 +1,20 @@
+#!/bin/bash
+# Copyright 1999-2013 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+if ! ___eapi_has_prefix_variables; then
+ ED=${D}
+fi
+
+dodir "$@"
+ret=$?
+
+for x in "$@"; do
+ >> "${ED}${x}/.keep_${CATEGORY}_${PN}-${SLOT%/*}" || \
+ { echo "!!! ${0##*/}: cannot write .keep in ${ED}${x}" 1>&2; ret=1; }
+done
+
+[[ ${ret} -ne 0 ]] && __helpers_die "${0##*/} failed"
+exit ${ret}
diff --git a/bin/ebuild-helpers/newbin b/bin/ebuild-helpers/newbin
index bf9874472..59a0db27b 100755..120000
--- a/bin/ebuild-helpers/newbin
+++ b/bin/ebuild-helpers/newbin
@@ -1,22 +1 @@
-#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
-# Distributed under the terms of the GNU General Public License v2
-
-source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
-
-if [[ -z ${T} ]] || [[ -z ${2} ]] ; then
- helpers_die "${0##*/}: Need two arguments, old file and new file"
- exit 1
-fi
-
-if [ ! -e "$1" ] ; then
- helpers_die "!!! ${0##*/}: $1 does not exist"
- exit 1
-fi
-
-(($#>2)) && \
- eqawarn "QA Notice: ${0##*/} called with more than 2 arguments: ${@:3}"
-
-rm -rf "${T}/${2}" && \
-cp -f "${1}" "${T}/${2}" && \
-exec dobin "${T}/${2}"
+newins \ No newline at end of file
diff --git a/bin/ebuild-helpers/newconfd b/bin/ebuild-helpers/newconfd
index fa3710d8f..59a0db27b 100755..120000
--- a/bin/ebuild-helpers/newconfd
+++ b/bin/ebuild-helpers/newconfd
@@ -1,22 +1 @@
-#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
-# Distributed under the terms of the GNU General Public License v2
-
-source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
-
-if [[ -z ${T} ]] || [[ -z ${2} ]] ; then
- helpers_die "${0##*/}: Need two arguments, old file and new file"
- exit 1
-fi
-
-if [ ! -e "$1" ] ; then
- helpers_die "!!! ${0##*/}: $1 does not exist"
- exit 1
-fi
-
-(($#>2)) && \
- eqawarn "QA Notice: ${0##*/} called with more than 2 arguments: ${@:3}"
-
-rm -rf "${T}/${2}" && \
-cp -f "${1}" "${T}/${2}" && \
-exec doconfd "${T}/${2}"
+newins \ No newline at end of file
diff --git a/bin/ebuild-helpers/newdoc b/bin/ebuild-helpers/newdoc
index df6fb1d58..59a0db27b 100755..120000
--- a/bin/ebuild-helpers/newdoc
+++ b/bin/ebuild-helpers/newdoc
@@ -1,22 +1 @@
-#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
-# Distributed under the terms of the GNU General Public License v2
-
-source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
-
-if [[ -z ${T} ]] || [[ -z ${2} ]] ; then
- helpers_die "${0##*/}: Need two arguments, old file and new file"
- exit 1
-fi
-
-if [ ! -e "$1" ] ; then
- helpers_die "!!! ${0##*/}: $1 does not exist"
- exit 1
-fi
-
-(($#>2)) && \
- eqawarn "QA Notice: ${0##*/} called with more than 2 arguments: ${@:3}"
-
-rm -rf "${T}/${2}" && \
-cp -f "${1}" "${T}/${2}" && \
-exec dodoc "${T}/${2}"
+newins \ No newline at end of file
diff --git a/bin/ebuild-helpers/newenvd b/bin/ebuild-helpers/newenvd
index c54af0520..59a0db27b 100755..120000
--- a/bin/ebuild-helpers/newenvd
+++ b/bin/ebuild-helpers/newenvd
@@ -1,22 +1 @@
-#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
-# Distributed under the terms of the GNU General Public License v2
-
-source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
-
-if [[ -z ${T} ]] || [[ -z ${2} ]] ; then
- helpers_die "${0##*/}: Need two arguments, old file and new file"
- exit 1
-fi
-
-if [ ! -e "$1" ] ; then
- helpers_die "!!! ${0##*/}: $1 does not exist"
- exit 1
-fi
-
-(($#>2)) && \
- eqawarn "QA Notice: ${0##*/} called with more than 2 arguments: ${@:3}"
-
-rm -rf "${T}/${2}" && \
-cp -f "${1}" "${T}/${2}" && \
-exec doenvd "${T}/${2}"
+newins \ No newline at end of file
diff --git a/bin/ebuild-helpers/newexe b/bin/ebuild-helpers/newexe
index 9bcf64b31..59a0db27b 100755..120000
--- a/bin/ebuild-helpers/newexe
+++ b/bin/ebuild-helpers/newexe
@@ -1,22 +1 @@
-#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
-# Distributed under the terms of the GNU General Public License v2
-
-source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
-
-if [[ -z ${T} ]] || [[ -z ${2} ]] ; then
- helpers_die "${0##*/}: Need two arguments, old file and new file"
- exit 1
-fi
-
-if [ ! -e "$1" ] ; then
- helpers_die "!!! ${0##*/}: $1 does not exist"
- exit 1
-fi
-
-(($#>2)) && \
- eqawarn "QA Notice: ${0##*/} called with more than 2 arguments: ${@:3}"
-
-rm -rf "${T}/${2}" && \
-cp -f "${1}" "${T}/${2}" && \
-exec doexe "${T}/${2}"
+newins \ No newline at end of file
diff --git a/bin/ebuild-helpers/newheader b/bin/ebuild-helpers/newheader
new file mode 120000
index 000000000..59a0db27b
--- /dev/null
+++ b/bin/ebuild-helpers/newheader
@@ -0,0 +1 @@
+newins \ No newline at end of file
diff --git a/bin/ebuild-helpers/newinitd b/bin/ebuild-helpers/newinitd
index 03bbe68a7..59a0db27b 100755..120000
--- a/bin/ebuild-helpers/newinitd
+++ b/bin/ebuild-helpers/newinitd
@@ -1,22 +1 @@
-#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
-# Distributed under the terms of the GNU General Public License v2
-
-source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
-
-if [[ -z ${T} ]] || [[ -z ${2} ]] ; then
- helpers_die "${0##*/}: Need two arguments, old file and new file"
- exit 1
-fi
-
-if [ ! -e "$1" ] ; then
- helpers_die "!!! ${0##*/}: $1 does not exist"
- exit 1
-fi
-
-(($#>2)) && \
- eqawarn "QA Notice: ${0##*/} called with more than 2 arguments: ${@:3}"
-
-rm -rf "${T}/${2}" && \
-cp -f "${1}" "${T}/${2}" && \
-exec doinitd "${T}/${2}"
+newins \ No newline at end of file
diff --git a/bin/ebuild-helpers/newins b/bin/ebuild-helpers/newins
index adf2d809e..03359851a 100755
--- a/bin/ebuild-helpers/newins
+++ b/bin/ebuild-helpers/newins
@@ -1,38 +1,57 @@
#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
+# Copyright 1999-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+helper=${0##*/}
+
if [[ -z ${T} ]] || [[ -z ${2} ]] ; then
- helpers_die "${0##*/}: Need two arguments, old file and new file"
+ __helpers_die "${helper}: Need two arguments, old file and new file"
exit 1
fi
-if [ ! -e "$1" ] ; then
- helpers_die "!!! ${0##*/}: $1 does not exist"
- exit 1
+(($#>2)) && \
+ eqawarn "QA Notice: ${helper} called with more than 2 arguments: ${@:3}"
+
+stdin=
+if ___eapi_newins_supports_reading_from_standard_input && [[ $1 == "-" ]]; then
+ stdin=yes
fi
-(($#>2)) && \
- eqawarn "QA Notice: ${0##*/} called with more than 2 arguments: ${@:3}"
-
-rm -rf "${T}/${2}" || exit $?
-case "$EAPI" in
- 0|1|2|3|3_pre2)
- cp "$1" "$T/$2" || exit $?
- ;;
- *)
- cp -P "$1" "$T/$2"
- ret=$?
- if [[ $ret -ne 0 ]] ; then
- helpers_die "${0##*/} failed"
- exit $ret
+TMP=$(mktemp -d "${T}/.newins_tmp_XXXXXX")
+trap 'rm -rf "${TMP}"' EXIT
+
+if [[ ${stdin} ]] ; then
+ if [[ -t 0 ]] ; then
+ __helpers_die "!!! ${helper}: Input is from a terminal"
+ exit 1
+ fi
+ cat > "${TMP}/$2"
+ ret=$?
+else
+ if [[ ! -e $1 ]] ; then
+ __helpers_die "!!! ${helper}: $1 does not exist"
+ exit 1
+ fi
+
+ cp_args="-f"
+ if [[ ${helper} == newins ]] ; then
+ if ___eapi_doins_and_newins_preserve_symlinks; then
+ cp_args+=" -P"
fi
- ;;
-esac
-doins "${T}/${2}"
+ fi
+
+ cp ${cp_args} "$1" "${TMP}/$2"
+ ret=$?
+fi
+
+if [[ ${ret} -ne 0 ]] ; then
+ __helpers_die "${0##*/} failed"
+ exit ${ret}
+fi
+
+do${helper#new} "${TMP}/$2"
ret=$?
-rm -rf "${T}/${2}"
-[[ $ret -ne 0 ]] && helpers_die "${0##*/} failed"
+[[ $ret -ne 0 ]] && __helpers_die "${helper} failed"
exit $ret
diff --git a/bin/ebuild-helpers/newlib.a b/bin/ebuild-helpers/newlib.a
index 7ff819547..59a0db27b 100755..120000
--- a/bin/ebuild-helpers/newlib.a
+++ b/bin/ebuild-helpers/newlib.a
@@ -1,22 +1 @@
-#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
-# Distributed under the terms of the GNU General Public License v2
-
-source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
-
-if [[ -z ${T} ]] || [[ -z ${2} ]] ; then
- helpers_die "${0##*/}: Need two arguments, old file and new file"
- exit 1
-fi
-
-if [ ! -e "$1" ] ; then
- helpers_die "!!! ${0##*/}: $1 does not exist"
- exit 1
-fi
-
-(($#>2)) && \
- eqawarn "QA Notice: ${0##*/} called with more than 2 arguments: ${@:3}"
-
-rm -rf "${T}/${2}" && \
-cp -f "${1}" "${T}/${2}" && \
-exec dolib.a "${T}/${2}"
+newins \ No newline at end of file
diff --git a/bin/ebuild-helpers/newlib.so b/bin/ebuild-helpers/newlib.so
index fd4c097d7..59a0db27b 100755..120000
--- a/bin/ebuild-helpers/newlib.so
+++ b/bin/ebuild-helpers/newlib.so
@@ -1,22 +1 @@
-#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
-# Distributed under the terms of the GNU General Public License v2
-
-source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
-
-if [[ -z ${T} ]] || [[ -z ${2} ]] ; then
- helpers_die "${0##*/}: Need two arguments, old file and new file"
- exit 1
-fi
-
-if [ ! -e "$1" ] ; then
- helpers_die "!!! ${0##*/}: $1 does not exist"
- exit 1
-fi
-
-(($#>2)) && \
- eqawarn "QA Notice: ${0##*/} called with more than 2 arguments: ${@:3}"
-
-rm -rf "${T}/${2}" && \
-cp -f "${1}" "${T}/${2}" && \
-exec dolib.so "${T}/${2}"
+newins \ No newline at end of file
diff --git a/bin/ebuild-helpers/newman b/bin/ebuild-helpers/newman
index 889e0f985..59a0db27b 100755..120000
--- a/bin/ebuild-helpers/newman
+++ b/bin/ebuild-helpers/newman
@@ -1,22 +1 @@
-#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
-# Distributed under the terms of the GNU General Public License v2
-
-source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
-
-if [[ -z ${T} ]] || [[ -z ${2} ]] ; then
- helpers_die "${0##*/}: Need two arguments, old file and new file"
- exit 1
-fi
-
-if [ ! -e "$1" ] ; then
- helpers_die "!!! ${0##*/}: $1 does not exist"
- exit 1
-fi
-
-(($#>2)) && \
- eqawarn "QA Notice: ${0##*/} called with more than 2 arguments: ${@:3}"
-
-rm -rf "${T}/${2}" && \
-cp -f "${1}" "${T}/${2}" && \
-exec doman "${T}/${2}"
+newins \ No newline at end of file
diff --git a/bin/ebuild-helpers/newsbin b/bin/ebuild-helpers/newsbin
index 9df0af275..59a0db27b 100755..120000
--- a/bin/ebuild-helpers/newsbin
+++ b/bin/ebuild-helpers/newsbin
@@ -1,22 +1 @@
-#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
-# Distributed under the terms of the GNU General Public License v2
-
-source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
-
-if [[ -z ${T} ]] || [[ -z ${2} ]] ; then
- helpers_die "${0##*/}: Need two arguments, old file and new file"
- exit 1
-fi
-
-if [ ! -e "$1" ] ; then
- helpers_die "!!! ${0##*/}: $1 does not exist"
- exit 1
-fi
-
-(($#>2)) && \
- eqawarn "QA Notice: ${0##*/} called with more than 2 arguments: ${@:3}"
-
-rm -rf "${T}/${2}" && \
-cp -f "${1}" "${T}/${2}" && \
-exec dosbin "${T}/${2}"
+newins \ No newline at end of file
diff --git a/bin/ebuild-helpers/portageq b/bin/ebuild-helpers/portageq
index ec30b66cb..b67b03f33 100755
--- a/bin/ebuild-helpers/portageq
+++ b/bin/ebuild-helpers/portageq
@@ -1,8 +1,10 @@
#!/bin/bash
-# Copyright 2009-2010 Gentoo Foundation
+# Copyright 2009-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
PORTAGE_BIN_PATH=${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}
PORTAGE_PYM_PATH=${PORTAGE_PYM_PATH:-/usr/lib/portage/pym}
-PYTHONPATH=$PORTAGE_PYM_PATH${PYTHONPATH:+:}$PYTHONPATH \
+# Use safe cwd, avoiding unsafe import for bug #469338.
+cd "${PORTAGE_PYM_PATH}"
+PYTHONPATH=${PORTAGE_PYTHONPATH:-${PORTAGE_PYM_PATH}} \
exec "${PORTAGE_PYTHON:-/usr/bin/python}" "$PORTAGE_BIN_PATH/portageq" "$@"
diff --git a/bin/ebuild-helpers/prepall b/bin/ebuild-helpers/prepall
index 49e646cd2..fb5c2db55 100755
--- a/bin/ebuild-helpers/prepall
+++ b/bin/ebuild-helpers/prepall
@@ -1,11 +1,12 @@
#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
+# Copyright 1999-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
-[[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) ED=${D} ;; esac
+if ! ___eapi_has_prefix_variables; then
+ ED=${D}
+fi
if has chflags $FEATURES ; then
# Save all the file flags for restoration at the end of prepall.
diff --git a/bin/ebuild-helpers/prepalldocs b/bin/ebuild-helpers/prepalldocs
index 560a02bcb..3094661f5 100755
--- a/bin/ebuild-helpers/prepalldocs
+++ b/bin/ebuild-helpers/prepalldocs
@@ -1,15 +1,21 @@
#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
+# Copyright 1999-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+if ___eapi_has_docompress; then
+ die "'${0##*/}' has been banned for EAPI '$EAPI'"
+ exit 1
+fi
+
if [[ -n $1 ]] ; then
- vecho "${0##*/}: invalid usage; takes no arguments" 1>&2
+ __vecho "${0##*/}: invalid usage; takes no arguments" 1>&2
fi
-[[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) ED=${D} ;; esac
+if ! ___eapi_has_prefix_variables; then
+ ED=${D}
+fi
[[ -d ${ED}usr/share/doc ]] || exit 0
diff --git a/bin/ebuild-helpers/prepallinfo b/bin/ebuild-helpers/prepallinfo
index db9bbfacb..1a2027580 100755
--- a/bin/ebuild-helpers/prepallinfo
+++ b/bin/ebuild-helpers/prepallinfo
@@ -1,11 +1,12 @@
#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
+# Copyright 1999-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
-[[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) ED=${D} ;; esac
+if ! ___eapi_has_prefix_variables; then
+ ED=${D}
+fi
[[ -d ${ED}usr/share/info ]] || exit 0
diff --git a/bin/ebuild-helpers/prepallman b/bin/ebuild-helpers/prepallman
index dee1c7236..5331eaf01 100755
--- a/bin/ebuild-helpers/prepallman
+++ b/bin/ebuild-helpers/prepallman
@@ -1,22 +1,22 @@
#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
+# Copyright 1999-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
# replaced by controllable compression in EAPI 4
-has "${EAPI}" 0 1 2 3 || exit 0
+___eapi_has_docompress && exit 0
-[[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) ED=${D} ;; esac
+if ! ___eapi_has_prefix_variables; then
+ ED=${D}
+fi
ret=0
-find "${ED}" -type d -name man > "${T}"/prepallman.filelist
-while read -r mandir ; do
+while IFS= read -r -d '' mandir ; do
mandir=${mandir#${ED}}
prepman "${mandir%/man}"
((ret|=$?))
-done < "${T}"/prepallman.filelist
+done < <(find "${ED}" -type d -name man -print0)
exit ${ret}
diff --git a/bin/ebuild-helpers/prepallstrip b/bin/ebuild-helpers/prepallstrip
index 28320d975..1aa6686cd 100755
--- a/bin/ebuild-helpers/prepallstrip
+++ b/bin/ebuild-helpers/prepallstrip
@@ -1,8 +1,11 @@
#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
+# Copyright 1999-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-[[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) ED=${D} ;; esac
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+if ! ___eapi_has_prefix_variables; then
+ ED=${D}
+fi
exec prepstrip "${ED}"
diff --git a/bin/ebuild-helpers/prepinfo b/bin/ebuild-helpers/prepinfo
index ffe2ecec3..5afc18a71 100755
--- a/bin/ebuild-helpers/prepinfo
+++ b/bin/ebuild-helpers/prepinfo
@@ -1,11 +1,12 @@
#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
+# Copyright 1999-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
-[[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) ED=${D} ;; esac
+if ! ___eapi_has_prefix_variables; then
+ ED=${D}
+fi
if [[ -z $1 ]] ; then
infodir="/usr/share/info"
@@ -19,7 +20,7 @@ fi
if [[ ! -d ${ED}${infodir} ]] ; then
if [[ -n $1 ]] ; then
- vecho "${0##*/}: '${infodir}' does not exist!"
+ __vecho "${0##*/}: '${infodir}' does not exist!"
exit 1
else
exit 0
@@ -33,5 +34,5 @@ find "${ED}${infodir}" -type d -print0 | while read -r -d $'\0' x ; do
rm -f "${x}"/dir{,.info}{,.gz,.bz2}
done
-has "${EAPI}" 0 1 2 3 || exit 0
+___eapi_has_docompress && exit 0
exec ecompressdir --queue "${infodir}"
diff --git a/bin/ebuild-helpers/preplib b/bin/ebuild-helpers/preplib
deleted file mode 100755
index 6e91cf33d..000000000
--- a/bin/ebuild-helpers/preplib
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
-# Distributed under the terms of the GNU General Public License v2
-
-source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
-
-eqawarn "QA Notice: Deprecated call to 'preplib'"
-
-[[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) ED=${D} ;; esac
-
-LIBDIR_VAR="LIBDIR_${ABI}"
-if [ -n "${ABI}" -a -n "${!LIBDIR_VAR}" ]; then
- CONF_LIBDIR="${!LIBDIR_VAR}"
-fi
-unset LIBDIR_VAR
-
-if [ -z "${CONF_LIBDIR}" ]; then
- # we need this to default to lib so that things dont break
- CONF_LIBDIR="lib"
-fi
-
-if [ -z "$1" ] ; then
- z="${ED}usr/${CONF_LIBDIR}"
-else
- z="${ED}$1/${CONF_LIBDIR}"
-fi
-
-if [ -d "${z}" ] ; then
- ldconfig -n -N "${z}"
-fi
diff --git a/bin/ebuild-helpers/prepman b/bin/ebuild-helpers/prepman
index f96b64147..fb5dcb4a5 100755
--- a/bin/ebuild-helpers/prepman
+++ b/bin/ebuild-helpers/prepman
@@ -1,13 +1,17 @@
#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
+# Copyright 1999-2012 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
+# Do not compress man pages which are smaller than this (in bytes). #169260
+SIZE_LIMIT='128'
+
source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
-[[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) ED=${D} ;; esac
+if ! ___eapi_has_prefix_variables; then
+ ED=${D}
+fi
-if [[ -z $1 ]] ; then
+if [[ -z $1 ]] ; then
mandir="${ED}usr/share/man"
else
mandir="${ED}$1/man"
@@ -19,7 +23,7 @@ if [[ ! -d ${mandir} ]] ; then
fi
# replaced by controllable compression in EAPI 4
-has "${EAPI}" 0 1 2 3 || exit 0
+___eapi_has_docompress && exit 0
shopt -s nullglob
@@ -30,6 +34,6 @@ for subdir in "${mandir}"/man* "${mandir}"/*/man* ; do
[[ -d ${subdir} ]] && really_is_mandir=1 && break
done
-[[ ${really_is_mandir} == 1 ]] && exec ecompressdir --queue "${mandir#${ED}}"
+[[ ${really_is_mandir} == 1 ]] && exec ecompressdir --limit ${SIZE_LIMIT} --queue "${mandir#${ED}}"
exit 0
diff --git a/bin/ebuild-helpers/prepstrip b/bin/ebuild-helpers/prepstrip
index fe5c1bc32..2ef8a1ace 100755
--- a/bin/ebuild-helpers/prepstrip
+++ b/bin/ebuild-helpers/prepstrip
@@ -1,7 +1,8 @@
#!/bin/bash
-# Copyright 1999-2012 Gentoo Foundation
+# Copyright 1999-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
+PORTAGE_PYM_PATH=${PORTAGE_PYM_PATH:-/usr/lib/portage/pym}
source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/helper-functions.sh
# avoid multiple calls to `has`. this creates things like:
@@ -15,11 +16,12 @@ exp_tf() {
eval ${var}_${flag}=$(tf has ${flag} ${!var})
done
}
-exp_tf FEATURES compressdebug installsources nostrip splitdebug
-exp_tf RESTRICT binchecks installsources strip
+exp_tf FEATURES compressdebug installsources nostrip splitdebug xattr
+exp_tf RESTRICT binchecks installsources splitdebug strip
-[[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "${EAPI}" in 0|1|2) EPREFIX= ED=${D} ;; esac
+if ! ___eapi_has_prefix_variables; then
+ EPREFIX= ED=${D}
+fi
banner=false
SKIP_STRIP=false
@@ -29,6 +31,30 @@ if ${RESTRICT_strip} || ${FEATURES_nostrip} ; then
${FEATURES_installsources} || exit 0
fi
+PRESERVE_XATTR=false
+if [[ ${KERNEL} == linux ]] && ${FEATURES_xattr} ; then
+ PRESERVE_XATTR=true
+ if type -P getfattr >/dev/null && type -P setfattr >/dev/null ; then
+ dump_xattrs() {
+ getfattr -d --absolute-names "$1"
+ }
+ restore_xattrs() {
+ setfattr --restore=-
+ }
+ else
+ dump_xattrs() {
+ PYTHONPATH=${PORTAGE_PYTHONPATH:-${PORTAGE_PYM_PATH}} \
+ "${PORTAGE_PYTHON:-/usr/bin/python}" \
+ "${PORTAGE_BIN_PATH}/xattr-helper.py" --dump < <(echo -n "$1")
+ }
+ restore_xattrs() {
+ PYTHONPATH=${PORTAGE_PYTHONPATH:-${PORTAGE_PYM_PATH}} \
+ "${PORTAGE_PYTHON:-/usr/bin/python}" \
+ "${PORTAGE_BIN_PATH}/xattr-helper.py" --restore
+ }
+ fi
+fi
+
# look up the tools we might be using
for t in STRIP:strip OBJCOPY:objcopy READELF:readelf ; do
v=${t%:*} # STRIP
@@ -51,7 +77,7 @@ case $(${STRIP} --version 2>/dev/null) in
# We'll leave out -R .note for now until we can check out the relevance
# of the section when it has the ALLOC flag set on it ...
SAFE_STRIP_FLAGS="--strip-unneeded"
- DEF_STRIP_FLAGS="-R .comment -R .GCC.command.line"
+ DEF_STRIP_FLAGS="-R .comment -R .GCC.command.line -R .note.gnu.gold-version"
SPLIT_STRIP_FLAGS=
;;
esac
@@ -62,23 +88,13 @@ prepstrip_sources_dir=${EPREFIX}/usr/src/debug/${CATEGORY}/${PF}
type -P debugedit >/dev/null && debugedit_found=true || debugedit_found=false
debugedit_warned=false
-multijob_init
+__multijob_init
# Setup $T filesystem layout that we care about.
tmpdir="${T}/prepstrip"
rm -rf "${tmpdir}"
mkdir -p "${tmpdir}"/{inodes,splitdebug,sources}
-# Usage: inode_var_name: <file>
-inode_file_link() {
- echo -n "${tmpdir}/inodes/"
- if [[ ${USERLAND} == "BSD" ]] ; then
- stat -f '%i' "$1"
- else
- stat -c '%i' "$1"
- fi
-}
-
# Usage: save_elf_sources <elf>
save_elf_sources() {
${FEATURES_installsources} || return 0
@@ -93,7 +109,6 @@ save_elf_sources() {
fi
local x=$1
- [[ -f $(inode_file_link "${x}") ]] && return 0
# since we're editing the ELF here, we should recompute the build-id
# (the -i flag below). save that output so we don't need to recompute
@@ -101,20 +116,22 @@ save_elf_sources() {
buildid=$(debugedit -i \
-b "${WORKDIR}" \
-d "${prepstrip_sources_dir}" \
- -l "${tmpdir}/sources/${x##*/}.${BASHPID}" \
+ -l "${tmpdir}/sources/${x##*/}.${BASHPID:-$(__bashpid)}" \
"${x}")
}
# Usage: save_elf_debug <elf> [splitdebug file]
save_elf_debug() {
${FEATURES_splitdebug} || return 0
+ ${RESTRICT_splitdebug} && return 0
# NOTE: Debug files must be installed in
# ${EPREFIX}/usr/lib/debug/${EPREFIX} (note that ${EPREFIX} occurs
# twice in this path) in order for gdb's debug-file-directory
# lookup to work correctly.
local x=$1
- local splitdebug=$2
+ local inode_debug=$2
+ local splitdebug=$3
local y=${ED}usr/lib/debug/${x:${#D}}.debug
# dont save debug info twice
@@ -122,9 +139,8 @@ save_elf_debug() {
mkdir -p "${y%/*}"
- local inode=$(inode_file_link "${x}")
- if [[ -f ${inode} ]] ; then
- ln "${inode}" "${y}"
+ if [ -f "${inode_debug}" ] ; then
+ ln "${inode_debug}" "${y}" || die "ln failed unexpectedly"
else
if [[ -n ${splitdebug} ]] ; then
mv "${splitdebug}" "${y}"
@@ -134,64 +150,89 @@ save_elf_debug() {
${OBJCOPY} ${objcopy_flags} "${x}" "${y}"
${OBJCOPY} --add-gnu-debuglink="${y}" "${x}"
fi
- local args="a-x,o-w"
- [[ -g ${x} || -u ${x} ]] && args+=",go-r"
- chmod ${args} "${y}"
- ln "${y}" "${inode}"
+ # Only do the following if the debug file was
+ # successfully created (see bug #446774).
+ if [ $? -eq 0 ] ; then
+ local args="a-x,o-w"
+ [[ -g ${x} || -u ${x} ]] && args+=",go-r"
+ chmod ${args} "${y}"
+ ln "${y}" "${inode_debug}" || die "ln failed unexpectedly"
+ fi
fi
# if we don't already have build-id from debugedit, look it up
if [[ -z ${buildid} ]] ; then
# convert the readelf output to something useful
- buildid=$(${READELF} -x .note.gnu.build-id "${x}" 2>/dev/null \
- | awk '$NF ~ /GNU/ { getline; printf $2$3$4$5; getline; print $2 }')
+ buildid=$(${READELF} -n "${x}" 2>/dev/null | awk '/Build ID:/{ print $NF; exit }')
fi
if [[ -n ${buildid} ]] ; then
local buildid_dir="${ED}usr/lib/debug/.build-id/${buildid:0:2}"
local buildid_file="${buildid_dir}/${buildid:2}"
mkdir -p "${buildid_dir}"
- ln -s "../../${x:${#D}}.debug" "${buildid_file}.debug"
- ln -s "/${x:${#D}}" "${buildid_file}"
+ [ -L "${buildid_file}".debug ] || ln -s "../../${x:${#D}}.debug" "${buildid_file}.debug"
+ [ -L "${buildid_file}" ] || ln -s "/${x:${#D}}" "${buildid_file}"
fi
}
# Usage: process_elf <elf>
process_elf() {
- local x=$1 strip_flags=${*:2}
-
- vecho " ${x:${#ED}}"
- save_elf_sources "${x}"
+ local x=$1 inode_link=$2 strip_flags=${*:3}
+ local already_stripped lockfile xt_data
+
+ __vecho " ${x:${#ED}}"
+
+ # If two processes try to debugedit or strip the same hardlink at the
+ # same time, it may corrupt files or cause loss of splitdebug info.
+ # So, use a lockfile to prevent interference (easily observed with
+ # dev-vcs/git which creates ~111 hardlinks to one file in
+ # /usr/libexec/git-core).
+ lockfile=${inode_link}_lockfile
+ if ! ln "${inode_link}" "${lockfile}" 2>/dev/null ; then
+ while [[ -f ${lockfile} ]] ; do
+ sleep 1
+ done
+ unset lockfile
+ fi
- if ${strip_this} ; then
+ [ -f "${inode_link}_stripped" ] && already_stripped=true || already_stripped=false
- # If two processes try to strip the same hardlink at the same
- # time, it will cause one of them to lose the splitdebug info.
- # So, use a lockfile to prevent interference (easily observed
- # with dev-vcs/git which creates ~109 hardlinks to one file in
- # /usr/libexec/git-core).
- local lockfile=$(inode_file_link "${x}")_lockfile
- if ! ln "${x}" "${lockfile}" ; then
- while [[ -f ${lockfile} ]] ; do
- sleep 1
- done
- unset lockfile
+ if ! ${already_stripped} ; then
+ if ${PRESERVE_XATTR} ; then
+ xt_data=$(dump_xattrs "${x}")
fi
+ save_elf_sources "${x}"
+ fi
+
+ if ${strip_this} ; then
# see if we can split & strip at the same time
if [[ -n ${SPLIT_STRIP_FLAGS} ]] ; then
local shortname="${x##*/}.debug"
- local splitdebug="${tmpdir}/splitdebug/${shortname}.${BASHPID}"
+ local splitdebug="${tmpdir}/splitdebug/${shortname}.${BASHPID:-$(__bashpid)}"
+ ${already_stripped} || \
${STRIP} ${strip_flags} \
-f "${splitdebug}" \
-F "${shortname}" \
"${x}"
- save_elf_debug "${x}" "${splitdebug}"
+ save_elf_debug "${x}" "${inode_link}_debug" "${splitdebug}"
else
- save_elf_debug "${x}"
+ save_elf_debug "${x}" "${inode_link}_debug"
+ ${already_stripped} || \
${STRIP} ${strip_flags} "${x}"
fi
- [[ -n ${lockfile} ]] && rm -f "${lockfile}"
fi
+
+ if ${already_stripped} ; then
+ rm -f "${x}" || die "rm failed unexpectedly"
+ ln "${inode_link}_stripped" "${x}" || die "ln failed unexpectedly"
+ else
+ ln "${x}" "${inode_link}_stripped" || die "ln failed unexpectedly"
+ if [[ ${xt_data} ]] ; then
+ restore_xattrs <<< "${xt_data}"
+ fi
+ fi
+
+ [[ -n ${lockfile} ]] && rm -f "${lockfile}"
}
# The existance of the section .symtab tells us that a binary is stripped.
@@ -204,7 +245,7 @@ if ! ${RESTRICT_binchecks} && ! ${RESTRICT_strip} ; then
log=${tmpdir}/scanelf-already-stripped.log
scanelf -yqRBF '#k%F' -k '!.symtab' "$@" | sed -e "s#^${ED}##" > "${log}"
(
- multijob_child_init
+ __multijob_child_init
qa_var="QA_PRESTRIPPED_${ARCH/-/_}"
[[ -n ${!qa_var} ]] && QA_PRESTRIPPED="${!qa_var}"
if [[ -n ${QA_PRESTRIPPED} && -s ${log} && \
@@ -219,28 +260,49 @@ if ! ${RESTRICT_binchecks} && ! ${RESTRICT_strip} ; then
fi
sed -e "/^\$/d" -e "s#^#/#" -i "${log}"
if [[ -s ${log} ]] ; then
- vecho -e "\n"
+ __vecho -e "\n"
eqawarn "QA Notice: Pre-stripped files found:"
eqawarn "$(<"${log}")"
else
rm -f "${log}"
fi
) &
- multijob_post_fork
+ __multijob_post_fork
+fi
+
+# Since strip creates a new inode, we need to know the initial set of
+# inodes in advance, so that we can avoid interference due to trying
+# to strip the same (hardlinked) file multiple times in parallel.
+# See bug #421099.
+if [[ ${USERLAND} == BSD ]] ; then
+ get_inode_number() { stat -f '%i' "$1"; }
+else
+ get_inode_number() { stat -c '%i' "$1"; }
fi
+cd "${tmpdir}/inodes" || die "cd failed unexpectedly"
+while read -r x ; do
+ inode_link=$(get_inode_number "${x}") || die "stat failed unexpectedly"
+ echo "${x}" >> "${inode_link}" || die "echo failed unexpectedly"
+done < <(
+ # Use sort -u to eliminate duplicates for bug #445336.
+ (
+ scanelf -yqRBF '#k%F' -k '.symtab' "$@"
+ find "$@" -type f ! -type l -name '*.a'
+ ) | LC_ALL=C sort -u
+)
# Now we look for unstripped binaries.
-for x in \
- $(scanelf -yqRBF '#k%F' -k '.symtab' "$@") \
- $(find "$@" -type f -name '*.a')
+for inode_link in $(shopt -s nullglob; echo *) ; do
+while read -r x
do
+
if ! ${banner} ; then
- vecho "strip: ${STRIP} ${PORTAGE_STRIP_FLAGS}"
+ __vecho "strip: ${STRIP} ${PORTAGE_STRIP_FLAGS}"
banner=true
fi
(
- multijob_child_init
+ __multijob_child_init
f=$(file "${x}") || exit 0
[[ -z ${f} ]] && exit 0
@@ -275,27 +337,34 @@ do
buildid=
if [[ ${f} == *"current ar archive"* ]] ; then
- vecho " ${x:${#ED}}"
+ __vecho " ${x:${#ED}}"
if ${strip_this} ; then
- # hmm, can we split debug/sources for .a ?
- ${STRIP} -g "${x}"
+ # If we have split debug enabled, then do not strip this.
+ # There is no concept of splitdebug for objects not yet
+ # linked in (only for finally linked ELFs), so we have to
+ # retain the debug info in the archive itself.
+ if ! ${FEATURES_splitdebug} || ${RESTRICT_splitdebug} ; then
+ ${STRIP} -g "${x}"
+ fi
fi
elif [[ ${f} == *"SB executable"* || ${f} == *"SB shared object"* ]] ; then
- process_elf "${x}" ${PORTAGE_STRIP_FLAGS}
+ process_elf "${x}" "${inode_link}" ${PORTAGE_STRIP_FLAGS}
elif [[ ${f} == *"SB relocatable"* ]] ; then
- process_elf "${x}" ${SAFE_STRIP_FLAGS}
+ process_elf "${x}" "${inode_link}" ${SAFE_STRIP_FLAGS}
fi
if ${was_not_writable} ; then
chmod u-w "${x}"
fi
) &
- multijob_post_fork
+ __multijob_post_fork
+
+done < "${inode_link}"
done
# With a bit more work, we could run the rsync processes below in
# parallel, but not sure that'd be an overall improvement.
-multijob_finish
+__multijob_finish
cd "${tmpdir}"/sources/ && cat * > "${tmpdir}/debug.sources" 2>/dev/null
if [[ -s ${tmpdir}/debug.sources ]] && \
@@ -303,11 +372,11 @@ if [[ -s ${tmpdir}/debug.sources ]] && \
! ${RESTRICT_installsources} && \
${debugedit_found}
then
- vecho "installsources: rsyncing source files"
+ __vecho "installsources: rsyncing source files"
[[ -d ${D}${prepstrip_sources_dir} ]] || mkdir -p "${D}${prepstrip_sources_dir}"
grep -zv '/<[^/>]*>$' "${tmpdir}"/debug.sources | \
(cd "${WORKDIR}"; LANG=C sort -z -u | \
- rsync -tL0 --files-from=- "${WORKDIR}/" "${D}${prepstrip_sources_dir}/" )
+ rsync -tL0 --chmod=ugo-st,a+r,go-w,Da+x,Fa-x --files-from=- "${WORKDIR}/" "${D}${prepstrip_sources_dir}/" )
# Preserve directory structure.
# Needed after running save_elf_sources.
diff --git a/bin/ebuild-helpers/unprivileged/chgrp b/bin/ebuild-helpers/unprivileged/chgrp
new file mode 120000
index 000000000..6fb0fcd80
--- /dev/null
+++ b/bin/ebuild-helpers/unprivileged/chgrp
@@ -0,0 +1 @@
+chown \ No newline at end of file
diff --git a/bin/ebuild-helpers/unprivileged/chown b/bin/ebuild-helpers/unprivileged/chown
new file mode 100755
index 000000000..08fa650c5
--- /dev/null
+++ b/bin/ebuild-helpers/unprivileged/chown
@@ -0,0 +1,41 @@
+#!/bin/bash
+# Copyright 2012-2013 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+scriptpath=${BASH_SOURCE[0]}
+scriptname=${scriptpath##*/}
+
+IFS=':'
+
+for path in ${PATH}; do
+ [[ -x ${path}/${scriptname} ]] || continue
+ [[ ${path}/${scriptname} -ef ${scriptpath} ]] && continue
+ IFS=$' \t\n'
+ output=$("${path}/${scriptname}" "$@" 2>&1)
+ if [[ $? -ne 0 ]] ; then
+
+ # Avoid an extreme performance problem when the
+ # output is very long (bug #470992).
+ if [[ $(wc -l <<< "${output}") -gt 100 ]]; then
+ output=$(head -n100 <<< "${output}")
+ output="${output}\n ... (further messages truncated)"
+ fi
+
+ source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
+
+ if ! ___eapi_has_prefix_variables; then
+ EPREFIX=
+ fi
+ msg="${scriptname} failure ignored with unprivileged user:\n ${scriptname} $*\n ${output}"
+ # Reverse expansion of ${D} and ${EPREFIX}, for readability.
+ msg=${msg//${D}/'${D}'}
+ if [[ -n ${EPREFIX} ]] ; then
+ msg=${msg//${EPREFIX}/'${EPREFIX}'}
+ msg=${msg//${EPREFIX#/}/'${EPREFIX}'}
+ fi
+ ewarn "${msg}"
+ fi
+ exit 0
+done
+
+exit 1
diff --git a/bin/ebuild-helpers/xattr/install b/bin/ebuild-helpers/xattr/install
new file mode 100755
index 000000000..f51f621bc
--- /dev/null
+++ b/bin/ebuild-helpers/xattr/install
@@ -0,0 +1,12 @@
+#!/bin/bash
+# Copyright 2013 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+PORTAGE_BIN_PATH=${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}
+PORTAGE_PYM_PATH=${PORTAGE_PYM_PATH:-/usr/lib/portage/pym}
+# Use safe cwd, avoiding unsafe import for bug #469338.
+export __PORTAGE_HELPER_CWD=${PWD}
+cd "${PORTAGE_PYM_PATH}"
+export __PORTAGE_HELPER_PATH=${BASH_SOURCE[0]}
+PYTHONPATH=${PORTAGE_PYTHONPATH:-${PORTAGE_PYM_PATH}} \
+ exec "${PORTAGE_PYTHON:-/usr/bin/python}" "${PORTAGE_BIN_PATH}/install.py" "$@"
diff --git a/bin/ebuild-ipc b/bin/ebuild-ipc
index 43e4a02ae..820005fbb 100755
--- a/bin/ebuild-ipc
+++ b/bin/ebuild-ipc
@@ -1,8 +1,10 @@
#!/bin/bash
-# Copyright 2010 Gentoo Foundation
+# Copyright 2010-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
PORTAGE_BIN_PATH=${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}
PORTAGE_PYM_PATH=${PORTAGE_PYM_PATH:-/usr/lib/portage/pym}
-PYTHONPATH=$PORTAGE_PYM_PATH${PYTHONPATH:+:}$PYTHONPATH \
+# Use safe cwd, avoiding unsafe import for bug #469338.
+cd "${PORTAGE_PYM_PATH}"
+PYTHONPATH=${PORTAGE_PYTHONPATH:-${PORTAGE_PYM_PATH}} \
exec "${PORTAGE_PYTHON:-/usr/bin/python}" "$PORTAGE_BIN_PATH/ebuild-ipc.py" "$@"
diff --git a/bin/ebuild-ipc.py b/bin/ebuild-ipc.py
index 3caf2d185..00337ee22 100755
--- a/bin/ebuild-ipc.py
+++ b/bin/ebuild-ipc.py
@@ -1,20 +1,17 @@
-#!/usr/bin/python
-# Copyright 2010-2012 Gentoo Foundation
+#!/usr/bin/python -b
+# Copyright 2010-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
#
# This is a helper which ebuild processes can use
# to communicate with portage's main python process.
-import errno
import logging
import os
import pickle
import platform
-import select
import signal
import sys
import time
-import traceback
def debug_signal(signum, frame):
import pdb
@@ -38,14 +35,28 @@ if os.environ.get("SANDBOX_ON") == "1":
":".join(filter(None, sandbox_write))
import portage
+portage._internal_caller = True
portage._disable_legacy_globals()
+from portage.util._async.ForkProcess import ForkProcess
+from portage.util._eventloop.global_event_loop import global_event_loop
+from _emerge.PipeReader import PipeReader
+
+class FifoWriter(ForkProcess):
+
+ __slots__ = ('buf', 'fifo',)
+
+ def _run(self):
+ # Atomically write the whole buffer into the fifo.
+ with open(self.fifo, 'wb', 0) as f:
+ f.write(self.buf)
+ return os.EX_OK
+
class EbuildIpc(object):
# Timeout for each individual communication attempt (we retry
# as long as the daemon process appears to be alive).
- _COMMUNICATE_RETRY_TIMEOUT_SECONDS = 15
- _BUFSIZE = 4096
+ _COMMUNICATE_RETRY_TIMEOUT_MS = 15000
def __init__(self):
self.fifo_dir = os.environ['PORTAGE_BUILDDIR']
@@ -89,7 +100,7 @@ class EbuildIpc(object):
'ebuild-ipc: daemon process not detected\n'),
level=logging.ERROR, noiselevel=-1)
- def _wait(self, pid, pr, msg):
+ def _run_writer(self, fifo_writer, msg):
"""
Wait on pid and return an appropriate exit code. This
may return unsuccessfully due to timeout if the daemon
@@ -98,88 +109,48 @@ class EbuildIpc(object):
start_time = time.time()
- while True:
- try:
- events = select.select([pr], [], [],
- self._COMMUNICATE_RETRY_TIMEOUT_SECONDS)
- except select.error as e:
- portage.util.writemsg_level(
- "ebuild-ipc: %s: %s\n" % \
- (portage.localization._('during select'), e),
- level=logging.ERROR, noiselevel=-1)
- continue
+ fifo_writer.start()
+ eof = fifo_writer.poll() is not None
- if events[0]:
- break
+ while not eof:
+ fifo_writer._wait_loop(timeout=self._COMMUNICATE_RETRY_TIMEOUT_MS)
- if self._daemon_is_alive():
+ eof = fifo_writer.poll() is not None
+ if eof:
+ break
+ elif self._daemon_is_alive():
self._timeout_retry_msg(start_time, msg)
else:
+ fifo_writer.cancel()
self._no_daemon_msg()
- try:
- os.kill(pid, signal.SIGKILL)
- os.waitpid(pid, 0)
- except OSError as e:
- portage.util.writemsg_level(
- "ebuild-ipc: %s\n" % (e,),
- level=logging.ERROR, noiselevel=-1)
+ fifo_writer.wait()
return 2
- try:
- wait_retval = os.waitpid(pid, 0)
- except OSError as e:
- portage.util.writemsg_level(
- "ebuild-ipc: %s: %s\n" % (msg, e),
- level=logging.ERROR, noiselevel=-1)
- return 2
+ return fifo_writer.wait()
- if not os.WIFEXITED(wait_retval[1]):
- portage.util.writemsg_level(
- "ebuild-ipc: %s: %s\n" % (msg,
- portage.localization._('subprocess failure: %s') % \
- wait_retval[1]),
- level=logging.ERROR, noiselevel=-1)
- return 2
+ def _receive_reply(self, input_fd):
- return os.WEXITSTATUS(wait_retval[1])
+ start_time = time.time()
- def _receive_reply(self, input_fd):
+ pipe_reader = PipeReader(input_files={"input_fd":input_fd},
+ scheduler=global_event_loop())
+ pipe_reader.start()
- # Timeouts are handled by the parent process, so just
- # block until input is available. For maximum portability,
- # use a single atomic read.
- buf = None
- while True:
- try:
- events = select.select([input_fd], [], [])
- except select.error as e:
- portage.util.writemsg_level(
- "ebuild-ipc: %s: %s\n" % \
- (portage.localization._('during select for read'), e),
- level=logging.ERROR, noiselevel=-1)
- continue
-
- if events[0]:
- # For maximum portability, use os.read() here since
- # array.fromfile() and file.read() are both known to
- # erroneously return an empty string from this
- # non-blocking fifo stream on FreeBSD (bug #337465).
- try:
- buf = os.read(input_fd, self._BUFSIZE)
- except OSError as e:
- if e.errno != errno.EAGAIN:
- portage.util.writemsg_level(
- "ebuild-ipc: %s: %s\n" % \
- (portage.localization._('read error'), e),
- level=logging.ERROR, noiselevel=-1)
- break
- # Assume that another event will be generated
- # if there's any relevant data.
- continue
-
- # Only one (atomic) read should be necessary.
- if buf:
- break
+ eof = pipe_reader.poll() is not None
+
+ while not eof:
+ pipe_reader._wait_loop(timeout=self._COMMUNICATE_RETRY_TIMEOUT_MS)
+ eof = pipe_reader.poll() is not None
+ if not eof:
+ if self._daemon_is_alive():
+ self._timeout_retry_msg(start_time,
+ portage.localization._('during read'))
+ else:
+ pipe_reader.cancel()
+ self._no_daemon_msg()
+ return 2
+
+ buf = pipe_reader.getvalue()
retval = 2
@@ -232,32 +203,9 @@ class EbuildIpc(object):
# un-interrupted, while the parent handles all timeout
# considerations. This helps to avoid possible race conditions
# from interference between timeouts and blocking IO operations.
- pr, pw = os.pipe()
- pid = os.fork()
-
- if pid == 0:
- retval = 2
- try:
- os.close(pr)
-
- # File streams are in unbuffered mode since we do atomic
- # read and write of whole pickles.
- output_file = open(self.ipc_in_fifo, 'wb', 0)
- output_file.write(pickle.dumps(args))
- output_file.close()
- retval = os.EX_OK
- except SystemExit:
- raise
- except:
- traceback.print_exc()
- finally:
- os._exit(retval)
-
- os.close(pw)
-
msg = portage.localization._('during write')
- retval = self._wait(pid, pr, msg)
- os.close(pr)
+ retval = self._run_writer(FifoWriter(buf=pickle.dumps(args),
+ fifo=self.ipc_in_fifo, scheduler=global_event_loop()), msg)
if retval != os.EX_OK:
portage.util.writemsg_level(
@@ -270,26 +218,7 @@ class EbuildIpc(object):
self._no_daemon_msg()
return 2
- pr, pw = os.pipe()
- pid = os.fork()
-
- if pid == 0:
- retval = 2
- try:
- os.close(pr)
- retval = self._receive_reply(input_fd)
- except SystemExit:
- raise
- except:
- traceback.print_exc()
- finally:
- os._exit(retval)
-
- os.close(pw)
- retval = self._wait(pid, pr, portage.localization._('during read'))
- os.close(pr)
- os.close(input_fd)
- return retval
+ return self._receive_reply(input_fd)
def ebuild_ipc_main(args):
ebuild_ipc = EbuildIpc()
diff --git a/bin/ebuild.sh b/bin/ebuild.sh
index 9829f68b3..be044e08d 100755
--- a/bin/ebuild.sh
+++ b/bin/ebuild.sh
@@ -1,5 +1,5 @@
#!/bin/bash
-# Copyright 1999-2012 Gentoo Foundation
+# Copyright 1999-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
PORTAGE_BIN_PATH="${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"
@@ -21,21 +21,23 @@ else
# in global scope, even though they are completely useless during
# the "depend" phase.
for x in diropts docompress exeopts get_KV insopts \
- keepdir KV_major KV_micro KV_minor KV_to_int \
+ KV_major KV_micro KV_minor KV_to_int \
libopts register_die_hook register_success_hook \
- remove_path_entry set_unless_changed strip_duplicate_slashes \
- unset_unless_changed use_with use_enable ; do
+ __strip_duplicate_slashes \
+ use_with use_enable ; do
eval "${x}() {
- if has \"\${EAPI:-0}\" 4-python; then
+ if ___eapi_disallows_helpers_in_global_scope; then
die \"\${FUNCNAME}() calls are not allowed in global scope\"
fi
}"
done
- # These dummy functions return false in older EAPIs, in order to ensure that
+ # These dummy functions return false in non-strict EAPIs, in order to ensure that
# `use multislot` is false for the "depend" phase.
- for x in use useq usev ; do
+ funcs="use useq usev"
+ ___eapi_has_usex && funcs+=" usex"
+ for x in ${funcs} ; do
eval "${x}() {
- if has \"\${EAPI:-0}\" 4-python; then
+ if ___eapi_disallows_helpers_in_global_scope; then
die \"\${FUNCNAME}() calls are not allowed in global scope\"
else
return 1
@@ -44,10 +46,16 @@ else
done
# These functions die because calls to them during the "depend" phase
# are considered to be severe QA violations.
- for x in best_version has_version portageq ; do
+ funcs="best_version has_version portageq"
+ ___eapi_has_master_repositories && funcs+=" master_repositories"
+ ___eapi_has_repository_path && funcs+=" repository_path"
+ ___eapi_has_available_eclasses && funcs+=" available_eclasses"
+ ___eapi_has_eclass_path && funcs+=" eclass_path"
+ ___eapi_has_license_path && funcs+=" license_path"
+ for x in ${funcs} ; do
eval "${x}() { die \"\${FUNCNAME}() calls are not allowed in global scope\"; }"
done
- unset x
+ unset funcs x
fi
# Don't use sandbox's BASH_ENV for new shells because it does
@@ -66,7 +74,7 @@ export PORTAGE_BZIP2_COMMAND=${PORTAGE_BZIP2_COMMAND:-bzip2}
# with shell opts (shopts). Ebuilds/eclasses changing shopts should reset them
# when they are done.
-qa_source() {
+__qa_source() {
local shopts=$(shopt) OLDIFS="$IFS"
local retval
source "$@"
@@ -79,7 +87,7 @@ qa_source() {
return $retval
}
-qa_call() {
+__qa_call() {
local shopts=$(shopt) OLDIFS="$IFS"
local retval
"$@"
@@ -102,20 +110,19 @@ unset GZIP BZIP BZIP2 CDPATH GREP_OPTIONS GREP_COLOR GLOBIGNORE
[[ $PORTAGE_QUIET != "" ]] && export PORTAGE_QUIET
# sandbox support functions; defined prior to profile.bashrc srcing, since the profile might need to add a default exception (/usr/lib64/conftest fex)
-_sb_append_var() {
+__sb_append_var() {
local _v=$1 ; shift
local var="SANDBOX_${_v}"
- [[ -z $1 || -n $2 ]] && die "Usage: add$(echo ${_v} | \
- LC_ALL=C tr [:upper:] [:lower:]) <colon-delimited list of paths>"
+ [[ -z $1 || -n $2 ]] && die "Usage: add$(LC_ALL=C tr "[:upper:]" "[:lower:]" <<< "${_v}") <colon-delimited list of paths>"
export ${var}="${!var:+${!var}:}$1"
}
# bash-4 version:
# local var="SANDBOX_${1^^}"
-# addread() { _sb_append_var ${0#add} "$@" ; }
-addread() { _sb_append_var READ "$@" ; }
-addwrite() { _sb_append_var WRITE "$@" ; }
-adddeny() { _sb_append_var DENY "$@" ; }
-addpredict() { _sb_append_var PREDICT "$@" ; }
+# addread() { __sb_append_var ${0#add} "$@" ; }
+addread() { __sb_append_var READ "$@" ; }
+addwrite() { __sb_append_var WRITE "$@" ; }
+adddeny() { __sb_append_var DENY "$@" ; }
+addpredict() { __sb_append_var PREDICT "$@" ; }
addwrite "${PORTAGE_TMPDIR}"
addread "/:${PORTAGE_TMPDIR}"
@@ -136,19 +143,11 @@ fi
# the sandbox is disabled by default except when overridden in the relevant stages
export SANDBOX_ON=0
-esyslog() {
- # Custom version of esyslog() to take care of the "Red Star" bug.
- # MUST follow functions.sh to override the "" parameter problem.
- return 0
-}
-
# Ensure that $PWD is sane whenever possible, to protect against
# exploitation of insecure search path for python -c in ebuilds.
-# See bug #239560.
-if ! has "$EBUILD_PHASE" clean cleanrm depend help ; then
- cd "$PORTAGE_BUILDDIR" || \
- die "PORTAGE_BUILDDIR does not exist: '$PORTAGE_BUILDDIR'"
-fi
+# See bug #239560 and bug #469338.
+cd "${PORTAGE_PYM_PATH}" || \
+ die "PORTAGE_PYM_PATH does not exist: '${PORTAGE_PYM_PATH}'"
#if no perms are specified, dirs/files will have decent defaults
#(not secretive, but not stupid)
@@ -178,8 +177,8 @@ debug-print() {
# default target
printf '%s\n' "${@}" >> "${T}/eclass-debug.log"
# let the portage user own/write to this file
- chgrp portage "${T}/eclass-debug.log" &>/dev/null
- chmod g+w "${T}/eclass-debug.log" &>/dev/null
+ chgrp "${PORTAGE_GRPNAME:-portage}" "${T}/eclass-debug.log"
+ chmod g+w "${T}/eclass-debug.log"
fi
}
@@ -208,8 +207,9 @@ inherit() {
| fmt -w 75 | while read -r ; do eqawarn "$REPLY" ; done
fi
+ local repo_location
local location
- local olocation
+ local potential_location
local x
# These variables must be restored before returning.
@@ -221,9 +221,10 @@ inherit() {
local B_DEPEND
local B_RDEPEND
local B_PDEPEND
+ local B_HDEPEND
while [ "$1" ]; do
- location="${ECLASSDIR}/${1}.eclass"
- olocation=""
+ location=""
+ potential_location=""
export ECLASS="$1"
__export_funcs_var=__export_functions_$ECLASS_DEPTH
@@ -244,43 +245,36 @@ inherit() {
fi
fi
- # any future resolution code goes here
- if [ -n "$PORTDIR_OVERLAY" ]; then
- local overlay
- for overlay in ${PORTDIR_OVERLAY}; do
- olocation="${overlay}/eclass/${1}.eclass"
- if [ -e "$olocation" ]; then
- location="${olocation}"
- debug-print " eclass exists: ${location}"
- fi
- done
- fi
+ for repo_location in "${PORTAGE_ECLASS_LOCATIONS[@]}"; do
+ potential_location="${repo_location}/eclass/${1}.eclass"
+ if [[ -f ${potential_location} ]]; then
+ location="${potential_location}"
+ debug-print " eclass exists: ${location}"
+ break
+ fi
+ done
debug-print "inherit: $1 -> $location"
- [ ! -e "$location" ] && die "${1}.eclass could not be found by inherit()"
-
- if [ "${location}" == "${olocation}" ] && \
- ! has "${location}" ${EBUILD_OVERLAY_ECLASSES} ; then
- EBUILD_OVERLAY_ECLASSES="${EBUILD_OVERLAY_ECLASSES} ${location}"
- fi
+ [[ -z ${location} ]] && die "${1}.eclass could not be found by inherit()"
- #We need to back up the value of DEPEND and RDEPEND to B_DEPEND and B_RDEPEND
+ #We need to back up the values of *DEPEND to B_*DEPEND
#(if set).. and then restore them after the inherit call.
#turn off glob expansion
set -f
# Retain the old data and restore it later.
- unset B_IUSE B_REQUIRED_USE B_DEPEND B_RDEPEND B_PDEPEND
+ unset B_IUSE B_REQUIRED_USE B_DEPEND B_RDEPEND B_PDEPEND B_HDEPEND
[ "${IUSE+set}" = set ] && B_IUSE="${IUSE}"
[ "${REQUIRED_USE+set}" = set ] && B_REQUIRED_USE="${REQUIRED_USE}"
[ "${DEPEND+set}" = set ] && B_DEPEND="${DEPEND}"
[ "${RDEPEND+set}" = set ] && B_RDEPEND="${RDEPEND}"
[ "${PDEPEND+set}" = set ] && B_PDEPEND="${PDEPEND}"
- unset IUSE REQUIRED_USE DEPEND RDEPEND PDEPEND
+ [ "${HDEPEND+set}" = set ] && B_HDEPEND="${HDEPEND}"
+ unset IUSE REQUIRED_USE DEPEND RDEPEND PDEPEND HDEPEND
#turn on glob expansion
set +f
- qa_source "$location" || die "died sourcing $location in inherit()"
+ __qa_source "$location" || die "died sourcing $location in inherit()"
#turn off glob expansion
set -f
@@ -292,6 +286,7 @@ inherit() {
[ "${DEPEND+set}" = set ] && E_DEPEND+="${E_DEPEND:+ }${DEPEND}"
[ "${RDEPEND+set}" = set ] && E_RDEPEND+="${E_RDEPEND:+ }${RDEPEND}"
[ "${PDEPEND+set}" = set ] && E_PDEPEND+="${E_PDEPEND:+ }${PDEPEND}"
+ [ "${HDEPEND+set}" = set ] && E_HDEPEND+="${E_HDEPEND:+ }${HDEPEND}"
[ "${B_IUSE+set}" = set ] && IUSE="${B_IUSE}"
[ "${B_IUSE+set}" = set ] || unset IUSE
@@ -308,6 +303,9 @@ inherit() {
[ "${B_PDEPEND+set}" = set ] && PDEPEND="${B_PDEPEND}"
[ "${B_PDEPEND+set}" = set ] || unset PDEPEND
+ [ "${B_HDEPEND+set}" = set ] && HDEPEND="${B_HDEPEND}"
+ [ "${B_HDEPEND+set}" = set ] || unset HDEPEND
+
#turn on glob expansion
set +f
@@ -348,7 +346,7 @@ EXPORT_FUNCTIONS() {
PORTAGE_BASHRCS_SOURCED=0
-# @FUNCTION: source_all_bashrcs
+# @FUNCTION: __source_all_bashrcs
# @DESCRIPTION:
# Source a relevant bashrc files and perform other miscellaneous
# environment initialization when appropriate.
@@ -359,7 +357,7 @@ PORTAGE_BASHRCS_SOURCED=0
# * A "default" function which is an alias for the default phase
# function for the current phase.
#
-source_all_bashrcs() {
+__source_all_bashrcs() {
[[ $PORTAGE_BASHRCS_SOURCED = 1 ]] && return 0
PORTAGE_BASHRCS_SOURCED=1
local x
@@ -373,7 +371,7 @@ source_all_bashrcs() {
local path_array=($PROFILE_PATHS)
restore_IFS
for x in "${path_array[@]}" ; do
- [ -f "$x/profile.bashrc" ] && qa_source "$x/profile.bashrc"
+ [ -f "$x/profile.bashrc" ] && __qa_source "$x/profile.bashrc"
done
fi
@@ -390,7 +388,7 @@ source_all_bashrcs() {
if [[ $EBUILD_PHASE != depend ]] ; then
# The user's bashrc is the ONLY non-portage bit of code that can
# change shopts without a QA violation.
- for x in "${PM_EBUILD_HOOK_DIR}"/${CATEGORY}/{${PN},${PN}:${SLOT},${P},${PF}}; do
+ for x in "${PM_EBUILD_HOOK_DIR}"/${CATEGORY}/{${PN},${PN}:${SLOT%/*},${P},${PF}}; do
if [ -r "${x}" ]; then
# If $- contains x, then tracing has already been enabled
# elsewhere for some reason. We preserve it's state so as
@@ -470,7 +468,7 @@ if [[ -n ${QA_INTERCEPTORS} ]] ; then
fi
# Subshell/helper die support (must export for the die helper).
-export EBUILD_MASTER_PID=$BASHPID
+export EBUILD_MASTER_PID=${BASHPID:-$(__bashpid)}
trap 'exit 1' SIGTERM
if ! has "$EBUILD_PHASE" clean cleanrm depend && \
@@ -479,7 +477,7 @@ if ! has "$EBUILD_PHASE" clean cleanrm depend && \
# may have come from another version of ebuild.sh or something.
# In any case, preprocess it to prevent any potential interference.
# NOTE: export ${FOO}=... requires quoting, unlike normal exports
- preprocess_ebuild_env || \
+ __preprocess_ebuild_env || \
die "error processing environment"
# Colon separated SANDBOX_* variables need to be cumulative.
for x in SANDBOX_DENY SANDBOX_READ SANDBOX_PREDICT SANDBOX_WRITE ; do
@@ -512,17 +510,22 @@ if ! has "$EBUILD_PHASE" clean cleanrm depend && \
[[ -n $EAPI ]] || EAPI=0
fi
-if has "${EAPI:-0}" 4-python; then
+if ___eapi_enables_globstar; then
shopt -s globstar
fi
+# Convert quoted paths to array.
+eval "PORTAGE_ECLASS_LOCATIONS=(${PORTAGE_ECLASS_LOCATIONS})"
+
+# Source the ebuild every time for FEATURES=noauto, so that ebuild
+# modifications take effect immediately.
if ! has "$EBUILD_PHASE" clean cleanrm ; then
if [[ $EBUILD_PHASE = depend || ! -f $T/environment || \
- -f $PORTAGE_BUILDDIR/.ebuild_changed ]] || \
- has noauto $FEATURES ; then
+ -f $PORTAGE_BUILDDIR/.ebuild_changed || \
+ " ${FEATURES} " == *" noauto "* ]] ; then
# The bashrcs get an opportunity here to set aliases that will be expanded
# during sourcing of ebuilds and eclasses.
- source_all_bashrcs
+ __source_all_bashrcs
# When EBUILD_PHASE != depend, INHERITED comes pre-initialized
# from cache. In order to make INHERITED content independent of
@@ -534,8 +537,9 @@ if ! has "$EBUILD_PHASE" clean cleanrm ; then
# In order to ensure correct interaction between ebuilds and
# eclasses, they need to be unset before this process of
# interaction begins.
- unset EAPI DEPEND RDEPEND PDEPEND INHERITED IUSE REQUIRED_USE \
- ECLASS E_IUSE E_REQUIRED_USE E_DEPEND E_RDEPEND E_PDEPEND
+ unset EAPI DEPEND RDEPEND PDEPEND HDEPEND INHERITED IUSE REQUIRED_USE \
+ ECLASS E_IUSE E_REQUIRED_USE E_DEPEND E_RDEPEND E_PDEPEND \
+ E_HDEPEND
if [[ $PORTAGE_DEBUG != 1 || ${-/x/} != $- ]] ; then
source "$EBUILD" || die "error sourcing ebuild"
@@ -556,7 +560,7 @@ if ! has "$EBUILD_PHASE" clean cleanrm ; then
# export EAPI for helpers (especially since we unset it above)
export EAPI
- if has "$EAPI" 0 1 2 3 3_pre2 ; then
+ if ___eapi_has_RDEPEND_DEPEND_fallback; then
export RDEPEND=${RDEPEND-${DEPEND}}
debug-print "RDEPEND: not set... Setting to: ${DEPEND}"
fi
@@ -566,19 +570,20 @@ if ! has "$EBUILD_PHASE" clean cleanrm ; then
DEPEND+="${DEPEND:+ }${E_DEPEND}"
RDEPEND+="${RDEPEND:+ }${E_RDEPEND}"
PDEPEND+="${PDEPEND:+ }${E_PDEPEND}"
+ HDEPEND+="${HDEPEND:+ }${E_HDEPEND}"
REQUIRED_USE+="${REQUIRED_USE:+ }${E_REQUIRED_USE}"
- unset ECLASS E_IUSE E_REQUIRED_USE E_DEPEND E_RDEPEND E_PDEPEND \
+ unset ECLASS E_IUSE E_REQUIRED_USE E_DEPEND E_RDEPEND E_PDEPEND E_HDEPEND \
__INHERITED_QA_CACHE
# alphabetically ordered by $EBUILD_PHASE value
- case "$EAPI" in
+ case ${EAPI} in
0|1)
_valid_phases="src_compile pkg_config pkg_info src_install
pkg_nofetch pkg_postinst pkg_postrm pkg_preinst pkg_prerm
pkg_setup src_test src_unpack"
;;
- 2|3|3_pre2)
+ 2|3)
_valid_phases="src_compile pkg_config src_configure pkg_info
src_install pkg_nofetch pkg_postinst pkg_postrm pkg_preinst
src_prepare pkg_prerm pkg_setup src_test src_unpack"
@@ -670,9 +675,13 @@ if [[ $EBUILD_PHASE = depend ]] ; then
auxdbkeys="DEPEND RDEPEND SLOT SRC_URI RESTRICT HOMEPAGE LICENSE
DESCRIPTION KEYWORDS INHERITED IUSE REQUIRED_USE PDEPEND PROVIDE EAPI
- PROPERTIES DEFINED_PHASES UNUSED_05 UNUSED_04
+ PROPERTIES DEFINED_PHASES HDEPEND UNUSED_04
UNUSED_03 UNUSED_02 UNUSED_01"
+ if ! ___eapi_has_HDEPEND; then
+ unset HDEPEND
+ fi
+
# The extra $(echo) commands remove newlines.
if [ -n "${dbkey}" ] ; then
> "${dbkey}"
@@ -681,31 +690,28 @@ if [[ $EBUILD_PHASE = depend ]] ; then
done
else
for f in ${auxdbkeys} ; do
- echo $(echo ${!f}) 1>&9 || exit $?
+ eval "echo \$(echo \${!f}) 1>&${PORTAGE_PIPE_FD}" || exit $?
done
- exec 9>&-
+ eval "exec ${PORTAGE_PIPE_FD}>&-"
fi
set +f
else
- # Note: readonly variables interfere with preprocess_ebuild_env(), so
+ # Note: readonly variables interfere with __preprocess_ebuild_env(), so
# declare them only after it has already run.
declare -r $PORTAGE_READONLY_METADATA $PORTAGE_READONLY_VARS
- case "$EAPI" in
- 0|1|2)
- [[ " ${FEATURES} " == *" force-prefix "* ]] && \
- declare -r ED EPREFIX EROOT
- ;;
- *)
- declare -r ED EPREFIX EROOT
- ;;
- esac
+ if ___eapi_has_prefix_variables; then
+ declare -r ED EPREFIX EROOT
+ fi
if [[ -n $EBUILD_SH_ARGS ]] ; then
(
# Don't allow subprocesses to inherit the pipe which
# emerge uses to monitor ebuild.sh.
- exec 9>&-
- ebuild_main ${EBUILD_SH_ARGS}
+ if [[ -n ${PORTAGE_PIPE_FD} ]] ; then
+ eval "exec ${PORTAGE_PIPE_FD}>&-"
+ unset PORTAGE_PIPE_FD
+ fi
+ __ebuild_main ${EBUILD_SH_ARGS}
exit 0
)
exit $?
diff --git a/bin/egencache b/bin/egencache
index a75a34172..c14be936b 100755
--- a/bin/egencache
+++ b/bin/egencache
@@ -1,15 +1,17 @@
-#!/usr/bin/python
-# Copyright 2009-2012 Gentoo Foundation
+#!/usr/bin/python -b
+# Copyright 2009-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-from __future__ import print_function
+# unicode_literals for compat with TextIOWrapper in Python 2
+from __future__ import print_function, unicode_literals
+import platform
import signal
import sys
# This block ensures that ^C interrupts are handled quietly.
try:
- def exithandler(signum,frame):
+ def exithandler(signum, _frame):
signal.signal(signal.SIGINT, signal.SIG_IGN)
signal.signal(signal.SIGTERM, signal.SIG_IGN)
sys.exit(128 + signum)
@@ -20,26 +22,39 @@ try:
except KeyboardInterrupt:
sys.exit(128 + signal.SIGINT)
+def debug_signal(_signum, _frame):
+ import pdb
+ pdb.set_trace()
+
+if platform.python_implementation() == 'Jython':
+ debug_signum = signal.SIGUSR2 # bug #424259
+else:
+ debug_signum = signal.SIGUSR1
+
+signal.signal(debug_signum, debug_signal)
+
import io
import logging
-import optparse
import subprocess
import time
import textwrap
import re
-try:
- import portage
-except ImportError:
- from os import path as osp
- sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
- import portage
-
+from os import path as osp
+pym_path = osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")
+sys.path.insert(0, pym_path)
+import portage
+portage._internal_caller = True
from portage import os, _encodings, _unicode_encode, _unicode_decode
from _emerge.MetadataRegen import MetadataRegen
from portage.cache.cache_errors import CacheError, StatCollision
+from portage.const import TIMESTAMP_FORMAT
from portage.manifest import guessManifestFileType
+from portage.package.ebuild._parallel_manifest.ManifestScheduler import ManifestScheduler
from portage.util import cmp_sort_key, writemsg_level
+from portage.util._argparse import ArgumentParser
+from portage.util._async.run_main_scheduler import run_main_scheduler
+from portage.util._eventloop.global_event_loop import global_event_loop
from portage import cpv_getkey
from portage.dep import Atom, isjustname
from portage.versions import pkgsplit, vercmp
@@ -59,72 +74,98 @@ else:
from repoman.utilities import FindVCS
if sys.hexversion >= 0x3000000:
+ # pylint: disable=W0622
long = int
def parse_args(args):
usage = "egencache [options] <action> ... [atom] ..."
- parser = optparse.OptionParser(usage=usage)
+ parser = ArgumentParser(usage=usage)
- actions = optparse.OptionGroup(parser, 'Actions')
- actions.add_option("--update",
+ actions = parser.add_argument_group('Actions')
+ actions.add_argument("--update",
action="store_true",
- help="update metadata/cache/ (generate as necessary)")
- actions.add_option("--update-use-local-desc",
+ help="update metadata/md5-cache/ (generate as necessary)")
+ actions.add_argument("--update-use-local-desc",
action="store_true",
help="update the use.local.desc file from metadata.xml")
- actions.add_option("--update-changelogs",
+ actions.add_argument("--update-changelogs",
action="store_true",
help="update the ChangeLog files from SCM logs")
- parser.add_option_group(actions)
+ actions.add_argument("--update-manifests",
+ action="store_true",
+ help="update manifests")
- common = optparse.OptionGroup(parser, 'Common options')
- common.add_option("--repo",
+ common = parser.add_argument_group('Common options')
+ common.add_argument("--repo",
action="store",
- help="name of repo to operate on (default repo is located at $PORTDIR)")
- common.add_option("--config-root",
+ help="name of repo to operate on")
+ common.add_argument("--config-root",
help="location of portage config files",
dest="portage_configroot")
- common.add_option("--portdir",
- help="override the portage tree location",
+ common.add_argument("--gpg-dir",
+ help="override the PORTAGE_GPG_DIR variable",
+ dest="gpg_dir")
+ common.add_argument("--gpg-key",
+ help="override the PORTAGE_GPG_KEY variable",
+ dest="gpg_key")
+ common.add_argument("--portdir",
+ help="override the PORTDIR variable (deprecated in favor of --repositories-configuration)",
dest="portdir")
- common.add_option("--portdir-overlay",
- help="override the PORTDIR_OVERLAY variable (requires that --repo is also specified)",
+ common.add_argument("--portdir-overlay",
+ help="override the PORTDIR_OVERLAY variable (deprecated in favor of --repositories-configuration)",
dest="portdir_overlay")
- common.add_option("--tolerant",
+ common.add_argument("--repositories-configuration",
+ help="override configuration of repositories (in format of repos.conf)",
+ dest="repositories_configuration")
+ common.add_argument("--sign-manifests",
+ choices=('y', 'n'),
+ metavar="<y|n>",
+ help="manually override layout.conf sign-manifests setting")
+ common.add_argument("--strict-manifests",
+ choices=('y', 'n'),
+ metavar="<y|n>",
+ help="manually override \"strict\" FEATURES setting")
+ common.add_argument("--thin-manifests",
+ choices=('y', 'n'),
+ metavar="<y|n>",
+ help="manually override layout.conf thin-manifests setting")
+ common.add_argument("--tolerant",
action="store_true",
help="exit successfully if only minor errors occurred")
- common.add_option("--ignore-default-opts",
+ common.add_argument("--ignore-default-opts",
action="store_true",
help="do not use the EGENCACHE_DEFAULT_OPTS environment variable")
- parser.add_option_group(common)
+ common.add_argument("--write-timestamp",
+ action="store_true",
+ help="write metadata/timestamp.chk as required for rsync repositories")
- update = optparse.OptionGroup(parser, '--update options')
- update.add_option("--cache-dir",
+ update = parser.add_argument_group('--update options')
+ update.add_argument("--cache-dir",
help="location of the metadata cache",
dest="cache_dir")
- update.add_option("--jobs",
+ update.add_argument("-j", "--jobs",
+ type=int,
action="store",
help="max ebuild processes to spawn")
- update.add_option("--load-average",
+ update.add_argument("--load-average",
+ type=float,
action="store",
help="max load allowed when spawning multiple jobs",
dest="load_average")
- update.add_option("--rsync",
+ update.add_argument("--rsync",
action="store_true",
help="enable rsync stat collision workaround " + \
"for bug 139134 (use with --update)")
- parser.add_option_group(update)
- uld = optparse.OptionGroup(parser, '--update-use-local-desc options')
- uld.add_option("--preserve-comments",
+ uld = parser.add_argument_group('--update-use-local-desc options')
+ uld.add_argument("--preserve-comments",
action="store_true",
help="preserve the comments from the existing use.local.desc file")
- uld.add_option("--use-local-desc-output",
+ uld.add_argument("--use-local-desc-output",
help="output file for use.local.desc data (or '-' for stdout)",
dest="uld_output")
- parser.add_option_group(uld)
- options, args = parser.parse_args(args)
+ options, args = parser.parse_known_args(args)
if options.jobs:
jobs = None
@@ -171,9 +212,12 @@ def parse_args(args):
parser.error("Write access denied: --cache-dir='%s'" % \
(options.cache_dir,))
- if options.portdir_overlay is not None and \
- options.repo is None:
- parser.error("--portdir-overlay option requires --repo option")
+ if options.portdir is not None:
+ writemsg_level("egencache: warning: --portdir option is deprecated in favor of --repositories-configuration option\n",
+ level=logging.WARNING, noiselevel=-1)
+ if options.portdir_overlay is not None:
+ writemsg_level("egencache: warning: --portdir-overlay option is deprecated in favor of --repositories-configuration option\n",
+ level=logging.WARNING, noiselevel=-1)
for atom in args:
try:
@@ -215,9 +259,11 @@ class GenCache(object):
else:
self._cp_set = None
self._cp_missing = set()
+ write_auxdb = "metadata-transfer" in portdb.settings.features
self._regen = MetadataRegen(portdb, cp_iter=cp_iter,
consumer=self._metadata_callback,
- max_jobs=max_jobs, max_load=max_load)
+ max_jobs=max_jobs, max_load=max_load,
+ write_auxdb=write_auxdb, main=True)
self.returncode = os.EX_OK
conf = portdb.repositories.get_repo_for_location(tree)
self._trg_caches = tuple(conf.iter_pregenerated_caches(
@@ -255,98 +301,74 @@ class GenCache(object):
def _write_cache(self, trg_cache, cpv, repo_path, metadata, ebuild_hash):
- if not hasattr(trg_cache, 'raise_stat_collision'):
- # This cache does not avoid redundant writes automatically,
- # so check for an identical existing entry before writing.
- # This prevents unnecessary disk writes and can also prevent
- # unnecessary rsync transfers.
- try:
- dest = trg_cache[cpv]
- except (KeyError, CacheError):
- pass
- else:
- if trg_cache.validate_entry(dest,
- ebuild_hash, self._eclass_db):
- identical = True
- for k in self._auxdbkeys:
- if dest.get(k, '') != metadata.get(k, ''):
- identical = False
- break
- if identical:
- return
+ if not hasattr(trg_cache, 'raise_stat_collision'):
+ # This cache does not avoid redundant writes automatically,
+ # so check for an identical existing entry before writing.
+ # This prevents unnecessary disk writes and can also prevent
+ # unnecessary rsync transfers.
+ try:
+ dest = trg_cache[cpv]
+ except (KeyError, CacheError):
+ pass
+ else:
+ if trg_cache.validate_entry(dest,
+ ebuild_hash, self._eclass_db):
+ identical = True
+ for k in self._auxdbkeys:
+ if dest.get(k, '') != metadata.get(k, ''):
+ identical = False
+ break
+ if identical:
+ return
+ try:
+ chf = trg_cache.validation_chf
+ metadata['_%s_' % chf] = getattr(ebuild_hash, chf)
try:
- chf = trg_cache.validation_chf
- metadata['_%s_' % chf] = getattr(ebuild_hash, chf)
+ trg_cache[cpv] = metadata
+ except StatCollision as sc:
+ # If the content of a cache entry changes and neither the
+ # file mtime nor size changes, it will prevent rsync from
+ # detecting changes. Cache backends may raise this
+ # exception from _setitem() if they detect this type of stat
+ # collision. These exceptions are handled by bumping the
+ # mtime on the ebuild (and the corresponding cache entry).
+ # See bug #139134. It is convenient to include checks for
+ # redundant writes along with the internal StatCollision
+ # detection code, so for caches with the
+ # raise_stat_collision attribute, we do not need to
+ # explicitly check for redundant writes like we do for the
+ # other cache types above.
+ max_mtime = sc.mtime
+ for _ec, ec_hash in metadata['_eclasses_'].items():
+ if max_mtime < ec_hash.mtime:
+ max_mtime = ec_hash.mtime
+ if max_mtime == sc.mtime:
+ max_mtime += 1
+ max_mtime = long(max_mtime)
try:
+ os.utime(ebuild_hash.location, (max_mtime, max_mtime))
+ except OSError as e:
+ self.returncode |= 1
+ writemsg_level(
+ "%s writing target: %s\n" % (cpv, e),
+ level=logging.ERROR, noiselevel=-1)
+ else:
+ ebuild_hash.mtime = max_mtime
+ metadata['_mtime_'] = max_mtime
trg_cache[cpv] = metadata
- except StatCollision as sc:
- # If the content of a cache entry changes and neither the
- # file mtime nor size changes, it will prevent rsync from
- # detecting changes. Cache backends may raise this
- # exception from _setitem() if they detect this type of stat
- # collision. These exceptions are handled by bumping the
- # mtime on the ebuild (and the corresponding cache entry).
- # See bug #139134. It is convenient to include checks for
- # redundant writes along with the internal StatCollision
- # detection code, so for caches with the
- # raise_stat_collision attribute, we do not need to
- # explicitly check for redundant writes like we do for the
- # other cache types above.
- max_mtime = sc.mtime
- for ec, ec_hash in metadata['_eclasses_'].items():
- if max_mtime < ec_hash.mtime:
- max_mtime = ec_hash.mtime
- if max_mtime == sc.mtime:
- max_mtime += 1
- max_mtime = long(max_mtime)
- try:
- os.utime(ebuild_hash.location, (max_mtime, max_mtime))
- except OSError as e:
- self.returncode |= 1
- writemsg_level(
- "%s writing target: %s\n" % (cpv, e),
- level=logging.ERROR, noiselevel=-1)
- else:
- ebuild_hash.mtime = max_mtime
- metadata['_mtime_'] = max_mtime
- trg_cache[cpv] = metadata
- self._portdb.auxdb[repo_path][cpv] = metadata
+ self._portdb.auxdb[repo_path][cpv] = metadata
- except CacheError as ce:
- self.returncode |= 1
- writemsg_level(
- "%s writing target: %s\n" % (cpv, ce),
- level=logging.ERROR, noiselevel=-1)
+ except CacheError as ce:
+ self.returncode |= 1
+ writemsg_level(
+ "%s writing target: %s\n" % (cpv, ce),
+ level=logging.ERROR, noiselevel=-1)
def run(self):
-
- received_signal = []
-
- def sighandler(signum, frame):
- signal.signal(signal.SIGINT, signal.SIG_IGN)
- signal.signal(signal.SIGTERM, signal.SIG_IGN)
- self._regen.terminate()
- received_signal.append(128 + signum)
-
- earlier_sigint_handler = signal.signal(signal.SIGINT, sighandler)
- earlier_sigterm_handler = signal.signal(signal.SIGTERM, sighandler)
-
- try:
- self._regen.run()
- finally:
- # Restore previous handlers
- if earlier_sigint_handler is not None:
- signal.signal(signal.SIGINT, earlier_sigint_handler)
- else:
- signal.signal(signal.SIGINT, signal.SIG_DFL)
- if earlier_sigterm_handler is not None:
- signal.signal(signal.SIGTERM, earlier_sigterm_handler)
- else:
- signal.signal(signal.SIGTERM, signal.SIG_DFL)
-
- if received_signal:
- sys.exit(received_signal[0])
+ signum = run_main_scheduler(self._regen)
+ if signum is not None:
+ sys.exit(128 + signum)
self.returncode |= self._regen.returncode
@@ -371,8 +393,8 @@ class GenCache(object):
self.returncode |= 1
writemsg_level(
"Error listing cache entries for " + \
- "'%s/metadata/cache': %s, continuing...\n" % \
- (self._portdb.porttree_root, ce),
+ "'%s': %s, continuing...\n" % \
+ (trg_cache.location, ce),
level=logging.ERROR, noiselevel=-1)
else:
@@ -393,8 +415,8 @@ class GenCache(object):
self.returncode |= 1
writemsg_level(
"Error listing cache entries for " + \
- "'%s/metadata/cache': %s, continuing...\n" % \
- (self._portdb.porttree_root, ce),
+ "'%s': %s, continuing...\n" % \
+ (trg_cache.location, ce),
level=logging.ERROR, noiselevel=-1)
if cp_missing:
@@ -436,7 +458,7 @@ class GenUseLocalDesc(object):
self._portdb = portdb
self._output = output
self._preserve_comments = preserve_comments
-
+
def run(self):
repo_path = self._portdb.porttrees[0]
ops = {'<':0, '<=':1, '=':2, '>=':3, '>':4}
@@ -509,14 +531,14 @@ class GenUseLocalDesc(object):
encoding=_encodings['fs'], errors='strict'),
mode='a', encoding=_encodings['repo.content'],
errors='backslashreplace')
- output.write(_unicode_decode('\n'))
+ output.write('\n')
else:
- output.write(textwrap.dedent(_unicode_decode('''\
+ output.write(textwrap.dedent('''\
# This file is deprecated as per GLEP 56 in favor of metadata.xml. Please add
# your descriptions to your package's metadata.xml ONLY.
# * generated automatically using egencache *
- ''')))
+ '''))
# The cmp function no longer exists in python3, so we'll
# implement our own here under a slightly different name
@@ -544,7 +566,8 @@ class GenUseLocalDesc(object):
for cp in self._portdb.cp_all():
metadata_path = os.path.join(repo_path, cp, 'metadata.xml')
try:
- metadata = ElementTree.parse(metadata_path,
+ metadata = ElementTree.parse(_unicode_encode(metadata_path,
+ encoding=_encodings['fs'], errors='strict'),
parser=ElementTree.XMLParser(
target=_MetadataTreeBuilder()))
except IOError:
@@ -600,8 +623,7 @@ class GenUseLocalDesc(object):
resatoms = sorted(reskeys, key=cmp_sort_key(atomcmp))
resdesc = resdict[reskeys[resatoms[-1]]]
- output.write(_unicode_decode(
- '%s:%s - %s\n' % (cp, flag, resdesc)))
+ output.write('%s:%s - %s\n' % (cp, flag, resdesc))
output.close()
@@ -623,7 +645,8 @@ class _special_filename(_filename_base):
self.file_name = file_name
self.file_type = guessManifestFileType(file_name)
- def file_type_lt(self, a, b):
+ @staticmethod
+ def file_type_lt(a, b):
"""
Defines an ordering between file types.
"""
@@ -698,12 +721,12 @@ class GenChangeLogs(object):
self.returncode |= 2
return
- output.write(textwrap.dedent(_unicode_decode('''\
+ output.write(textwrap.dedent('''\
# ChangeLog for %s
# Copyright 1999-%s Gentoo Foundation; Distributed under the GPL v2
# $Header: $
- ''' % (cp, time.strftime('%Y')))))
+ ''' % (cp, time.strftime('%Y'))))
# now grab all the commits
commits = self.grab(['git', 'rev-list', 'HEAD', '--', '.']).split()
@@ -767,11 +790,10 @@ class GenChangeLogs(object):
# Reverse the sort order for headers.
for c in reversed(changed):
if c.startswith('+') and c.endswith('.ebuild'):
- output.write(_unicode_decode(
- '*%s (%s)\n' % (c[1:-7], date)))
+ output.write('*%s (%s)\n' % (c[1:-7], date))
wroteheader = True
if wroteheader:
- output.write(_unicode_decode('\n'))
+ output.write('\n')
# strip '<cp>: ', '[<cp>] ', and similar
body[0] = re.sub(r'^\W*' + re.escape(cp) + r'\W+', '', body[0])
@@ -791,13 +813,12 @@ class GenChangeLogs(object):
# don't break filenames on hyphens
self._wrapper.break_on_hyphens = False
- output.write(_unicode_decode(
- self._wrapper.fill(
- '%s; %s %s:' % (date, author, ', '.join(changed)))))
+ output.write(self._wrapper.fill(
+ '%s; %s %s:' % (date, author, ', '.join(changed))))
# but feel free to break commit messages there
self._wrapper.break_on_hyphens = True
- output.write(_unicode_decode(
- '\n%s\n\n' % '\n'.join(self._wrapper.fill(x) for x in body)))
+ output.write(
+ '\n%s\n\n' % '\n'.join(self._wrapper.fill(x) for x in body))
output.close()
@@ -830,17 +851,22 @@ class GenChangeLogs(object):
self.generate_changelog(cp)
def egencache_main(args):
- parser, options, atoms = parse_args(args)
-
- config_root = options.config_root
# The calling environment is ignored, so the program is
# completely controlled by commandline arguments.
env = {}
- if options.repo is None:
- env['PORTDIR_OVERLAY'] = ''
- elif options.portdir_overlay:
+ if not sys.stdout.isatty():
+ portage.output.nocolor()
+ env['NOCOLOR'] = 'true'
+
+ parser, options, atoms = parse_args(args)
+
+ config_root = options.config_root
+
+ if options.repositories_configuration is not None:
+ env['PORTAGE_REPOSITORIES'] = options.repositories_configuration
+ elif options.portdir_overlay is not None:
env['PORTDIR_OVERLAY'] = options.portdir_overlay
if options.cache_dir is not None:
@@ -854,7 +880,8 @@ def egencache_main(args):
default_opts = None
if not options.ignore_default_opts:
- default_opts = settings.get('EGENCACHE_DEFAULT_OPTS', '').split()
+ default_opts = portage.util.shlex_split(
+ settings.get('EGENCACHE_DEFAULT_OPTS', ''))
if default_opts:
parser, options, args = parse_args(default_opts + args)
@@ -865,18 +892,50 @@ def egencache_main(args):
settings = portage.config(config_root=config_root,
local_config=False, env=env)
- if not options.update and not options.update_use_local_desc \
- and not options.update_changelogs:
+ if not (options.update or options.update_use_local_desc or
+ options.update_changelogs or options.update_manifests):
parser.error('No action specified')
return 1
+ if options.repo is None:
+ if len(settings.repositories.prepos) == 2:
+ for repo in settings.repositories:
+ if repo.name != "DEFAULT":
+ options.repo = repo.name
+ break
+
+ if options.repo is None:
+ parser.error("--repo option is required")
+
+ repo_path = settings.repositories.treemap.get(options.repo)
+ if repo_path is None:
+ parser.error("Unable to locate repository named '%s'" % (options.repo,))
+ return 1
+
+ repo_config = settings.repositories.get_repo_for_location(repo_path)
+
+ if options.strict_manifests is not None:
+ if options.strict_manifests == "y":
+ settings.features.add("strict")
+ else:
+ settings.features.discard("strict")
+
if options.update and 'metadata-transfer' not in settings.features:
- settings.features.add('metadata-transfer')
+ # Forcibly enable metadata-transfer if portdbapi has a pregenerated
+ # cache that does not support eclass validation.
+ cache = repo_config.get_pregenerated_cache(
+ portage.dbapi.dbapi._known_keys, readonly=True)
+ if cache is not None and not cache.complete_eclass_entries:
+ settings.features.add('metadata-transfer')
+ cache = None
settings.lock()
portdb = portage.portdbapi(mysettings=settings)
+ # Limit ebuilds to the specified repo.
+ portdb.porttrees = [repo_path]
+
if options.update:
if options.cache_dir is not None:
# already validated earlier
@@ -892,17 +951,71 @@ def egencache_main(args):
level=logging.ERROR, noiselevel=-1)
return 1
- if options.repo is not None:
- repo_path = portdb.getRepositoryPath(options.repo)
- if repo_path is None:
- parser.error("Unable to locate repository named '%s'" % \
- (options.repo,))
- return 1
+ if options.sign_manifests is not None:
+ repo_config.sign_manifest = options.sign_manifests == 'y'
- # Limit ebuilds to the specified repo.
- portdb.porttrees = [repo_path]
- else:
- portdb.porttrees = [portdb.porttree_root]
+ if options.thin_manifests is not None:
+ repo_config.thin_manifest = options.thin_manifests == 'y'
+
+ gpg_cmd = None
+ gpg_vars = None
+ force_sign_key = None
+
+ if options.update_manifests:
+ if repo_config.sign_manifest:
+
+ sign_problem = False
+ gpg_dir = None
+ gpg_cmd = settings.get("PORTAGE_GPG_SIGNING_COMMAND")
+ if gpg_cmd is None:
+ writemsg_level("egencache: error: "
+ "PORTAGE_GPG_SIGNING_COMMAND is unset! "
+ "Is make.globals missing?\n",
+ level=logging.ERROR, noiselevel=-1)
+ sign_problem = True
+ elif "${PORTAGE_GPG_KEY}" in gpg_cmd and \
+ options.gpg_key is None and \
+ "PORTAGE_GPG_KEY" not in settings:
+ writemsg_level("egencache: error: "
+ "PORTAGE_GPG_KEY is unset!\n",
+ level=logging.ERROR, noiselevel=-1)
+ sign_problem = True
+ elif "${PORTAGE_GPG_DIR}" in gpg_cmd:
+ if options.gpg_dir is not None:
+ gpg_dir = options.gpg_dir
+ elif "PORTAGE_GPG_DIR" not in settings:
+ gpg_dir = os.path.expanduser("~/.gnupg")
+ else:
+ gpg_dir = os.path.expanduser(settings["PORTAGE_GPG_DIR"])
+ if not os.access(gpg_dir, os.X_OK):
+ writemsg_level(("egencache: error: "
+ "Unable to access directory: "
+ "PORTAGE_GPG_DIR='%s'\n") % gpg_dir,
+ level=logging.ERROR, noiselevel=-1)
+ sign_problem = True
+
+ if sign_problem:
+ writemsg_level("egencache: You may disable manifest "
+ "signatures with --sign-manifests=n or by setting "
+ "\"sign-manifests = false\" in metadata/layout.conf\n",
+ level=logging.ERROR, noiselevel=-1)
+ return 1
+
+ gpg_vars = {}
+ if gpg_dir is not None:
+ gpg_vars["PORTAGE_GPG_DIR"] = gpg_dir
+ gpg_var_names = []
+ if options.gpg_key is None:
+ gpg_var_names.append("PORTAGE_GPG_KEY")
+ else:
+ gpg_vars["PORTAGE_GPG_KEY"] = options.gpg_key
+
+ for k in gpg_var_names:
+ v = settings.get(k)
+ if v is not None:
+ gpg_vars[k] = v
+
+ force_sign_key = gpg_vars.get("PORTAGE_GPG_KEY")
ret = [os.EX_OK]
@@ -921,6 +1034,29 @@ def egencache_main(args):
else:
ret.append(gen_cache.returncode)
+ if options.update_manifests:
+
+ cp_iter = None
+ if atoms:
+ cp_iter = iter(atoms)
+
+ event_loop = global_event_loop()
+ scheduler = ManifestScheduler(portdb, cp_iter=cp_iter,
+ gpg_cmd=gpg_cmd, gpg_vars=gpg_vars,
+ force_sign_key=force_sign_key,
+ max_jobs=options.jobs,
+ max_load=options.load_average,
+ event_loop=event_loop)
+
+ signum = run_main_scheduler(scheduler)
+ if signum is not None:
+ sys.exit(128 + signum)
+
+ if options.tolerant:
+ ret.append(os.EX_OK)
+ else:
+ ret.append(scheduler.returncode)
+
if options.update_use_local_desc:
gen_desc = GenUseLocalDesc(portdb,
output=options.uld_output,
@@ -933,6 +1069,16 @@ def egencache_main(args):
gen_clogs.run()
ret.append(gen_clogs.returncode)
+ if options.write_timestamp:
+ timestamp_path = os.path.join(repo_path, 'metadata', 'timestamp.chk')
+ try:
+ with open(timestamp_path, 'w') as f:
+ f.write(time.strftime('%s\n' % TIMESTAMP_FORMAT, time.gmtime()))
+ except IOError:
+ ret.append(os.EX_IOERR)
+ else:
+ ret.append(os.EX_OK)
+
return max(ret)
if __name__ == "__main__":
diff --git a/bin/emaint b/bin/emaint
index bee46c40d..aeeb18328 100755
--- a/bin/emaint
+++ b/bin/emaint
@@ -1,9 +1,8 @@
-#!/usr/bin/python -O
-# Copyright 2005-2012 Gentoo Foundation
+#!/usr/bin/python -bO
+# Copyright 2005-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-"""'The emaint program provides an interface to system health
- checks and maintenance.
+"""System health checks and maintenance utilities.
"""
from __future__ import print_function
@@ -14,10 +13,10 @@ import errno
try:
import signal
- def exithandler(signum,frame):
+ def exithandler(signum, _frame):
signal.signal(signal.SIGINT, signal.SIG_IGN)
signal.signal(signal.SIGTERM, signal.SIG_IGN)
- sys.exit(1)
+ sys.exit(128 + signum)
signal.signal(signal.SIGINT, exithandler)
signal.signal(signal.SIGTERM, exithandler)
@@ -26,13 +25,11 @@ try:
except KeyboardInterrupt:
sys.exit(1)
-try:
- import portage
-except ImportError:
- from os import path as osp
- sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
- import portage
-
+from os import path as osp
+pym_path = osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")
+sys.path.insert(0, pym_path)
+import portage
+portage._internal_caller = True
from portage.emaint.main import emaint_main
try:
diff --git a/bin/emerge b/bin/emerge
index a9a56432c..bb93d83a6 100755
--- a/bin/emerge
+++ b/bin/emerge
@@ -1,5 +1,5 @@
-#!/usr/bin/python
-# Copyright 2006-2012 Gentoo Foundation
+#!/usr/bin/python -b
+# Copyright 2006-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
from __future__ import print_function
@@ -7,67 +7,73 @@ from __future__ import print_function
import platform
import signal
import sys
-# This block ensures that ^C interrupts are handled quietly.
+
+# This block ensures that ^C interrupts are handled quietly. We handle
+# KeyboardInterrupt instead of installing a SIGINT handler, since
+# exiting from signal handlers intermittently causes python to ignore
+# the SystemExit exception with a message like this:
+# Exception SystemExit: 130 in <function remove at 0x7fd2146c1320> ignored
try:
- def exithandler(signum,frame):
- signal.signal(signal.SIGINT, signal.SIG_IGN)
+ def exithandler(signum, _frame):
signal.signal(signal.SIGTERM, signal.SIG_IGN)
sys.exit(128 + signum)
- signal.signal(signal.SIGINT, exithandler)
signal.signal(signal.SIGTERM, exithandler)
# Prevent "[Errno 32] Broken pipe" exceptions when
# writing to a pipe.
signal.signal(signal.SIGPIPE, signal.SIG_DFL)
-except KeyboardInterrupt:
- sys.exit(128 + signal.SIGINT)
+ def debug_signal(_signum, _frame):
+ import pdb
+ pdb.set_trace()
-def debug_signal(signum, frame):
- import pdb
- pdb.set_trace()
+ if platform.python_implementation() == 'Jython':
+ debug_signum = signal.SIGUSR2 # bug #424259
+ else:
+ debug_signum = signal.SIGUSR1
-if platform.python_implementation() == 'Jython':
- debug_signum = signal.SIGUSR2 # bug #424259
-else:
- debug_signum = signal.SIGUSR1
+ signal.signal(debug_signum, debug_signal)
-signal.signal(debug_signum, debug_signal)
-
-try:
- from _emerge.main import emerge_main
-except ImportError:
from os import path as osp
- import sys
- sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
+ pym_path = osp.join(osp.dirname(osp.dirname(
+ osp.realpath(__file__))), "pym")
+ sys.path.insert(0, pym_path)
+ import portage
+ portage._internal_caller = True
+ portage._disable_legacy_globals()
from _emerge.main import emerge_main
-if __name__ == "__main__":
- import sys
- from portage.exception import ParseError, PermissionDenied
- try:
- retval = emerge_main()
- except PermissionDenied as e:
- sys.stderr.write("Permission denied: '%s'\n" % str(e))
- sys.exit(e.errno)
- except ParseError as e:
- sys.stderr.write("%s\n" % str(e))
- sys.exit(1)
- except SystemExit:
- raise
- except Exception:
- # If an unexpected exception occurs then we don't want the mod_echo
- # output to obscure the traceback, so dump the mod_echo output before
- # showing the traceback.
- import traceback
- tb_str = traceback.format_exc()
+ if __name__ == "__main__":
+ from portage.exception import ParseError, PermissionDenied
try:
- from portage.elog import mod_echo
- except ImportError:
- pass
- else:
- mod_echo.finalize()
- sys.stderr.write(tb_str)
- sys.exit(1)
- sys.exit(retval)
+ retval = emerge_main()
+ except PermissionDenied as e:
+ sys.stderr.write("Permission denied: '%s'\n" % str(e))
+ sys.exit(e.errno)
+ except ParseError as e:
+ sys.stderr.write("%s\n" % str(e))
+ sys.exit(1)
+ except (KeyboardInterrupt, SystemExit):
+ raise
+ except Exception:
+ # If an unexpected exception occurs then we don't want the
+ # mod_echo output to obscure the traceback, so dump the
+ # mod_echo output before showing the traceback.
+ import traceback
+ tb_str = traceback.format_exc()
+ try:
+ from portage.elog import mod_echo
+ except ImportError:
+ pass
+ else:
+ mod_echo.finalize()
+ sys.stderr.write(tb_str)
+ sys.exit(1)
+ sys.exit(retval)
+
+except KeyboardInterrupt:
+ sys.stderr.write("\n\nExiting on signal %(signal)s\n" %
+ {"signal": signal.SIGINT})
+ sys.stderr.flush()
+ sys.exit(128 + signal.SIGINT)
diff --git a/bin/emerge-webrsync b/bin/emerge-webrsync
index bfd9aa2fc..2f0689c15 100755
--- a/bin/emerge-webrsync
+++ b/bin/emerge-webrsync
@@ -1,5 +1,5 @@
#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
+# Copyright 1999-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# Author: Karl Trygve Kalleberg <karltk@gentoo.org>
# Rewritten from the old, Perl-based emerge-webrsync script
@@ -22,9 +22,9 @@ vvecho() { [[ ${do_verbose} -eq 1 ]] && echo "$@" ; }
# Only echo if not in verbose mode
nvecho() { [[ ${do_verbose} -eq 0 ]] && echo "$@" ; }
# warning echos
-wecho() { echo "${argv0}: warning: $*" 1>&2 ; }
+wecho() { echo "${argv0##*/}: warning: $*" 1>&2 ; }
# error echos
-eecho() { echo "${argv0}: error: $*" 1>&2 ; }
+eecho() { echo "${argv0##*/}: error: $*" 1>&2 ; }
argv0=$0
@@ -39,23 +39,33 @@ else
eecho "could not find 'portageq'; aborting"
exit 1
fi
-eval $("${portageq}" envvar -v FEATURES FETCHCOMMAND GENTOO_MIRRORS \
- PORTAGE_BIN_PATH PORTAGE_GPG_DIR \
- PORTAGE_NICENESS PORTAGE_RSYNC_EXTRA_OPTS PORTAGE_TMPDIR PORTDIR \
- SYNC http_proxy ftp_proxy)
-DISTDIR="${PORTAGE_TMPDIR}/emerge-webrsync"
+eval "$("${portageq}" envvar -v DISTDIR EPREFIX FEATURES \
+ FETCHCOMMAND GENTOO_MIRRORS \
+ PORTAGE_BIN_PATH PORTAGE_CONFIGROOT PORTAGE_GPG_DIR \
+ PORTAGE_NICENESS PORTAGE_REPOSITORIES PORTAGE_RSYNC_EXTRA_OPTS \
+ PORTAGE_RSYNC_OPTS PORTAGE_TMPDIR \
+ USERLAND http_proxy ftp_proxy)"
export http_proxy ftp_proxy
+source "${PORTAGE_BIN_PATH}"/isolated-functions.sh || exit 1
+
+repo_name=gentoo
+repo_location=$(__repo_attr "${repo_name}" location)
+if [[ -z ${repo_location} ]]; then
+ eecho "Repository '${repo_name}' not found"
+ exit 1
+fi
+repo_sync_type=$(__repo_attr "${repo_name}" sync-type)
+
# If PORTAGE_NICENESS is overriden via the env then it will
# still pass through the portageq call and override properly.
if [ -n "${PORTAGE_NICENESS}" ]; then
renice $PORTAGE_NICENESS $$ > /dev/null
fi
-source "${PORTAGE_BIN_PATH}"/isolated-functions.sh || exit 1
-
do_verbose=0
do_debug=0
+keep=false
if has webrsync-gpg ${FEATURES} ; then
WEBSYNC_VERIFY_SIGNATURE=1
@@ -99,7 +109,9 @@ get_date_part() {
get_utc_second_from_string() {
local s="$1"
if [[ ${USERLAND} == BSD ]] ; then
- date -juf "%Y%m%d" "$s" +"%s"
+ # Specify zeros for the least significant digits, or else those
+ # digits are inherited from the current system clock time.
+ date -juf "%Y%m%d%H%M.%S" "${s}0000.00" +"%s"
else
date -d "${s:0:4}-${s:4:2}-${s:6:2}" -u +"%s"
fi
@@ -108,8 +120,8 @@ get_utc_second_from_string() {
get_portage_timestamp() {
local portage_current_timestamp=0
- if [ -f "${PORTDIR}/metadata/timestamp.x" ]; then
- portage_current_timestamp=$(cut -f 1 -d " " "${PORTDIR}/metadata/timestamp.x" )
+ if [ -f "${repo_location}/metadata/timestamp.x" ]; then
+ portage_current_timestamp=$(cut -f 1 -d " " "${repo_location}/metadata/timestamp.x" )
fi
echo "${portage_current_timestamp}"
@@ -125,13 +137,18 @@ fetch_file() {
elif [ "${FETCHCOMMAND/curl/}" != "${FETCHCOMMAND}" ]; then
opts="--continue-at - $(nvecho -s -f)"
else
- rm -f "${FILE}"
+ rm -f "${DISTDIR}/${FILE}"
fi
- vecho "Fetching file ${FILE} ..."
+ __vecho "Fetching file ${FILE} ..."
# already set DISTDIR=
- eval "${FETCHCOMMAND}" ${opts}
- [ -s "${FILE}" ]
+ eval "${FETCHCOMMAND} ${opts}"
+ if [[ $? -eq 0 && -s ${DISTDIR}/${FILE} ]] ; then
+ return 0
+ else
+ rm -f "${DISTDIR}/${FILE}"
+ return 1
+ fi
}
check_file_digest() {
@@ -139,10 +156,12 @@ check_file_digest() {
local file="$2"
local r=1
- vecho "Checking digest ..."
+ __vecho "Checking digest ..."
if type -P md5sum > /dev/null; then
- md5sum -c $digest && r=0
+ local md5sum_output=$(md5sum "${file}")
+ local digest_content=$(< "${digest}")
+ [ "${md5sum_output%%[[:space:]]*}" = "${digest_content%%[[:space:]]*}" ] && r=0
elif type -P md5 > /dev/null; then
[ "$(md5 -q "${file}")" == "$(cut -d ' ' -f 1 "${digest}")" ] && r=0
else
@@ -159,7 +178,7 @@ check_file_signature() {
if [ ${WEBSYNC_VERIFY_SIGNATURE} != 0 ]; then
- vecho "Checking signature ..."
+ __vecho "Checking signature ..."
if type -P gpg > /dev/null; then
gpg --homedir "${PORTAGE_GPG_DIR}" --verify "$signature" "$file" && r=0
@@ -183,13 +202,25 @@ get_snapshot_timestamp() {
sync_local() {
local file="$1"
- vecho "Syncing local tree ..."
+ __vecho "Syncing local tree ..."
+
+ local ownership="portage:portage"
+ if has usersync ${FEATURES} ; then
+ case "${USERLAND}" in
+ BSD)
+ ownership=$(stat -f '%Su:%Sg' "${repo_location}")
+ ;;
+ *)
+ ownership=$(stat -c '%U:%G' "${repo_location}")
+ ;;
+ esac
+ fi
if type -P tarsync > /dev/null ; then
- local chown_opts="-o portage -g portage"
- chown portage:portage portage > /dev/null 2>&1 || chown_opts=""
+ local chown_opts="-o ${ownership%:*} -g ${ownership#*:}"
+ chown ${ownership} "${repo_location}" > /dev/null 2>&1 || chown_opts=""
if ! tarsync $(vvecho -v) -s 1 ${chown_opts} \
- -e /distfiles -e /packages -e /local "${file}" "${PORTDIR}"; then
+ -e /distfiles -e /packages -e /local "${file}" "${repo_location}"; then
eecho "tarsync failed; tarball is corrupt? (${file})"
return 1
fi
@@ -201,27 +232,29 @@ sync_local() {
fi
# Free disk space
- rm -f "${file}"
+ ${keep} || rm -f "${file}"
- chown portage:portage portage > /dev/null 2>&1 && \
- chown -R portage:portage portage
+ local rsync_opts="${PORTAGE_RSYNC_OPTS} ${PORTAGE_RSYNC_EXTRA_OPTS}"
+ if chown ${ownership} portage > /dev/null 2>&1; then
+ chown -R ${ownership} portage
+ rsync_opts+=" --owner --group"
+ fi
cd portage
- rsync -av --progress --stats --delete --delete-after \
- --exclude='/distfiles' --exclude='/packages' \
- --exclude='/local' ${PORTAGE_RSYNC_EXTRA_OPTS} . "${PORTDIR%%/}"
+ rsync ${rsync_opts} . "${repo_location%%/}"
cd ..
- vecho "Cleaning up ..."
+ __vecho "Cleaning up ..."
rm -fr portage
fi
if has metadata-transfer ${FEATURES} ; then
- vecho "Updating cache ..."
- emerge --metadata
+ __vecho "Updating cache ..."
+ "${PORTAGE_BIN_PATH}/emerge" --metadata
fi
- [ -x /etc/portage/bin/post_sync ] && /etc/portage/bin/post_sync
+ local post_sync=${PORTAGE_CONFIGROOT}etc/portage/bin/post_sync
+ [ -x "${post_sync}" ] && "${post_sync}"
# --quiet suppresses output if there are no relevant news items
- has news ${FEATURES} && emerge --check-news --quiet
+ has news ${FEATURES} && "${PORTAGE_BIN_PATH}/emerge" --check-news --quiet
return 0
}
@@ -251,14 +284,15 @@ do_snapshot() {
for mirror in ${GENTOO_MIRRORS} ; do
- vecho "Trying to retrieve ${date} snapshot from ${mirror} ..."
+ mirror=${mirror%/}
+ __vecho "Trying to retrieve ${date} snapshot from ${mirror} ..."
for compression in ${compressions} ; do
local file="portage-${date}.tar.${compression}"
local digest="${file}.md5sum"
local signature="${file}.gpgsig"
- if [ -s "${file}" -a -s "${digest}" -a -s "${signature}" ] ; then
+ if [ -s "${DISTDIR}/${file}" -a -s "${DISTDIR}/${digest}" -a -s "${DISTDIR}/${signature}" ] ; then
check_file_digest "${DISTDIR}/${digest}" "${DISTDIR}/${file}" && \
check_file_signature "${DISTDIR}/${signature}" "${DISTDIR}/${file}" && \
have_files=1
@@ -280,8 +314,8 @@ do_snapshot() {
#
if [ ${have_files} -eq 1 ]; then
- vecho "Getting snapshot timestamp ..."
- local snapshot_timestamp=$(get_snapshot_timestamp "${file}")
+ __vecho "Getting snapshot timestamp ..."
+ local snapshot_timestamp=$(get_snapshot_timestamp "${DISTDIR}/${file}")
if [ ${ignore_timestamp} == 0 ]; then
if [ ${snapshot_timestamp} -lt $(get_portage_timestamp) ]; then
@@ -310,7 +344,7 @@ do_snapshot() {
#
# Remove files and use a different mirror
#
- rm -f "${file}" "${digest}" "${signature}"
+ rm -f "${DISTDIR}/${file}" "${DISTDIR}/${digest}" "${DISTDIR}/${signature}"
fi
done
@@ -318,12 +352,12 @@ do_snapshot() {
done
if [ ${have_files} -eq 1 ]; then
- sync_local "${file}" && r=0
+ sync_local "${DISTDIR}/${file}" && r=0
else
- vecho "${date} snapshot was not found"
+ __vecho "${date} snapshot was not found"
fi
-
- rm -f "${file}" "${digest}" "${signature}"
+
+ ${keep} || rm -f "${DISTDIR}/${file}" "${DISTDIR}/${digest}" "${DISTDIR}/${signature}"
return "${r}"
}
@@ -331,9 +365,9 @@ do_latest_snapshot() {
local attempts=0
local r=1
- vecho "Fetching most recent snapshot ..."
+ __vecho "Fetching most recent snapshot ..."
- # The snapshot for a given day is generated at 01:45 UTC on the following
+ # The snapshot for a given day is generated at 00:45 UTC on the following
# day, so the current day's snapshot (going by UTC time) hasn't been
# generated yet. Therefore, always start by looking for the previous day's
# snapshot (for attempts=1, subtract 1 day from the current UTC time).
@@ -349,10 +383,10 @@ do_latest_snapshot() {
local start_time=$(get_utc_date_in_seconds)
local start_hour=$(get_date_part ${start_time} "%H")
- # Daily snapshots are created at 1:45 AM and are not
- # available until after 2 AM. Don't waste time trying
+ # Daily snapshots are created at 00:45 and are not
+ # available until after 01:00. Don't waste time trying
# to fetch a snapshot before it's been created.
- if [ ${start_hour} -lt 2 ] ; then
+ if [ ${start_hour} -lt 1 ] ; then
(( start_time -= 86400 ))
fi
local snapshot_date=$(get_date_part ${start_time} "%Y%m%d")
@@ -361,8 +395,8 @@ do_latest_snapshot() {
while (( ${attempts} < 40 )) ; do
(( attempts++ ))
(( snapshot_date_seconds -= 86400 ))
- # snapshots are created at 1:45 AM
- (( approx_snapshot_time = snapshot_date_seconds + 86400 + 6300 ))
+ # snapshots are created at 00:45
+ (( approx_snapshot_time = snapshot_date_seconds + 86400 + 2700 ))
(( timestamp_difference = existing_timestamp - approx_snapshot_time ))
[ ${timestamp_difference} -lt 0 ] && (( timestamp_difference = -1 * timestamp_difference ))
snapshot_date=$(get_date_part ${snapshot_date_seconds} "%Y%m%d")
@@ -388,7 +422,7 @@ do_latest_snapshot() {
"snapshot. In order to force sync," \
"use the --revert option or remove" \
"the timestamp file located at" \
- "'${PORTDIR}/metadata/timestamp.x'." | fmt -w 70 | \
+ "'${repo_location}/metadata/timestamp.x'." | fmt -w 70 | \
while read -r line ; do
ewarn "${line}"
done
@@ -408,9 +442,10 @@ do_latest_snapshot() {
usage() {
cat <<-EOF
Usage: $0 [options]
-
+
Options:
--revert=yyyymmdd Revert to snapshot
+ -k, --keep Keep snapshots in DISTDIR (don't delete)
-q, --quiet Only output errors
-v, --verbose Enable verbose output
-x, --debug Enable debug output
@@ -427,14 +462,12 @@ usage() {
main() {
local arg
local revert_date
-
- [ ! -d "${DISTDIR}" ] && mkdir -p "${DISTDIR}"
- cd "${DISTDIR}"
for arg in "$@" ; do
local v=${arg#*=}
case ${arg} in
-h|--help) usage ;;
+ -k|--keep) keep=true ;;
-q|--quiet) PORTAGE_QUIET=1 ;;
-v|--verbose) do_verbose=1 ;;
-x|--debug) do_debug=1 ;;
@@ -443,16 +476,39 @@ main() {
esac
done
+ [[ -d ${repo_location} ]] || mkdir -p "${repo_location}"
+ if [[ ! -w ${repo_location} ]] ; then
+ eecho "Repository '${repo_name}' is not writable: ${repo_location}"
+ exit 1
+ fi
+
+ [[ -d ${PORTAGE_TMPDIR}/portage ]] || mkdir -p "${PORTAGE_TMPDIR}/portage"
+ TMPDIR=$(mktemp -d "${PORTAGE_TMPDIR}/portage/webrsync-XXXXXX")
+ if [[ ! -w ${TMPDIR} ]] ; then
+ eecho "TMPDIR is not writable: ${TMPDIR}"
+ exit 1
+ fi
+ trap 'cd / ; rm -rf "${TMPDIR}"' EXIT
+ cd "${TMPDIR}" || exit 1
+
+ ${keep} || DISTDIR=${TMPDIR}
+ [ ! -d "${DISTDIR}" ] && mkdir -p "${DISTDIR}"
+
+ if ${keep} && [[ ! -w ${DISTDIR} ]] ; then
+ eecho "DISTDIR is not writable: ${DISTDIR}"
+ exit 1
+ fi
+
# This is a sanity check to help prevent people like funtoo users
# from accidentally wiping out their git tree.
- if [[ -n $SYNC && ${SYNC#rsync:} = $SYNC ]] ; then
- echo "The current SYNC variable setting does not refer to an rsync URI:" >&2
+ if [[ -n ${repo_sync_type} && ${repo_sync_type} != rsync ]] ; then
+ echo "The current sync-type attribute of repository 'gentoo' is not set to 'rsync':" >&2
echo >&2
- echo " SYNC=$SYNC" >&2
+ echo " sync-type=${repo_sync_type}" >&2
echo >&2
echo "If you intend to use emerge-webrsync then please" >&2
- echo "adjust SYNC to refer to an rsync URI." >&2
- echo "emerge-webrsync exiting due to abnormal SYNC setting." >&2
+ echo "adjust sync-type and sync-uri attributes to refer to rsync." >&2
+ echo "emerge-webrsync exiting due to abnormal sync-type setting." >&2
exit 1
fi
diff --git a/bin/emirrordist b/bin/emirrordist
new file mode 100755
index 000000000..0368eee2a
--- /dev/null
+++ b/bin/emirrordist
@@ -0,0 +1,13 @@
+#!/usr/bin/python -b
+# Copyright 2013-2014 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+import sys
+
+import portage
+portage._internal_caller = True
+portage._disable_legacy_globals()
+from portage._emirrordist.main import emirrordist_main
+
+if __name__ == "__main__":
+ sys.exit(emirrordist_main(sys.argv[1:]))
diff --git a/bin/env-update b/bin/env-update
index 8a69f2bb2..7651ef9c1 100755
--- a/bin/env-update
+++ b/bin/env-update
@@ -1,5 +1,5 @@
-#!/usr/bin/python -O
-# Copyright 1999-2006 Gentoo Foundation
+#!/usr/bin/python -bO
+# Copyright 1999-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
from __future__ import print_function
@@ -25,12 +25,12 @@ if len(sys.argv) > 1:
print("!!! Invalid command line options!\n")
usage(1)
-try:
- import portage
-except ImportError:
- from os import path as osp
- sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
- import portage
+from os import path as osp
+pym_path = osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")
+sys.path.insert(0, pym_path)
+import portage
+portage._internal_caller = True
+
try:
portage.env_update(makelinks)
except IOError as e:
diff --git a/bin/etc-update b/bin/etc-update
index d763c1f73..1a99231b7 100755
--- a/bin/etc-update
+++ b/bin/etc-update
@@ -62,7 +62,7 @@ do_mv_ln() {
}
scan() {
- echo "Scanning Configuration files..."
+ ${QUIET} || echo "Scanning Configuration files..."
rm -rf "${TMP}"/files > /dev/null 2>&1
mkdir "${TMP}"/files || die "Failed mkdir command!"
count=0
@@ -107,13 +107,13 @@ scan() {
for mpath in ${CONFIG_PROTECT_MASK}; do
mpath="${EROOT%/}${mpath}"
if [[ "${rpath}" == "${mpath}"* ]] ; then
- echo "Updating masked file: ${live_file}"
+ ${QUIET} || echo "Updating masked file: ${live_file}"
mv "${cfg_file}" "${live_file}"
continue 2
fi
done
if [[ ! -f ${file} ]] ; then
- echo "Skipping non-file ${file} ..."
+ ${QUIET} || echo "Skipping non-file ${file} ..."
continue
fi
@@ -140,7 +140,7 @@ scan() {
fi
if [[ ${MATCHES} == 1 ]] ; then
- echo "Automerging trivial changes in: ${live_file}"
+ ${QUIET} || echo "Automerging trivial changes in: ${live_file}"
do_mv_ln "${cfg_file}" "${live_file}"
continue
else
@@ -548,9 +548,9 @@ die() {
local msg=$1 exitcode=${2:-1}
if [ ${exitcode} -eq 0 ] ; then
- printf 'Exiting: %b\n' "${msg}"
+ ${QUIET} || printf 'Exiting: %b\n' "${msg}"
scan > /dev/null
- [ ${count} -gt 0 ] && echo "NOTE: ${count} updates remaining"
+ ! ${QUIET} && [ ${count} -gt 0 ] && echo "NOTE: ${count} updates remaining"
else
error "${msg}"
fi
@@ -575,6 +575,7 @@ usage() {
-d, --debug Enable shell debugging
-h, --help Show help and run away
-p, --preen Automerge trivial changes only and quit
+ -q, --quiet Show only essential output
-v, --verbose Show settings and such along the way
-V, --version Show version and trundle away
@@ -600,6 +601,7 @@ declare title="Gentoo's etc-update tool!"
PREEN=false
SET_X=false
+QUIET=false
VERBOSE=false
NONINTERACTIVE_MV=false
while [[ -n $1 ]] ; do
@@ -607,6 +609,7 @@ while [[ -n $1 ]] ; do
-d|--debug) SET_X=true;;
-h|--help) usage;;
-p|--preen) PREEN=true;;
+ -q|--quiet) QUIET=true;;
-v|--verbose) VERBOSE=true;;
-V|--version) emerge --version; exit 0;;
--automode) parse_automode_flag $2 && shift || usage 1 "Invalid mode '$2'";;
@@ -617,7 +620,7 @@ while [[ -n $1 ]] ; do
done
${SET_X} && set -x
-type portageq >/dev/null || die "missing portageq"
+type -P portageq >/dev/null || die "missing portageq"
portage_vars=(
CONFIG_PROTECT{,_MASK}
PORTAGE_CONFIGROOT
@@ -627,7 +630,7 @@ portage_vars=(
USERLAND
NOCOLOR
)
-eval $(portageq envvar -v ${portage_vars[@]})
+eval $(${PORTAGE_PYTHON:+"${PORTAGE_PYTHON}"} "$(type -P portageq)" envvar -v ${portage_vars[@]})
export PORTAGE_TMPDIR
SCAN_PATHS=${*:-${CONFIG_PROTECT}}
diff --git a/bin/filter-bash-environment.py b/bin/filter-bash-environment.py
index b9aec96d0..a4cdc5429 100755
--- a/bin/filter-bash-environment.py
+++ b/bin/filter-bash-environment.py
@@ -1,10 +1,9 @@
-#!/usr/bin/python
-# Copyright 1999-2011 Gentoo Foundation
+#!/usr/bin/python -b
+# Copyright 1999-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
import codecs
import io
-import optparse
import os
import re
import sys
@@ -126,10 +125,19 @@ if __name__ == "__main__":
"intact. The PATTERN is a space separated list of variable names" + \
" and it supports python regular expression syntax."
usage = "usage: %s PATTERN" % os.path.basename(sys.argv[0])
- parser = optparse.OptionParser(description=description, usage=usage)
- options, args = parser.parse_args(sys.argv[1:])
+ args = sys.argv[1:]
+
+ if '-h' in args or '--help' in args:
+ sys.stdout.write(usage + "\n")
+ sys.stdout.flush()
+ sys.exit(os.EX_OK)
+
if len(args) != 1:
- parser.error("Missing required PATTERN argument.")
+ sys.stderr.write(usage + "\n")
+ sys.stderr.write("Exactly one PATTERN argument required.\n")
+ sys.stderr.flush()
+ sys.exit(2)
+
file_in = sys.stdin
file_out = sys.stdout
if sys.hexversion >= 0x3000000:
diff --git a/bin/fixpackages b/bin/fixpackages
index dc43ed2b3..cec0030f2 100755
--- a/bin/fixpackages
+++ b/bin/fixpackages
@@ -1,5 +1,5 @@
-#!/usr/bin/python
-# Copyright 1999-2011 Gentoo Foundation
+#!/usr/bin/python -b
+# Copyright 1999-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
from __future__ import print_function
@@ -7,21 +7,27 @@ from __future__ import print_function
import os
import sys
-try:
- import portage
-except ImportError:
- from os import path as osp
- sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
- import portage
-
+from os import path as osp
+pym_path = osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")
+sys.path.insert(0, pym_path)
+import portage
+portage._internal_caller = True
from portage import os
from portage.output import EOutput
+from portage.util._argparse import ArgumentParser
from textwrap import wrap
from portage._global_updates import _global_updates
mysettings = portage.settings
mytrees = portage.db
mtimedb = portage.mtimedb
+description = """The fixpackages program performs package move updates on
+ configuration files, installed packages, and binary packages."""
+description = " ".join(description.split())
+
+parser = ArgumentParser(description=description)
+parser.parse_args()
+
if mysettings['ROOT'] != "/":
out = EOutput()
msg = "The fixpackages program is not intended for use with " + \
diff --git a/bin/glsa-check b/bin/glsa-check
index a840c3206..972679a80 100755
--- a/bin/glsa-check
+++ b/bin/glsa-check
@@ -1,81 +1,79 @@
-#!/usr/bin/python
-# Copyright 2008-2011 Gentoo Foundation
+#!/usr/bin/python -b
+# Copyright 2008-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
from __future__ import print_function
import sys
+import codecs
-try:
- import portage
-except ImportError:
- from os import path as osp
- sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
- import portage
-
+from os import path as osp
+pym_path = osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")
+sys.path.insert(0, pym_path)
+import portage
+portage._internal_caller = True
from portage import os
-from portage.output import *
-
-from optparse import OptionGroup, OptionParser
+from portage.output import green, red, nocolor, white
+from portage.util._argparse import ArgumentParser
__program__ = "glsa-check"
__author__ = "Marius Mauch <genone@gentoo.org>"
__version__ = "1.0"
-def cb_version(*args, **kwargs):
- """Callback for --version"""
- sys.stderr.write("\n"+ __program__ + ", version " + __version__ + "\n")
- sys.stderr.write("Author: " + __author__ + "\n")
- sys.stderr.write("This program is licensed under the GPL, version 2\n\n")
- sys.exit(0)
-
# option parsing
-parser = OptionParser(usage="%prog <option> [glsa-list]",
- version="%prog "+ __version__)
-parser.epilog = "glsa-list can contain an arbitrary number of GLSA ids," \
+epilog = "glsa-list can contain an arbitrary number of GLSA ids," \
" filenames containing GLSAs or the special identifiers" \
" 'all', 'new' and 'affected'"
+parser = ArgumentParser(usage=__program__ + " <option> [glsa-list]",
+ epilog=epilog)
-modes = OptionGroup(parser, "Modes")
-modes.add_option("-l", "--list", action="store_const",
+modes = parser.add_argument_group("Modes")
+modes.add_argument("-l", "--list", action="store_const",
const="list", dest="mode",
help="List all unapplied GLSA")
-modes.add_option("-d", "--dump", action="store_const",
+modes.add_argument("-d", "--dump", action="store_const",
const="dump", dest="mode",
help="Show all information about the given GLSA")
-modes.add_option("", "--print", action="store_const",
+modes.add_argument("--print", action="store_const",
const="dump", dest="mode",
help="Alias for --dump")
-modes.add_option("-t", "--test", action="store_const",
+modes.add_argument("-t", "--test", action="store_const",
const="test", dest="mode",
help="Test if this system is affected by the given GLSA")
-modes.add_option("-p", "--pretend", action="store_const",
+modes.add_argument("-p", "--pretend", action="store_const",
const="pretend", dest="mode",
help="Show the necessary commands to apply this GLSA")
-modes.add_option("-f", "--fix", action="store_const",
+modes.add_argument("-f", "--fix", action="store_const",
const="fix", dest="mode",
help="Try to auto-apply this GLSA (experimental)")
-modes.add_option("-i", "--inject", action="store_const", dest="mode",
- help="Inject the given GLSA into the checkfile")
-modes.add_option("-m", "--mail", action="store_const",
+modes.add_argument("-i", "--inject", action="store_const",
+ const="inject", dest="mode",
+ help="inject the given GLSA into the glsa_injected file")
+modes.add_argument("-m", "--mail", action="store_const",
const="mail", dest="mode",
help="Send a mail with the given GLSAs to the administrator")
-parser.add_option_group(modes)
-parser.remove_option("--version")
-parser.add_option("-V", "--version", action="callback",
- callback=cb_version, help="Some information about this tool")
-parser.add_option("-v", "--verbose", action="store_true", dest="verbose",
+parser.add_argument("-V", "--version", action="store_true",
+ help="Some information about this tool")
+parser.add_argument("-v", "--verbose", action="store_true", dest="verbose",
help="Print more information")
-parser.add_option("-n", "--nocolor", action="callback",
- callback=lambda *args, **kwargs: nocolor(),
+parser.add_argument("-n", "--nocolor", action="store_true",
help="Disable colors")
-parser.add_option("-e", "--emergelike", action="store_false", dest="least_change",
+parser.add_argument("-e", "--emergelike", action="store_false", dest="least_change",
help="Do not use a least-change algorithm")
-parser.add_option("-c", "--cve", action="store_true", dest="list_cve",
+parser.add_argument("-c", "--cve", action="store_true", dest="list_cve",
help="Show CAN ids in listing mode")
-options, params = parser.parse_args()
+options, params = parser.parse_known_args()
+
+if options.nocolor:
+ nocolor()
+
+if options.version:
+ sys.stderr.write("\n"+ __program__ + ", version " + __version__ + "\n")
+ sys.stderr.write("Author: " + __author__ + "\n")
+ sys.stderr.write("This program is licensed under the GPL, version 2\n\n")
+ sys.exit(0)
mode = options.mode
least_change = options.least_change
@@ -101,7 +99,8 @@ elif mode == "list" and not params:
params.append("new")
# delay this for speed increase
-from portage.glsa import *
+from portage.glsa import (Glsa, GlsaTypeException, GlsaFormatException,
+ get_applied_glsas, get_glsa_list)
eroot = portage.settings['EROOT']
vardb = portage.db[eroot]["vartree"].dbapi
@@ -117,7 +116,7 @@ glsalist = []
if "new" in params:
glsalist = todolist
params.remove("new")
-
+
if "all" in params:
glsalist = completelist
params.remove("all")
@@ -142,8 +141,17 @@ for p in params[:]:
glsalist.extend([g for g in params if g not in glsalist])
-def summarylist(myglsalist, fd1=sys.stdout, fd2=sys.stderr):
- fd2.write(white("[A]")+" means this GLSA was already applied,\n")
+def summarylist(myglsalist, fd1=sys.stdout, fd2=sys.stderr, encoding="utf-8"):
+ # Get to the raw streams in py3k before wrapping them with an encoded writer
+ # to avoid writing bytes to a text stream (stdout/stderr are text streams
+ # by default in py3k)
+ if hasattr(fd1, "buffer"):
+ fd1 = fd1.buffer
+ if hasattr(fd2, "buffer"):
+ fd2 = fd2.buffer
+ fd1 = codecs.getwriter(encoding)(fd1)
+ fd2 = codecs.getwriter(encoding)(fd2)
+ fd2.write(white("[A]")+" means this GLSA was marked as applied (injected),\n")
fd2.write(green("[U]")+" means the system is not affected and\n")
fd2.write(red("[N]")+" indicates that the system might be affected.\n\n")
@@ -155,7 +163,7 @@ def summarylist(myglsalist, fd1=sys.stdout, fd2=sys.stderr):
if verbose:
fd2.write(("invalid GLSA: %s (error message was: %s)\n" % (myid, e)))
continue
- if myglsa.isApplied():
+ if myglsa.isInjected():
status = "[A]"
color = white
elif myglsa.isVulnerable():
@@ -186,7 +194,7 @@ def summarylist(myglsalist, fd1=sys.stdout, fd2=sys.stderr):
fd1.write(")")
if list_cve:
fd1.write(" "+(",".join([r[:13] for r in myglsa.references if r[:4] in ["CAN-", "CVE-"]])))
- fd1.write("\n")
+ fd1.write("\n")
return 0
if mode == "list":
@@ -204,39 +212,46 @@ if mode in ["dump", "fix", "inject", "pretend"]:
if mode == "dump":
myglsa.dump()
elif mode == "fix":
- sys.stdout.write("fixing "+myid+"\n")
- mergelist = myglsa.getMergeList(least_change=least_change)
- for pkg in mergelist:
- sys.stdout.write(">>> merging "+pkg+"\n")
- # using emerge for the actual merging as it contains the dependency
- # code and we want to be consistent in behaviour. Also this functionality
- # will be integrated in emerge later, so it shouldn't hurt much.
- emergecmd = "emerge --oneshot " + portage.settings["EMERGE_OPTS"] + " =" + pkg
- if verbose:
- sys.stderr.write(emergecmd+"\n")
- exitcode = os.system(emergecmd)
- # system() returns the exitcode in the high byte of a 16bit integer
- if exitcode >= 1<<8:
- exitcode >>= 8
- if exitcode:
- sys.exit(exitcode)
- myglsa.inject()
+ sys.stdout.write("Fixing GLSA "+myid+"\n")
+ if not myglsa.isVulnerable():
+ sys.stdout.write(">>> no vulnerable packages installed\n")
+ else:
+ mergelist = myglsa.getMergeList(least_change=least_change)
+ if mergelist == []:
+ sys.stdout.write(">>> cannot fix GLSA, no unaffected packages available\n")
+ sys.exit(2)
+ for pkg in mergelist:
+ sys.stdout.write(">>> merging "+pkg+"\n")
+ # using emerge for the actual merging as it contains the dependency
+ # code and we want to be consistent in behaviour. Also this functionality
+ # will be integrated in emerge later, so it shouldn't hurt much.
+ emergecmd = "emerge --oneshot " + " =" + pkg
+ if verbose:
+ sys.stderr.write(emergecmd+"\n")
+ exitcode = os.system(emergecmd)
+ # system() returns the exitcode in the high byte of a 16bit integer
+ if exitcode >= 1<<8:
+ exitcode >>= 8
+ if exitcode:
+ sys.exit(exitcode)
+ if len(mergelist):
+ sys.stdout.write("\n")
elif mode == "pretend":
sys.stdout.write("Checking GLSA "+myid+"\n")
- mergelist = myglsa.getMergeList(least_change=least_change)
- if mergelist:
- sys.stdout.write("The following updates will be performed for this GLSA:\n")
- for pkg in mergelist:
- oldver = None
- for x in vardb.match(portage.cpv_getkey(pkg)):
- if vardb.aux_get(x, ["SLOT"]) == portdb.aux_get(pkg, ["SLOT"]):
- oldver = x
- if oldver == None:
- raise ValueError("could not find old version for package %s" % pkg)
- oldver = oldver[len(portage.cpv_getkey(oldver))+1:]
- sys.stdout.write(" " + pkg + " (" + oldver + ")\n")
+ if not myglsa.isVulnerable():
+ sys.stdout.write(">>> no vulnerable packages installed\n")
else:
- sys.stdout.write("Nothing to do for this GLSA\n")
+ mergedict = {}
+ for (vuln, update) in myglsa.getAffectionTable(least_change=least_change):
+ mergedict.setdefault(update, []).append(vuln)
+
+ sys.stdout.write(">>> The following updates will be performed for this GLSA:\n")
+ for pkg in mergedict:
+ if pkg != "":
+ sys.stdout.write(" " + pkg + " (vulnerable: " + ", ".join(mergedict[pkg]) + ")\n")
+ if "" in mergedict:
+ sys.stdout.write("\n>>> For the following packages, no upgrade path exists:\n")
+ sys.stdout.write(" " + ", ".join(mergedict[""]))
elif mode == "inject":
sys.stdout.write("injecting " + myid + "\n")
myglsa.inject()
@@ -268,9 +283,9 @@ if mode == "test":
# mail mode as requested by solar
if mode == "mail":
import portage.mail, socket
- from io import StringIO
+ from io import BytesIO
from email.mime.text import MIMEText
-
+
# color doesn't make any sense for mail
nocolor()
@@ -278,7 +293,7 @@ if mode == "mail":
myrecipient = portage.settings["PORTAGE_ELOG_MAILURI"].split()[0]
else:
myrecipient = "root@localhost"
-
+
if "PORTAGE_ELOG_MAILFROM" in portage.settings:
myfrom = portage.settings["PORTAGE_ELOG_MAILFROM"]
else:
@@ -287,11 +302,13 @@ if mode == "mail":
mysubject = "[glsa-check] Summary for %s" % socket.getfqdn()
# need a file object for summarylist()
- myfd = StringIO()
- myfd.write("GLSA Summary report for host %s\n" % socket.getfqdn())
- myfd.write("(Command was: %s)\n\n" % " ".join(sys.argv))
+ myfd = BytesIO()
+ line = "GLSA Summary report for host %s\n" % socket.getfqdn()
+ myfd.write(line.encode("utf-8"))
+ line = "(Command was: %s)\n\n" % " ".join(sys.argv)
+ myfd.write(line.encode("utf-8"))
summarylist(glsalist, fd1=myfd, fd2=myfd)
- summary = str(myfd.getvalue())
+ summary = myfd.getvalue().decode("utf-8")
myfd.close()
myattachments = []
@@ -302,16 +319,17 @@ if mode == "mail":
if verbose:
sys.stderr.write(("invalid GLSA: %s (error message was: %s)\n" % (myid, e)))
continue
- myfd = StringIO()
+ myfd = BytesIO()
myglsa.dump(outstream=myfd)
- myattachments.append(MIMEText(str(myfd.getvalue()), _charset="utf8"))
+ attachment = myfd.getvalue().decode("utf-8")
+ myattachments.append(MIMEText(attachment, _charset="utf8"))
myfd.close()
-
+
mymessage = portage.mail.create_message(myfrom, myrecipient, mysubject, summary, myattachments)
portage.mail.send_mail(portage.settings, mymessage)
-
+
sys.exit(0)
-
+
# something wrong here, all valid paths are covered with sys.exit()
sys.stderr.write("nothing more to do\n")
sys.exit(2)
diff --git a/bin/helper-functions.sh b/bin/helper-functions.sh
index c7400fa4b..b9bc74a2e 100644
--- a/bin/helper-functions.sh
+++ b/bin/helper-functions.sh
@@ -10,42 +10,45 @@ source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}"/isolated-functions.sh
#
# API functions for doing parallel processing
#
-numjobs() {
+makeopts_jobs() {
# Copied from eutils.eclass:makeopts_jobs()
local jobs=$(echo " ${MAKEOPTS} " | \
sed -r -n 's:.*[[:space:]](-j|--jobs[=[:space:]])[[:space:]]*([0-9]+).*:\2:p')
echo ${jobs:-1}
}
-multijob_init() {
+__multijob_init() {
# Setup a pipe for children to write their pids to when they finish.
- mj_control_pipe=$(mktemp -t multijob.XXXXXX)
- rm "${mj_control_pipe}"
- mkfifo "${mj_control_pipe}"
- redirect_alloc_fd mj_control_fd "${mj_control_pipe}"
- rm -f "${mj_control_pipe}"
+ # We have to allocate two fd's because POSIX has undefined behavior
+ # when you open a FIFO for simultaneous read/write. #487056
+ local pipe=$(mktemp -t multijob.XXXXXX)
+ rm -f "${pipe}"
+ mkfifo -m 600 "${pipe}"
+ __redirect_alloc_fd mj_write_fd "${pipe}"
+ __redirect_alloc_fd mj_read_fd "${pipe}"
+ rm -f "${pipe}"
# See how many children we can fork based on the user's settings.
- mj_max_jobs=$(numjobs)
+ mj_max_jobs=$(makeopts_jobs "$@")
mj_num_jobs=0
}
-multijob_child_init() {
- trap 'echo ${BASHPID} $? >&'${mj_control_fd} EXIT
+__multijob_child_init() {
+ trap 'echo ${BASHPID:-$(__bashpid)} $? >&'${mj_write_fd} EXIT
trap 'exit 1' INT TERM
}
-multijob_finish_one() {
+__multijob_finish_one() {
local pid ret
- read -r -u ${mj_control_fd} pid ret
+ read -r -u ${mj_read_fd} pid ret
: $(( --mj_num_jobs ))
return ${ret}
}
-multijob_finish() {
+__multijob_finish() {
local ret=0
while [[ ${mj_num_jobs} -gt 0 ]] ; do
- multijob_finish_one
+ __multijob_finish_one
: $(( ret |= $? ))
done
# Let bash clean up its internal child tracking state.
@@ -53,38 +56,42 @@ multijob_finish() {
return ${ret}
}
-multijob_post_fork() {
+__multijob_post_fork() {
: $(( ++mj_num_jobs ))
if [[ ${mj_num_jobs} -ge ${mj_max_jobs} ]] ; then
- multijob_finish_one
+ __multijob_finish_one
fi
return $?
}
-# @FUNCTION: redirect_alloc_fd
+# @FUNCTION: __redirect_alloc_fd
# @USAGE: <var> <file> [redirection]
# @DESCRIPTION:
# Find a free fd and redirect the specified file via it. Store the new
# fd in the specified variable. Useful for the cases where we don't care
# about the exact fd #.
-redirect_alloc_fd() {
+__redirect_alloc_fd() {
local var=$1 file=$2 redir=${3:-"<>"}
if [[ $(( (BASH_VERSINFO[0] << 8) + BASH_VERSINFO[1] )) -ge $(( (4 << 8) + 1 )) ]] ; then
- # Newer bash provides this functionality.
- eval "exec {${var}}${redir}'${file}'"
+ # Newer bash provides this functionality.
+ eval "exec {${var}}${redir}'${file}'"
else
- # Need to provide the functionality ourselves.
- local fd=10
- while :; do
- # Make sure the fd isn't open. It could be a char device,
- # or a symlink (possibly broken) to something else.
- if [[ ! -e /dev/fd/${fd} ]] && [[ ! -L /dev/fd/${fd} ]] ; then
- eval "exec ${fd}${redir}'${file}'" && break
- fi
- [[ ${fd} -gt 1024 ]] && die "redirect_alloc_fd failed"
- : $(( ++fd ))
- done
- : $(( ${var} = fd ))
+ # Need to provide the functionality ourselves.
+ local fd=10
+ local fddir=/dev/fd
+ # Prefer /proc/self/fd if available (/dev/fd
+ # doesn't work on solaris, see bug #474536).
+ [[ -d /proc/self/fd ]] && fddir=/proc/self/fd
+ while :; do
+ # Make sure the fd isn't open. It could be a char device,
+ # or a symlink (possibly broken) to something else.
+ if [[ ! -e ${fddir}/${fd} ]] && [[ ! -L ${fddir}/${fd} ]] ; then
+ eval "exec ${fd}${redir}'${file}'" && break
+ fi
+ [[ ${fd} -gt 1024 ]] && die 'could not locate a free temp fd !?'
+ : $(( ++fd ))
+ done
+ : $(( ${var} = fd ))
fi
}
diff --git a/bin/install.py b/bin/install.py
new file mode 100755
index 000000000..3c5e0de65
--- /dev/null
+++ b/bin/install.py
@@ -0,0 +1,253 @@
+#!/usr/bin/python -b
+# Copyright 2013-2014 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+import os
+import stat
+import sys
+import subprocess
+import traceback
+
+import portage
+from portage.util._argparse import ArgumentParser
+from portage.util.movefile import _copyxattr
+from portage.exception import OperationNotSupported
+
+# Change back to original cwd _after_ all imports (bug #469338).
+os.chdir(os.environ["__PORTAGE_HELPER_CWD"])
+
+def parse_args(args):
+ """
+ Parse the command line arguments using optparse for python 2.6 compatibility
+ Args:
+ args: a list of the white space delimited command line
+ Returns:
+ tuple of the Namespace of parsed options, and a list of order parameters
+ """
+ parser = ArgumentParser(add_help=False)
+
+ parser.add_argument(
+ "-b",
+ action="store_true",
+ dest="shortopt_b"
+ )
+ parser.add_argument(
+ "--backup",
+ action="store",
+ dest="backup"
+ )
+ parser.add_argument(
+ "-c",
+ action="store_true",
+ dest="shortopt_c"
+ )
+ parser.add_argument(
+ "--compare",
+ "-C",
+ action="store_true",
+ dest="compare"
+ )
+ parser.add_argument(
+ "--directory",
+ "-d",
+ action="store_true",
+ dest="directory"
+ )
+ parser.add_argument(
+ "-D",
+ action="store_true",
+ dest="shortopt_D"
+ )
+ parser.add_argument(
+ "--owner",
+ "-o",
+ action="store",
+ dest="owner"
+ )
+ parser.add_argument(
+ "--group",
+ "-g",
+ action="store",
+ dest="group"
+ )
+ parser.add_argument(
+ "--mode",
+ "-m",
+ action="store",
+ dest="mode"
+ )
+ parser.add_argument(
+ "--preserve-timestamps",
+ "-p",
+ action="store_true",
+ dest="preserve_timestamps"
+ )
+ parser.add_argument(
+ "--strip",
+ "-s",
+ action="store_true",
+ dest="strip"
+ )
+ parser.add_argument(
+ "--strip-program",
+ action="store",
+ dest="strip_program"
+ )
+ parser.add_argument(
+ "--suffix",
+ "-S",
+ action="store",
+ dest="suffix"
+ )
+ parser.add_argument(
+ "--target-directory",
+ "-t",
+ action="store",
+ dest="target_directory"
+ )
+ parser.add_argument(
+ "--no-target-directory",
+ "-T",
+ action="store_true",
+ dest="no_target_directory"
+ )
+ parser.add_argument(
+ "--context",
+ "-Z",
+ action="store",
+ dest="context"
+ )
+ parser.add_argument(
+ "--verbose",
+ "-v",
+ action="store_true",
+ dest="verbose"
+ )
+ parser.add_argument(
+ "--help",
+ action="store_true",
+ dest="help"
+ )
+ parser.add_argument(
+ "--version",
+ action="store_true",
+ dest="version"
+ )
+
+ # Use parse_known_args for maximum compatibility with
+ # getopt handling of non-option file arguments. Note
+ # that parser.add_argument("files", nargs='+') would
+ # be subtly incompatible because it requires that all
+ # of the file arguments be grouped sequentially. Also
+ # note that we have to explicitly call add_argument
+ # for known options in order for argparse to correctly
+ # separate option arguments from file arguments in all
+ # cases (it also allows for optparse compatibility).
+ parsed_args = parser.parse_known_args()
+
+ opts = parsed_args[0]
+ files = parsed_args[1]
+ files = [f for f in files if f != "--"] # filter out "--"
+
+ return (opts, files)
+
+
+def copy_xattrs(opts, files):
+ """
+ Copy the extended attributes using portage.util.movefile._copyxattr
+ Args:
+ opts: Namespace of the parsed command line otions
+ files: list of ordered command line parameters which should be files/directories
+ Returns:
+ system exit code
+ """
+ if opts.directory or not files:
+ return os.EX_OK
+
+ if opts.target_directory is None:
+ source, target = files[:-1], files[-1]
+ target_is_directory = os.path.isdir(target)
+ else:
+ source, target = files, opts.target_directory
+ target_is_directory = True
+
+ exclude = os.environ.get("PORTAGE_XATTR_EXCLUDE", "security.* system.nfs4_acl")
+
+ try:
+ if target_is_directory:
+ for s in source:
+ abs_path = os.path.join(target, os.path.basename(s))
+ _copyxattr(s, abs_path, exclude=exclude)
+ else:
+ _copyxattr(source[0], target, exclude=exclude)
+ return os.EX_OK
+
+ except OperationNotSupported:
+ traceback.print_exc()
+ return os.EX_OSERR
+
+
+def Which(filename, path=None, exclude=None):
+ """
+ Find the absolute path of 'filename' in a given search 'path'
+ Args:
+ filename: basename of the file
+ path: colon delimited search path
+ exclude: path of file to exclude
+ """
+ if path is None:
+ path = os.environ.get('PATH', '')
+
+ if exclude is not None:
+ st = os.stat(exclude)
+ exclude = (st.st_ino, st.st_dev)
+
+ for p in path.split(':'):
+ p = os.path.join(p, filename)
+ if os.access(p, os.X_OK):
+ try:
+ st = os.stat(p)
+ except OSError:
+ # file disappeared?
+ pass
+ else:
+ if stat.S_ISREG(st.st_mode) and \
+ (exclude is None or exclude != (st.st_ino, st.st_dev)):
+ return p
+
+ return None
+
+
+def main(args):
+ opts, files = parse_args(args)
+ install_binary = Which('install', exclude=os.environ["__PORTAGE_HELPER_PATH"])
+ if install_binary is None:
+ sys.stderr.write("install: command not found\n")
+ return 127
+
+ cmdline = [install_binary]
+ cmdline += args
+
+ if sys.hexversion >= 0x3000000:
+ # We can't trust that the filesystem encoding (locale dependent)
+ # correctly matches the arguments, so use surrogateescape to
+ # pass through the original argv bytes for Python 3.
+ fs_encoding = sys.getfilesystemencoding()
+ cmdline = [x.encode(fs_encoding, 'surrogateescape') for x in cmdline]
+ files = [x.encode(fs_encoding, 'surrogateescape') for x in files]
+ if opts.target_directory is not None:
+ opts.target_directory = \
+ opts.target_directory.encode(fs_encoding, 'surrogateescape')
+
+ returncode = subprocess.call(cmdline)
+ if returncode == os.EX_OK:
+ returncode = copy_xattrs(opts, files)
+ if returncode != os.EX_OK:
+ portage.util.writemsg("!!! install: copy_xattrs failed with the "
+ "following arguments: %s\n" %
+ " ".join(portage._shell_quote(x) for x in args), noiselevel=-1)
+ return returncode
+
+
+if __name__ == "__main__":
+ sys.exit(main(sys.argv[1:]))
diff --git a/bin/isolated-functions.sh b/bin/isolated-functions.sh
index dbf988b28..a22af574a 100644
--- a/bin/isolated-functions.sh
+++ b/bin/isolated-functions.sh
@@ -1,7 +1,9 @@
#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
+# Copyright 1999-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
+source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}/eapi.sh"
+
# We need this next line for "die" and "assert". It expands
# It _must_ preceed all the calls to die and assert.
shopt -s expand_aliases
@@ -15,7 +17,7 @@ assert() {
done
}
-assert_sigpipe_ok() {
+__assert_sigpipe_ok() {
# When extracting a tar file like this:
#
# bzip2 -dc foo.tar.bz2 | tar xof -
@@ -43,21 +45,21 @@ assert_sigpipe_ok() {
shopt -s extdebug
-# dump_trace([number of funcs on stack to skip],
+# __dump_trace([number of funcs on stack to skip],
# [whitespacing for filenames],
# [whitespacing for line numbers])
-dump_trace() {
+__dump_trace() {
local funcname="" sourcefile="" lineno="" s="yes" n p
declare -i strip=${1:-1}
local filespacing=$2 linespacing=$3
- # The qa_call() function and anything before it are portage internals
+ # The __qa_call() function and anything before it are portage internals
# that the user will not be interested in. Therefore, the stack trace
- # should only show calls that come after qa_call().
+ # should only show calls that come after __qa_call().
(( n = ${#FUNCNAME[@]} - 1 ))
(( p = ${#BASH_ARGV[@]} ))
while (( n > 0 )) ; do
- [ "${FUNCNAME[${n}]}" == "qa_call" ] && break
+ [ "${FUNCNAME[${n}]}" == "__qa_call" ] && break
(( p -= ${BASH_ARGC[${n}]} ))
(( n-- ))
done
@@ -86,7 +88,7 @@ dump_trace() {
}
nonfatal() {
- if has "${EAPI:-0}" 0 1 2 3 3_pre2 ; then
+ if ! ___eapi_has_nonfatal; then
die "$FUNCNAME() not supported in this EAPI"
fi
if [[ $# -lt 1 ]]; then
@@ -96,18 +98,24 @@ nonfatal() {
PORTAGE_NONFATAL=1 "$@"
}
-helpers_die() {
- case "${EAPI:-0}" in
- 0|1|2|3)
- echo -e "$@" >&2
- ;;
- *)
- die "$@"
- ;;
- esac
+__bashpid() {
+ # The BASHPID variable is new to bash-4.0, so add a hack for older
+ # versions. This must be used like so:
+ # ${BASHPID:-$(__bashpid)}
+ sh -c 'echo ${PPID}'
+}
+
+__helpers_die() {
+ if ___eapi_helpers_can_die; then
+ die "$@"
+ else
+ echo -e "$@" >&2
+ fi
}
die() {
+ local IFS=$' \t\n'
+
if [[ $PORTAGE_NONFATAL -eq 1 ]]; then
echo -e " $WARN*$NORMAL ${FUNCNAME[1]}: WARNING: $@" >&2
return 1
@@ -124,7 +132,7 @@ die() {
# setup spacing to make output easier to read
(( n = ${#FUNCNAME[@]} - 1 ))
while (( n > 0 )) ; do
- [ "${FUNCNAME[${n}]}" == "qa_call" ] && break
+ [ "${FUNCNAME[${n}]}" == "__qa_call" ] && break
(( n-- ))
done
(( n == 0 )) && (( n = ${#FUNCNAME[@]} - 1 ))
@@ -140,14 +148,14 @@ die() {
# get a stack trace, so at least report the phase that failed.
local phase_str=
[[ -n $EBUILD_PHASE ]] && phase_str=" ($EBUILD_PHASE phase)"
- eerror "ERROR: $CATEGORY/$PF failed${phase_str}:"
+ eerror "ERROR: ${CATEGORY}/${PF}::${PORTAGE_REPO_NAME} failed${phase_str}:"
eerror " ${*:-(no error message)}"
eerror
- # dump_trace is useless when the main script is a helper binary
+ # __dump_trace is useless when the main script is a helper binary
local main_index
(( main_index = ${#BASH_SOURCE[@]} - 1 ))
if has ${BASH_SOURCE[$main_index]##*/} ebuild.sh misc-functions.sh ; then
- dump_trace 2 ${filespacing} ${linespacing}
+ __dump_trace 2 ${filespacing} ${linespacing}
eerror " $(printf "%${filespacing}s" "${BASH_SOURCE[1]##*/}"), line $(printf "%${linespacing}s" "${BASH_LINENO[0]}"): Called die"
eerror "The specific snippet of code:"
# This scans the file that called die and prints out the logic that
@@ -173,39 +181,12 @@ die() {
| while read -r n ; do eerror " ${n#RETAIN-LEADING-SPACE}" ; done
eerror
fi
- eerror "If you need support, post the output of \`emerge --info '=$CATEGORY/$PF'\`,"
- eerror "the complete build log and the output of \`emerge -pqv '=$CATEGORY/$PF'\`."
- if [[ -n ${EBUILD_OVERLAY_ECLASSES} ]] ; then
- eerror "This ebuild used the following eclasses from overlays:"
- local x
- for x in ${EBUILD_OVERLAY_ECLASSES} ; do
- eerror " ${x}"
- done
- fi
- if [ "${EMERGE_FROM}" != "binary" ] && \
- ! has ${EBUILD_PHASE} prerm postrm && \
- [ "${EBUILD#${PORTDIR}/}" == "${EBUILD}" ] ; then
- local overlay=${EBUILD%/*}
- overlay=${overlay%/*}
- overlay=${overlay%/*}
- if [[ -n $PORTAGE_REPO_NAME ]] ; then
- eerror "This ebuild is from an overlay named" \
- "'$PORTAGE_REPO_NAME': '${overlay}/'"
- else
- eerror "This ebuild is from an overlay: '${overlay}/'"
- fi
- elif [[ -n $PORTAGE_REPO_NAME && -f "$PORTDIR"/profiles/repo_name ]] ; then
- local portdir_repo_name=$(<"$PORTDIR"/profiles/repo_name)
- if [[ -n $portdir_repo_name && \
- $portdir_repo_name != $PORTAGE_REPO_NAME ]] ; then
- eerror "This ebuild is from a repository" \
- "named '$PORTAGE_REPO_NAME'"
- fi
- fi
+ eerror "If you need support, post the output of \`emerge --info '=${CATEGORY}/${PF}::${PORTAGE_REPO_NAME}'\`,"
+ eerror "the complete build log and the output of \`emerge -pqv '=${CATEGORY}/${PF}::${PORTAGE_REPO_NAME}'\`."
# Only call die hooks here if we are executed via ebuild.sh or
# misc-functions.sh, since those are the only cases where the environment
- # contains the hook functions. When necessary (like for helpers_die), die
+ # contains the hook functions. When necessary (like for __helpers_die), die
# hooks are automatically called later by a misc-functions.sh invocation.
if has ${BASH_SOURCE[$main_index]##*/} ebuild.sh misc-functions.sh && \
[[ ${EBUILD_PHASE} != depend ]] ; then
@@ -218,7 +199,8 @@ die() {
if [[ -n ${PORTAGE_LOG_FILE} ]] ; then
eerror "The complete build log is located at '${PORTAGE_LOG_FILE}'."
- if [[ ${PORTAGE_LOG_FILE} != ${T}/* ]] ; then
+ if [[ ${PORTAGE_LOG_FILE} != ${T}/* ]] && \
+ ! has fail-clean ${FEATURES} ; then
# Display path to symlink in ${T}, as requested in bug #412865.
local log_ext=log
[[ ${PORTAGE_LOG_FILE} != *.log ]] && log_ext+=.${PORTAGE_LOG_FILE##*.}
@@ -241,26 +223,20 @@ die() {
[[ -n $PORTAGE_IPC_DAEMON ]] && "$PORTAGE_BIN_PATH"/ebuild-ipc exit 1
# subshell die support
- [[ $BASHPID = $EBUILD_MASTER_PID ]] || kill -s SIGTERM $EBUILD_MASTER_PID
+ [[ ${BASHPID:-$(__bashpid)} == ${EBUILD_MASTER_PID} ]] || kill -s SIGTERM ${EBUILD_MASTER_PID}
exit 1
}
-# We need to implement diefunc() since environment.bz2 files contain
-# calls to it (due to alias expansion).
-diefunc() {
- die "${@}"
-}
-
-quiet_mode() {
+__quiet_mode() {
[[ ${PORTAGE_QUIET} -eq 1 ]]
}
-vecho() {
- quiet_mode || echo "$@"
+__vecho() {
+ __quiet_mode || echo "$@"
}
# Internal logging function, don't use this in ebuilds
-elog_base() {
+__elog_base() {
local messagetype
[ -z "${1}" -o -z "${T}" -o ! -d "${T}/logging" ] && return 1
case "${1}" in
@@ -269,7 +245,7 @@ elog_base() {
shift
;;
*)
- vecho -e " ${BAD}*${NORMAL} Invalid use of internal function elog_base(), next message will not be logged"
+ __vecho -e " ${BAD}*${NORMAL} Invalid use of internal function __elog_base(), next message will not be logged"
return 1
;;
esac
@@ -281,17 +257,17 @@ elog_base() {
}
eqawarn() {
- elog_base QA "$*"
+ __elog_base QA "$*"
[[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo
echo -e "$@" | while read -r ; do
- vecho " $WARN*$NORMAL $REPLY" >&2
+ __vecho " $WARN*$NORMAL $REPLY" >&2
done
LAST_E_CMD="eqawarn"
return 0
}
elog() {
- elog_base LOG "$*"
+ __elog_base LOG "$*"
[[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo
echo -e "$@" | while read -r ; do
echo " $GOOD*$NORMAL $REPLY"
@@ -300,26 +276,8 @@ elog() {
return 0
}
-esyslog() {
- local pri=
- local tag=
-
- if [ -x /usr/bin/logger ]
- then
- pri="$1"
- tag="$2"
-
- shift 2
- [ -z "$*" ] && return 0
-
- /usr/bin/logger -p "${pri}" -t "${tag}" -- "$*"
- fi
-
- return 0
-}
-
einfo() {
- elog_base INFO "$*"
+ __elog_base INFO "$*"
[[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo
echo -e "$@" | while read -r ; do
echo " $GOOD*$NORMAL $REPLY"
@@ -329,7 +287,7 @@ einfo() {
}
einfon() {
- elog_base INFO "$*"
+ __elog_base INFO "$*"
[[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo
echo -ne " ${GOOD}*${NORMAL} $*"
LAST_E_CMD="einfon"
@@ -337,7 +295,7 @@ einfon() {
}
ewarn() {
- elog_base WARN "$*"
+ __elog_base WARN "$*"
[[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo
echo -e "$@" | while read -r ; do
echo " $WARN*$NORMAL $RC_INDENTATION$REPLY" >&2
@@ -347,7 +305,7 @@ ewarn() {
}
eerror() {
- elog_base ERROR "$*"
+ __elog_base ERROR "$*"
[[ ${RC_ENDCOL} != "yes" && ${LAST_E_CMD} == "ebegin" ]] && echo
echo -e "$@" | while read -r ; do
echo " $BAD*$NORMAL $RC_INDENTATION$REPLY" >&2
@@ -372,7 +330,7 @@ ebegin() {
return 0
}
-_eend() {
+__eend() {
local retval=${1:-0} efunc=${2:-eerror} msg
shift 2
@@ -399,13 +357,13 @@ eend() {
local retval=${1:-0}
shift
- _eend ${retval} eerror "$*"
+ __eend ${retval} eerror "$*"
LAST_E_CMD="eend"
return ${retval}
}
-unset_colors() {
+__unset_colors() {
COLS=80
ENDCOL=
@@ -417,7 +375,7 @@ unset_colors() {
BRACKET=
}
-set_colors() {
+__set_colors() {
COLS=${COLUMNS:-0} # bash's internal COLUMNS variable
# Avoid wasteful stty calls during the "depend" phases.
# If stdout is a pipe, the parent process can export COLUMNS
@@ -450,10 +408,10 @@ RC_DOT_PATTERN=''
case "${NOCOLOR:-false}" in
yes|true)
- unset_colors
+ __unset_colors
;;
no|false)
- set_colors
+ __set_colors
;;
esac
@@ -504,4 +462,24 @@ has() {
return 1
}
+__repo_attr() {
+ local appropriate_section=0 exit_status=1 line saved_extglob_shopt=$(shopt -p extglob)
+ shopt -s extglob
+ while read line; do
+ [[ ${appropriate_section} == 0 && ${line} == "[$1]" ]] && appropriate_section=1 && continue
+ [[ ${appropriate_section} == 1 && ${line} == "["*"]" ]] && appropriate_section=0 && continue
+ # If a conditional expression like [[ ${line} == $2*( )=* ]] is used
+ # then bash-3.2 produces an error like the following when the file is
+ # sourced: syntax error in conditional expression: unexpected token `('
+ # Therefore, use a regular expression for compatibility.
+ if [[ ${appropriate_section} == 1 && ${line} =~ ^${2}[[:space:]]*= ]]; then
+ echo "${line##$2*( )=*( )}"
+ exit_status=0
+ break
+ fi
+ done <<< "${PORTAGE_REPOSITORIES}"
+ eval "${saved_extglob_shopt}"
+ return ${exit_status}
+}
+
true
diff --git a/bin/lock-helper.py b/bin/lock-helper.py
index dfb887669..aa2dd60fa 100755
--- a/bin/lock-helper.py
+++ b/bin/lock-helper.py
@@ -1,11 +1,12 @@
-#!/usr/bin/python
-# Copyright 2010-2011 Gentoo Foundation
+#!/usr/bin/python -b
+# Copyright 2010-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
import os
import sys
sys.path.insert(0, os.environ['PORTAGE_PYM_PATH'])
import portage
+portage._internal_caller = True
portage._disable_legacy_globals()
def main(args):
diff --git a/bin/misc-functions.sh b/bin/misc-functions.sh
index 9eec8bb69..5ccf7c224 100755
--- a/bin/misc-functions.sh
+++ b/bin/misc-functions.sh
@@ -1,5 +1,5 @@
#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
+# Copyright 1999-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
#
# Miscellaneous shell functions that make use of the ebuild env but don't need
@@ -17,8 +17,9 @@ shift $#
source "${PORTAGE_BIN_PATH:-/usr/lib/portage/bin}/ebuild.sh"
install_symlink_html_docs() {
- [[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) local ED=${D} ;; esac
+ if ! ___eapi_has_prefix_variables; then
+ local ED=${D}
+ fi
cd "${ED}" || die "cd failed"
#symlink the html documentation (if DOC_SYMLINKS_DIR is set in make.conf)
if [ -n "${DOC_SYMLINKS_DIR}" ] ; then
@@ -30,10 +31,10 @@ install_symlink_html_docs() {
done
if [ -n "${mydocdir}" ] ; then
local mysympath
- if [ -z "${SLOT}" -o "${SLOT}" = "0" ] ; then
+ if [ -z "${SLOT}" -o "${SLOT%/*}" = "0" ] ; then
mysympath="${DOC_SYMLINKS_DIR}/${CATEGORY}/${PN}"
else
- mysympath="${DOC_SYMLINKS_DIR}/${CATEGORY}/${PN}-${SLOT}"
+ mysympath="${DOC_SYMLINKS_DIR}/${CATEGORY}/${PN}-${SLOT%/*}"
fi
einfo "Symlinking ${mysympath} to the HTML documentation"
dodir "${DOC_SYMLINKS_DIR}/${CATEGORY}"
@@ -43,7 +44,20 @@ install_symlink_html_docs() {
}
# replacement for "readlink -f" or "realpath"
+READLINK_F_WORKS=""
canonicalize() {
+ if [[ -z ${READLINK_F_WORKS} ]] ; then
+ if [[ $(readlink -f -- /../ 2>/dev/null) == "/" ]] ; then
+ READLINK_F_WORKS=true
+ else
+ READLINK_F_WORKS=false
+ fi
+ fi
+ if ${READLINK_F_WORKS} ; then
+ readlink -f -- "$@"
+ return
+ fi
+
local f=$1 b n=10 wd=$(pwd)
while (( n-- > 0 )); do
while [[ ${f: -1} = / && ${#f} -gt 1 ]]; do
@@ -66,8 +80,9 @@ canonicalize() {
prepcompress() {
local -a include exclude incl_d incl_f
local f g i real_f real_d
- [[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) local ED=${D} ;; esac
+ if ! ___eapi_has_prefix_variables; then
+ local ED=${D}
+ fi
# Canonicalize path names and check for their existence.
real_d=$(canonicalize "${ED}")
@@ -141,7 +156,7 @@ prepcompress() {
# Queue up for compression.
# ecompress{,dir} doesn't like to be called with empty argument lists.
- [[ ${#incl_d[@]} -gt 0 ]] && ecompressdir --queue "${incl_d[@]}"
+ [[ ${#incl_d[@]} -gt 0 ]] && ecompressdir --limit ${PORTAGE_DOCOMPRESS_SIZE_LIMIT:-0} --queue "${incl_d[@]}"
[[ ${#incl_f[@]} -gt 0 ]] && ecompress --queue "${incl_f[@]/#/${ED}}"
[[ ${#exclude[@]} -gt 0 ]] && ecompressdir --ignore "${exclude[@]}"
return 0
@@ -149,13 +164,12 @@ prepcompress() {
install_qa_check() {
local f i qa_var x
- [[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) local EPREFIX= ED=${D} ;; esac
+ if ! ___eapi_has_prefix_variables; then
+ local EPREFIX= ED=${D}
+ fi
cd "${ED}" || die "cd failed"
- # Merge QA_FLAGS_IGNORED and QA_DT_HASH into a single array, since
- # QA_DT_HASH is deprecated.
qa_var="QA_FLAGS_IGNORED_${ARCH/-/_}"
eval "[[ -n \${!qa_var} ]] && QA_FLAGS_IGNORED=(\"\${${qa_var}[@]}\")"
if [[ ${#QA_FLAGS_IGNORED[@]} -eq 1 ]] ; then
@@ -166,29 +180,6 @@ install_qa_check() {
set -${shopts}
fi
- qa_var="QA_DT_HASH_${ARCH/-/_}"
- eval "[[ -n \${!qa_var} ]] && QA_DT_HASH=(\"\${${qa_var}[@]}\")"
- if [[ ${#QA_DT_HASH[@]} -eq 1 ]] ; then
- local shopts=$-
- set -o noglob
- QA_DT_HASH=(${QA_DT_HASH})
- set +o noglob
- set -${shopts}
- fi
-
- if [[ -n ${QA_DT_HASH} ]] ; then
- QA_FLAGS_IGNORED=("${QA_FLAGS_IGNORED[@]}" "${QA_DT_HASH[@]}")
- unset QA_DT_HASH
- fi
-
- # Merge QA_STRICT_FLAGS_IGNORED and QA_STRICT_DT_HASH, since
- # QA_STRICT_DT_HASH is deprecated
- if [ "${QA_STRICT_FLAGS_IGNORED-unset}" = unset ] && \
- [ "${QA_STRICT_DT_HASH-unset}" != unset ] ; then
- QA_STRICT_FLAGS_IGNORED=1
- unset QA_STRICT_DT_HASH
- fi
-
# Check for files built without respecting *FLAGS. Note that
# -frecord-gcc-switches must be in all *FLAGS variables, in
# order to avoid false positive results here.
@@ -200,8 +191,7 @@ install_qa_check() {
[[ "${FFLAGS}" == *-frecord-gcc-switches* ]] && \
[[ "${FCFLAGS}" == *-frecord-gcc-switches* ]] ; then
rm -f "${T}"/scanelf-ignored-CFLAGS.log
- for x in $(scanelf -qyRF '%k %p' -k \!.GCC.command.line "${ED}" | \
- sed -e "s:\!.GCC.command.line ::") ; do
+ for x in $(scanelf -qyRF '#k%p' -k '!.GCC.command.line' "${ED}") ; do
# Separate out file types that are known to support
# .GCC.command.line sections, using the `file` command
# similar to how prepstrip uses it.
@@ -226,11 +216,11 @@ install_qa_check() {
-i "${T}"/scanelf-ignored-CFLAGS.log
f=$(<"${T}"/scanelf-ignored-CFLAGS.log)
if [[ -n ${f} ]] ; then
- vecho -ne '\n'
+ __vecho -ne '\n'
eqawarn "${BAD}QA Notice: Files built without respecting CFLAGS have been detected${NORMAL}"
eqawarn " Please include the following list of files in your report:"
eqawarn "${f}"
- vecho -ne '\n'
+ __vecho -ne '\n'
sleep 1
else
rm -f "${T}"/scanelf-ignored-CFLAGS.log
@@ -240,7 +230,7 @@ install_qa_check() {
export STRIP_MASK
prepall
- has "${EAPI}" 0 1 2 3 || prepcompress
+ ___eapi_has_docompress && prepcompress
ecompressdir --dequeue
ecompress --dequeue
@@ -251,32 +241,50 @@ install_qa_check() {
for x in etc/app-defaults usr/man usr/info usr/X11R6 usr/doc usr/locale ; do
[[ -d ${ED}/$x ]] && f+=" $x\n"
done
-
if [[ -n $f ]] ; then
eqawarn "QA Notice: This ebuild installs into the following deprecated directories:"
eqawarn
eqawarn "$f"
fi
- if [[ -d ${ED}/etc/udev/rules.d ]] ; then
- f=
- for x in $(ls "${ED}/etc/udev/rules.d") ; do
- f+=" etc/udev/rules.d/$x\n"
- done
- if [[ -n $f ]] ; then
- eqawarn "QA Notice: udev rules should be installed in /lib/udev/rules.d:"
- eqawarn
- eqawarn "$f"
+ # It's ok create these directories, but not to install into them. #493154
+ # TODO: We should add var/lib to this list.
+ f=
+ for x in var/cache var/lock var/run run ; do
+ if [[ ! -L ${ED}/${x} && -d ${ED}/${x} ]] ; then
+ if [[ -z $(find "${ED}/${x}" -prune -empty) ]] ; then
+ f+=$(cd "${ED}"; find "${x}" -printf ' %p\n')
+ fi
fi
+ done
+ if [[ -n ${f} ]] ; then
+ eqawarn "QA Notice: This ebuild installs into paths that should be created at runtime."
+ eqawarn " To fix, simply do not install into these directories. Instead, your package"
+ eqawarn " should create dirs on the fly at runtime as needed via init scripts/etc..."
+ eqawarn
+ eqawarn "${f}"
+ fi
+
+ set +f
+ f=
+ for x in "${ED}etc/udev/rules.d/"* "${ED}lib"*"/udev/rules.d/"* ; do
+ [[ -e ${x} ]] || continue
+ [[ ${x} == ${ED}lib/udev/rules.d/* ]] && continue
+ f+=" ${x#${ED}}\n"
+ done
+ if [[ -n $f ]] ; then
+ eqawarn "QA Notice: udev rules should be installed in /lib/udev/rules.d:"
+ eqawarn
+ eqawarn "$f"
fi
# Now we look for all world writable files.
local unsafe_files=$(find "${ED}" -type f -perm -2 | sed -e "s:^${ED}:- :")
if [[ -n ${unsafe_files} ]] ; then
- vecho "QA Security Notice: world writable file(s):"
- vecho "${unsafe_files}"
- vecho "- This may or may not be a security problem, most of the time it is one."
- vecho "- Please double check that $PF really needs a world writeable bit and file bugs accordingly."
+ __vecho "QA Security Notice: world writable file(s):"
+ __vecho "${unsafe_files}"
+ __vecho "- This may or may not be a security problem, most of the time it is one."
+ __vecho "- Please double check that $PF really needs a world writeable bit and file bugs accordingly."
sleep 1
fi
@@ -307,7 +315,7 @@ install_qa_check() {
for l in $(echo "${rpath_files}" | grep -E ":${dir}|::|: "); do
f+=" ${l%%:*}\n"
if ! has stricter ${FEATURES}; then
- vecho "Auto fixing rpaths for ${l%%:*}"
+ __vecho "Auto fixing rpaths for ${l%%:*}"
TMPDIR="${dir}" scanelf -BXr "${l%%:*}" -o /dev/null
fi
done
@@ -321,12 +329,12 @@ install_qa_check() {
# Print QA notice.
if [[ -n ${f}${x} ]] ; then
- vecho -ne '\n'
+ __vecho -ne '\n'
eqawarn "QA Notice: The following files contain insecure RUNPATHs"
eqawarn " Please file a bug about this at http://bugs.gentoo.org/"
eqawarn " with the maintaining herd of the package."
eqawarn "${f}${f:+${x:+\n}}${x}"
- vecho -ne '\n'
+ __vecho -ne '\n'
if [[ -n ${x} ]] || has stricter ${FEATURES} ; then
insecure_rpath=1
fi
@@ -344,7 +352,7 @@ install_qa_check() {
f=$(scanelf -qyRF '%t %p' "${ED}" | grep -v 'usr/lib/debug/')
if [[ -n ${f} ]] ; then
scanelf -qyRAF '%T %p' "${PORTAGE_BUILDDIR}"/ &> "${T}"/scanelf-textrel.log
- vecho -ne '\n'
+ __vecho -ne '\n'
eqawarn "QA Notice: The following files contain runtime text relocations"
eqawarn " Text relocations force the dynamic linker to perform extra"
eqawarn " work at startup, waste system resources, and may pose a security"
@@ -353,7 +361,7 @@ install_qa_check() {
eqawarn " For more information, see http://hardened.gentoo.org/pic-fix-guide.xml"
eqawarn " Please include the following list of files in your report:"
eqawarn "${f}"
- vecho -ne '\n'
+ __vecho -ne '\n'
die_msg="${die_msg} textrels,"
sleep 1
fi
@@ -364,7 +372,7 @@ install_qa_check() {
*-linux-gnu*)
# Check for files with executable stacks, but only on arches which
# are supported at the moment. Keep this list in sync with
- # http://hardened.gentoo.org/gnu-stack.xml (Arch Status)
+ # http://www.gentoo.org/proj/en/hardened/gnu-stack.xml (Arch Status)
case ${CTARGET:-${CHOST}} in
arm*|i?86*|ia64*|m68k*|s390*|sh*|x86_64*)
# Allow devs to mark things as ignorable ... e.g. things
@@ -389,7 +397,7 @@ install_qa_check() {
if [[ -n ${f} ]] ; then
# One more pass to help devs track down the source
scanelf -qyRAF '%e %p' "${PORTAGE_BUILDDIR}"/ &> "${T}"/scanelf-execstack.log
- vecho -ne '\n'
+ __vecho -ne '\n'
eqawarn "QA Notice: The following files contain writable and executable sections"
eqawarn " Files with such sections will not work properly (or at all!) on some"
eqawarn " architectures/operating systems. A bug should be filed at"
@@ -399,15 +407,15 @@ install_qa_check() {
eqawarn " Note: Bugs should be filed for the respective maintainers"
eqawarn " of the package in question and not hardened@g.o."
eqawarn "${f}"
- vecho -ne '\n'
+ __vecho -ne '\n'
die_msg="${die_msg} execstacks"
sleep 1
fi
# Check for files built without respecting LDFLAGS
if [[ "${LDFLAGS}" == *,--hash-style=gnu* ]] && \
- ! has binchecks ${RESTRICT} ; then
- f=$(scanelf -qyRF '%k %p' -k .hash "${ED}" | sed -e "s:\.hash ::")
+ ! has binchecks ${RESTRICT} ; then
+ f=$(scanelf -qyRF '#k%p' -k .hash "${ED}")
if [[ -n ${f} ]] ; then
echo "${f}" > "${T}"/scanelf-ignored-LDFLAGS.log
if [ "${QA_STRICT_FLAGS_IGNORED-unset}" = unset ] ; then
@@ -421,11 +429,11 @@ install_qa_check() {
-i "${T}"/scanelf-ignored-LDFLAGS.log
f=$(<"${T}"/scanelf-ignored-LDFLAGS.log)
if [[ -n ${f} ]] ; then
- vecho -ne '\n'
+ __vecho -ne '\n'
eqawarn "${BAD}QA Notice: Files built without respecting LDFLAGS have been detected${NORMAL}"
eqawarn " Please include the following list of files in your report:"
eqawarn "${f}"
- vecho -ne '\n'
+ __vecho -ne '\n'
sleep 1
else
rm -f "${T}"/scanelf-ignored-LDFLAGS.log
@@ -442,7 +450,7 @@ install_qa_check() {
# Check for shared libraries lacking SONAMEs
qa_var="QA_SONAME_${ARCH/-/_}"
eval "[[ -n \${!qa_var} ]] && QA_SONAME=(\"\${${qa_var}[@]}\")"
- f=$(scanelf -ByF '%S %p' "${ED}"{,usr/}lib*/lib*.so* | gawk '$2 == "" { print }' | sed -e "s:^[[:space:]]${ED}:/:")
+ f=$(scanelf -ByF '%S %p' "${ED}"{,usr/}lib*/lib*.so* | awk '$2 == "" { print }' | sed -e "s:^[[:space:]]${ED}:/:")
if [[ -n ${f} ]] ; then
echo "${f}" > "${T}"/scanelf-missing-SONAME.log
if [[ "${QA_STRICT_SONAME-unset}" == unset ]] ; then
@@ -463,10 +471,10 @@ install_qa_check() {
sed -e "/^\$/d" -i "${T}"/scanelf-missing-SONAME.log
f=$(<"${T}"/scanelf-missing-SONAME.log)
if [[ -n ${f} ]] ; then
- vecho -ne '\n'
+ __vecho -ne '\n'
eqawarn "QA Notice: The following shared libraries lack a SONAME"
eqawarn "${f}"
- vecho -ne '\n'
+ __vecho -ne '\n'
sleep 1
else
rm -f "${T}"/scanelf-missing-SONAME.log
@@ -476,7 +484,7 @@ install_qa_check() {
# Check for shared libraries lacking NEEDED entries
qa_var="QA_DT_NEEDED_${ARCH/-/_}"
eval "[[ -n \${!qa_var} ]] && QA_DT_NEEDED=(\"\${${qa_var}[@]}\")"
- f=$(scanelf -ByF '%n %p' "${ED}"{,usr/}lib*/lib*.so* | gawk '$2 == "" { print }' | sed -e "s:^[[:space:]]${ED}:/:")
+ f=$(scanelf -ByF '%n %p' "${ED}"{,usr/}lib*/lib*.so* | awk '$2 == "" { print }' | sed -e "s:^[[:space:]]${ED}:/:")
if [[ -n ${f} ]] ; then
echo "${f}" > "${T}"/scanelf-missing-NEEDED.log
if [[ "${QA_STRICT_DT_NEEDED-unset}" == unset ]] ; then
@@ -497,10 +505,10 @@ install_qa_check() {
sed -e "/^\$/d" -i "${T}"/scanelf-missing-NEEDED.log
f=$(<"${T}"/scanelf-missing-NEEDED.log)
if [[ -n ${f} ]] ; then
- vecho -ne '\n'
+ __vecho -ne '\n'
eqawarn "QA Notice: The following shared libraries lack NEEDED entries"
eqawarn "${f}"
- vecho -ne '\n'
+ __vecho -ne '\n'
sleep 1
else
rm -f "${T}"/scanelf-missing-NEEDED.log
@@ -545,14 +553,13 @@ install_qa_check() {
die "Unsafe files found in \${D}. Portage will not install them."
fi
- if [[ -d ${D}/${D} ]] ; then
- declare -i INSTALLTOD=0
- for i in $(find "${D}/${D}/"); do
- eqawarn "QA Notice: /${i##${D}/${D}} installed in \${D}/\${D}"
+ if [[ -d ${D%/}${D} ]] ; then
+ local -i INSTALLTOD=0
+ while read -r -d $'\0' i ; do
+ eqawarn "QA Notice: /${i##${D%/}${D}} installed in \${D}/\${D}"
((INSTALLTOD++))
- done
- die "Aborting due to QA concerns: ${INSTALLTOD} files installed in ${D}/${D}"
- unset INSTALLTOD
+ done < <(find "${D%/}${D}" -print0)
+ die "Aborting due to QA concerns: ${INSTALLTOD} files installed in ${D%/}${D}"
fi
# Sanity check syntax errors in init.d scripts
@@ -563,10 +570,31 @@ install_qa_check() {
[[ -L ${i} ]] && continue
# if empty conf.d/init.d dir exists (baselayout), then i will be "/etc/conf.d/*" and not exist
[[ ! -e ${i} ]] && continue
+ if [[ ${d} == /etc/init.d && ${i} != *.sh ]] ; then
+ # skip non-shell-script for bug #451386
+ [[ $(head -n1 "${i}") =~ ^#!.*[[:space:]/](runscript|sh)$ ]] || continue
+ fi
bash -n "${i}" || die "The init.d file has syntax errors: ${i}"
done
done
+ local checkbashisms=$(type -P checkbashisms)
+ if [[ -n ${checkbashisms} ]] ; then
+ for d in /etc/init.d ; do
+ [[ -d ${ED}${d} ]] || continue
+ for i in "${ED}${d}"/* ; do
+ [[ -e ${i} ]] || continue
+ [[ -L ${i} ]] && continue
+ f=$("${checkbashisms}" -f "${i}" 2>&1)
+ [[ $? != 0 && -n ${f} ]] || continue
+ eqawarn "QA Notice: shell script appears to use non-POSIX feature(s):"
+ while read -r ;
+ do eqawarn " ${REPLY}"
+ done <<< "${f//${ED}}"
+ done
+ done
+ fi
+
# Look for leaking LDFLAGS into pkg-config files
f=$(egrep -sH '^Libs.*-Wl,(-O[012]|--hash-style)' "${ED}"/usr/*/pkgconfig/*.pc)
if [[ -n ${f} ]] ; then
@@ -577,17 +605,16 @@ install_qa_check() {
# this should help to ensure that all (most?) shared libraries are executable
# and that all libtool scripts / static libraries are not executable
local j
- for i in "${ED}"opt/*/lib{,32,64} \
- "${ED}"lib{,32,64} \
- "${ED}"usr/lib{,32,64} \
- "${ED}"usr/X11R6/lib{,32,64} ; do
+ for i in "${ED}"opt/*/lib* \
+ "${ED}"lib* \
+ "${ED}"usr/lib* ; do
[[ ! -d ${i} ]] && continue
for j in "${i}"/*.so.* "${i}"/*.so ; do
[[ ! -e ${j} ]] && continue
[[ -L ${j} ]] && continue
[[ -x ${j} ]] && continue
- vecho "making executable: ${j#${ED}}"
+ __vecho "making executable: ${j#${ED}}"
chmod +x "${j}"
done
@@ -595,7 +622,7 @@ install_qa_check() {
[[ ! -e ${j} ]] && continue
[[ -L ${j} ]] && continue
[[ ! -x ${j} ]] && continue
- vecho "removing executable bit: ${j#${ED}}"
+ __vecho "removing executable bit: ${j#${ED}}"
chmod -x "${j}"
done
@@ -604,7 +631,7 @@ install_qa_check() {
[[ ! -L ${j} ]] && continue
linkdest=$(readlink "${j}")
if [[ ${linkdest} == /* ]] ; then
- vecho -ne '\n'
+ __vecho -ne '\n'
eqawarn "QA Notice: Found an absolute symlink in a library directory:"
eqawarn " ${j#${D}} -> ${linkdest}"
eqawarn " It should be a relative symlink if in the same directory"
@@ -613,8 +640,8 @@ install_qa_check() {
done
done
- # When installing static libraries into /usr/lib and shared libraries into
- # /lib, we have to make sure we have a linker script in /usr/lib along side
+ # When installing static libraries into /usr/lib and shared libraries into
+ # /lib, we have to make sure we have a linker script in /usr/lib along side
# the static library, or gcc will utilize the static lib when linking :(.
# http://bugs.gentoo.org/4411
abort="no"
@@ -624,7 +651,7 @@ install_qa_check() {
if [[ ! -e ${s} ]] ; then
s=${s%usr/*}${s##*/usr/}
if [[ -e ${s} ]] ; then
- vecho -ne '\n'
+ __vecho -ne '\n'
eqawarn "QA Notice: Missing gen_usr_ldscript for ${s##*/}"
abort="yes"
fi
@@ -635,11 +662,11 @@ install_qa_check() {
# Make sure people don't store libtool files or static libs in /lib
f=$(ls "${ED}"lib*/*.{a,la} 2>/dev/null)
if [[ -n ${f} ]] ; then
- vecho -ne '\n'
+ __vecho -ne '\n'
eqawarn "QA Notice: Excessive files found in the / partition"
eqawarn "${f}"
- vecho -ne '\n'
- die "static archives (*.a) and libtool library files (*.la) do not belong in /"
+ __vecho -ne '\n'
+ die "static archives (*.a) and libtool library files (*.la) belong in /usr/lib*, not /lib*"
fi
# Verify that the libtool files don't contain bogus $D entries.
@@ -647,7 +674,7 @@ install_qa_check() {
for a in "${ED}"usr/lib*/*.la ; do
s=${a##*/}
if grep -qs "${ED}" "${a}" ; then
- vecho -ne '\n'
+ __vecho -ne '\n'
eqawarn "QA Notice: ${s} appears to contain PORTAGE_TMPDIR paths"
abort="yes"
fi
@@ -688,6 +715,8 @@ install_qa_check() {
": warning: reference to local variable .* returned"
": warning: returning reference to temporary"
": warning: function returns address of local variable"
+ ": warning: .*\\[-Wsizeof-pointer-memaccess\\]"
+ ": warning: .*\\[-Waggressive-loop-optimizations\\]"
# this may be valid code :/
#": warning: multi-character character constant"
# need to check these two ...
@@ -726,18 +755,19 @@ install_qa_check() {
eerror " with the maintaining herd of the package."
eerror
else
- vecho -ne '\n'
+ __vecho -ne '\n'
eqawarn "QA Notice: Package triggers severe warnings which indicate that it"
eqawarn " may exhibit random runtime failures."
eqawarn "${f}"
- vecho -ne '\n'
+ __vecho -ne '\n'
fi
fi
done
local cat_cmd=cat
[[ $PORTAGE_LOG_FILE = *.gz ]] && cat_cmd=zcat
[[ $reset_debug = 1 ]] && set -x
- f=$($cat_cmd "${PORTAGE_LOG_FILE}" | \
+ # Use safe cwd, avoiding unsafe import for bug #469338.
+ f=$(cd "${PORTAGE_PYM_PATH}" ; $cat_cmd "${PORTAGE_LOG_FILE}" | \
"${PORTAGE_PYTHON:-/usr/bin/python}" "$PORTAGE_BIN_PATH"/check-implicit-pointer-usage.py || die "check-implicit-pointer-usage.py failed")
if [[ -n ${f} ]] ; then
@@ -763,11 +793,11 @@ install_qa_check() {
eerror " with the maintaining herd of the package."
eerror
else
- vecho -ne '\n'
+ __vecho -ne '\n'
eqawarn "QA Notice: Package triggers severe warnings which indicate that it"
eqawarn " will almost certainly crash on 64bit architectures."
eqawarn "${f}"
- vecho -ne '\n'
+ __vecho -ne '\n'
fi
fi
@@ -793,32 +823,42 @@ install_qa_check() {
[[ -x /usr/bin/file && -x /usr/bin/find ]] && \
[[ -n ${MULTILIB_STRICT_DIRS} && -n ${MULTILIB_STRICT_DENY} ]]
then
- local abort=no dir file firstrun=yes
+ rm -f "${T}/multilib-strict.log"
+ local abort=no dir file
MULTILIB_STRICT_EXEMPT=$(echo ${MULTILIB_STRICT_EXEMPT} | sed -e 's:\([(|)]\):\\\1:g')
for dir in ${MULTILIB_STRICT_DIRS} ; do
[[ -d ${ED}/${dir} ]] || continue
for file in $(find ${ED}/${dir} -type f | grep -v "^${ED}/${dir}/${MULTILIB_STRICT_EXEMPT}"); do
if file ${file} | egrep -q "${MULTILIB_STRICT_DENY}" ; then
- if [[ ${firstrun} == yes ]] ; then
- echo "Files matching a file type that is not allowed:"
- firstrun=no
- fi
- abort=yes
- echo " ${file#${ED}//}"
+ echo "${file#${ED}//}" >> "${T}/multilib-strict.log"
fi
done
done
- [[ ${abort} == yes ]] && die "multilib-strict check failed!"
- fi
- # ensure packages don't install systemd units automagically
- if ! has systemd ${INHERITED} && \
- [[ -d "${ED}"/lib/systemd/system ]]
- then
- eqawarn "QA Notice: package installs systemd unit files (/lib/systemd/system)"
- eqawarn " but does not inherit systemd.eclass."
- has stricter ${FEATURES} \
- && die "install aborted due to missing inherit of systemd.eclass"
+ if [[ -s ${T}/multilib-strict.log ]] ; then
+ if [[ ${#QA_MULTILIB_PATHS[@]} -eq 1 ]] ; then
+ local shopts=$-
+ set -o noglob
+ QA_MULTILIB_PATHS=(${QA_MULTILIB_PATHS})
+ set +o noglob
+ set -${shopts}
+ fi
+ if [ "${QA_STRICT_MULTILIB_PATHS-unset}" = unset ] ; then
+ for x in "${QA_MULTILIB_PATHS[@]}" ; do
+ sed -e "s#^${x#/}\$##" -i "${T}/multilib-strict.log"
+ done
+ sed -e "/^\$/d" -i "${T}/multilib-strict.log"
+ fi
+ if [[ -s ${T}/multilib-strict.log ]] ; then
+ abort=yes
+ echo "Files matching a file type that is not allowed:"
+ while read -r ; do
+ echo " ${REPLY}"
+ done < "${T}/multilib-strict.log"
+ fi
+ fi
+
+ [[ ${abort} == yes ]] && die "multilib-strict check failed!"
fi
}
@@ -851,16 +891,6 @@ install_qa_check_prefix() {
# all further checks rely on ${ED} existing
[[ -d ${ED} ]] || return
- # this does not really belong here, but it's closely tied to
- # the code below; many runscripts generate positives here, and we
- # know they don't work (bug #196294) so as long as that one
- # remains an issue, simply remove them as they won't work
- # anyway, avoid etc/init.d/functions.sh from being thrown away
- if [[ ( -d "${ED}"/etc/conf.d || -d "${ED}"/etc/init.d ) && ! -f "${ED}"/etc/init.d/functions.sh ]] ; then
- ewarn "removed /etc/init.d and /etc/conf.d directories until bug #196294 has been resolved"
- rm -Rf "${ED}"/etc/{conf,init}.d
- fi
-
# check shebangs, bug #282539
rm -f "${T}"/non-prefix-shebangs-errs
local WHITELIST=" /usr/bin/env "
@@ -952,7 +982,7 @@ install_mask() {
local no_inst
for no_inst in ${install_mask}; do
set +o noglob
- quiet_mode || einfo "Removing ${no_inst}"
+ __quiet_mode || einfo "Removing ${no_inst}"
# normal stuff
rm -Rf "${root}"/${no_inst} >&/dev/null
@@ -971,8 +1001,9 @@ preinst_mask() {
return 1
fi
- [[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) local ED=${D} ;; esac
+ if ! ___eapi_has_prefix_variables; then
+ local ED=${D}
+ fi
# Make sure $PWD is not ${D} so that we don't leave gmon.out files
# in there in case any tools were built with -pg in CFLAGS.
@@ -1000,8 +1031,9 @@ preinst_sfperms() {
return 1
fi
- [[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) local ED=${D} ;; esac
+ if ! ___eapi_has_prefix_variables; then
+ local ED=${D}
+ fi
# Smart FileSystem Permissions
if has sfperms $FEATURES; then
@@ -1039,8 +1071,9 @@ preinst_suid_scan() {
return 1
fi
- [[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) local ED=${D} ;; esac
+ if ! ___eapi_has_prefix_variables; then
+ local ED=${D}
+ fi
# total suid control.
if has suidctl $FEATURES; then
@@ -1050,19 +1083,19 @@ preinst_suid_scan() {
# to files outside of the sandbox, but this
# can easly be bypassed using the addwrite() function
addwrite "${sfconf}"
- vecho ">>> Performing suid scan in ${ED}"
+ __vecho ">>> Performing suid scan in ${ED}"
for i in $(find "${ED}" -type f \( -perm -4000 -o -perm -2000 \) ); do
if [ -s "${sfconf}" ]; then
install_path=/${i#${ED}}
if grep -q "^${install_path}\$" "${sfconf}" ; then
- vecho "- ${install_path} is an approved suid file"
+ __vecho "- ${install_path} is an approved suid file"
else
- vecho ">>> Removing sbit on non registered ${install_path}"
+ __vecho ">>> Removing sbit on non registered ${install_path}"
for x in 5 4 3 2 1 0; do sleep 0.25 ; done
ls_ret=$(ls -ldh "${i}")
chmod ugo-s "${i}"
grep "^#${install_path}$" "${sfconf}" > /dev/null || {
- vecho ">>> Appending commented out entry to ${sfconf} for ${PF}"
+ __vecho ">>> Appending commented out entry to ${sfconf} for ${PF}"
echo "## ${ls_ret%${ED}*}${install_path}" >> "${sfconf}"
echo "#${install_path}" >> "${sfconf}"
# no delwrite() eh?
@@ -1070,7 +1103,7 @@ preinst_suid_scan() {
}
fi
else
- vecho "suidctl feature set but you are lacking a ${sfconf}"
+ __vecho "suidctl feature set but you are lacking a ${sfconf}"
fi
done
fi
@@ -1082,34 +1115,35 @@ preinst_selinux_labels() {
return 1
fi
if has selinux ${FEATURES}; then
- # SELinux file labeling (needs to always be last in dyn_preinst)
+ # SELinux file labeling (needs to execute after preinst)
# only attempt to label if setfiles is executable
# and 'context' is available on selinuxfs.
if [ -f /selinux/context -o -f /sys/fs/selinux/context ] && \
[ -x /usr/sbin/setfiles -a -x /usr/sbin/selinuxconfig ]; then
- vecho ">>> Setting SELinux security labels"
+ __vecho ">>> Setting SELinux security labels"
(
eval "$(/usr/sbin/selinuxconfig)" || \
die "Failed to determine SELinux policy paths.";
-
+
addwrite /selinux/context
addwrite /sys/fs/selinux/context
-
+
/usr/sbin/setfiles "${file_contexts_path}" -r "${D}" "${D}"
) || die "Failed to set SELinux security labels."
else
# nonfatal, since merging can happen outside a SE kernel
# like during a recovery situation
- vecho "!!! Unable to set SELinux security labels"
+ __vecho "!!! Unable to set SELinux security labels"
fi
fi
}
-dyn_package() {
+__dyn_package() {
local PROOT
- [[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) local EPREFIX= ED=${D} ;; esac
+ if ! ___eapi_has_prefix_variables; then
+ local EPREFIX= ED=${D}
+ fi
# Make sure $PWD is not ${D} so that we don't leave gmon.out files
# in there in case any tools were built with -pg in CFLAGS.
@@ -1132,6 +1166,7 @@ dyn_package() {
local tar_options=""
[[ $PORTAGE_VERBOSE = 1 ]] && tar_options+=" -v"
+ has xattr ${FEATURES} && [[ $(tar --help 2> /dev/null) == *--xattrs* ]] && tar_options+=" --xattrs"
# Sandbox is disabled in case the user wants to use a symlink
# for $PKGDIR and/or $PKGDIR/All.
export SANDBOX_ON="0"
@@ -1141,7 +1176,7 @@ dyn_package() {
tar $tar_options -cf - $PORTAGE_BINPKG_TAR_OPTS -C "${PROOT}" . | \
$PORTAGE_BZIP2_COMMAND -c > "$PORTAGE_BINPKG_TMPFILE"
assert "failed to pack binary package: '$PORTAGE_BINPKG_TMPFILE'"
- PYTHONPATH=${PORTAGE_PYM_PATH}${PYTHONPATH:+:}${PYTHONPATH} \
+ PYTHONPATH=${PORTAGE_PYTHONPATH:-${PORTAGE_PYM_PATH}} \
"${PORTAGE_PYTHON:-/usr/bin/python}" "$PORTAGE_BIN_PATH"/xpak-helper.py recompose \
"$PORTAGE_BINPKG_TMPFILE" "$PORTAGE_BUILDDIR/build-info"
if [ $? -ne 0 ]; then
@@ -1158,7 +1193,7 @@ dyn_package() {
fi
[ -n "${md5_hash}" ] && \
echo ${md5_hash} > "${PORTAGE_BUILDDIR}"/build-info/BINPKGMD5
- vecho ">>> Done."
+ __vecho ">>> Done."
# cleanup our temp tree
[[ -n ${PKG_INSTALL_MASK} ]] && rm -rf "${PROOT}"
@@ -1167,8 +1202,8 @@ dyn_package() {
die "Failed to create $PORTAGE_BUILDDIR/.packaged"
}
-dyn_spec() {
- local sources_dir=/usr/src/rpm/SOURCES
+__dyn_spec() {
+ local sources_dir=${T}/rpmbuild/SOURCES
mkdir -p "${sources_dir}"
declare -a tar_args=("${EBUILD}")
[[ -d ${FILESDIR} ]] && tar_args=("${EBUILD}" "${FILESDIR}")
@@ -1181,10 +1216,9 @@ Summary: ${DESCRIPTION}
Name: ${PN}
Version: ${PV}
Release: ${PR}
-Copyright: GPL
+License: GPL
Group: portage/${CATEGORY}
Source: ${PF}.tar.gz
-Buildroot: ${D}
%description
${DESCRIPTION}
@@ -1205,18 +1239,18 @@ __END1__
}
-dyn_rpm() {
-
- [[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) local EPREFIX= ;; esac
+__dyn_rpm() {
+ if ! ___eapi_has_prefix_variables; then
+ local EPREFIX=
+ fi
cd "${T}" || die "cd failed"
- local machine_name=$(uname -m)
- local dest_dir=${EPREFIX}/usr/src/rpm/RPMS/${machine_name}
- addwrite ${EPREFIX}/usr/src/rpm
+ local machine_name=${CHOST%%-*}
+ local dest_dir=${T}/rpmbuild/RPMS/${machine_name}
addwrite "${RPMDIR}"
- dyn_spec
- rpmbuild -bb --clean --rmsource "${PF}.spec" || die "Failed to integrate rpm spec file"
+ __dyn_spec
+ HOME=${T} \
+ rpmbuild -bb --clean --nodeps --rmsource "${PF}.spec" --buildroot "${D}" --target "${CHOST}" || die "Failed to integrate rpm spec file"
install -D "${dest_dir}/${PN}-${PV}-${PR}.${machine_name}.rpm" \
"${RPMDIR}/${CATEGORY}/${PN}-${PV}-${PR}.rpm" || \
die "Failed to move rpm"
@@ -1254,7 +1288,7 @@ install_hooks() {
}
if [ -n "${MISC_FUNCTIONS_ARGS}" ]; then
- source_all_bashrcs
+ __source_all_bashrcs
[ "$PORTAGE_DEBUG" == "1" ] && set -x
for x in ${MISC_FUNCTIONS_ARGS}; do
${x}
diff --git a/bin/phase-functions.sh b/bin/phase-functions.sh
index ce251ceb9..f39a024a2 100644
--- a/bin/phase-functions.sh
+++ b/bin/phase-functions.sh
@@ -1,5 +1,5 @@
#!/bin/bash
-# Copyright 1999-2012 Gentoo Foundation
+# Copyright 1999-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# Hardcoded bash lists are needed for backward compatibility with
@@ -8,28 +8,31 @@
# when portage is upgrading itself.
PORTAGE_READONLY_METADATA="DEFINED_PHASES DEPEND DESCRIPTION
- EAPI HOMEPAGE INHERITED IUSE REQUIRED_USE KEYWORDS LICENSE
+ EAPI HDEPEND HOMEPAGE INHERITED IUSE REQUIRED_USE KEYWORDS LICENSE
PDEPEND PROVIDE RDEPEND REPOSITORY RESTRICT SLOT SRC_URI"
-PORTAGE_READONLY_VARS="D EBUILD EBUILD_PHASE \
+PORTAGE_READONLY_VARS="D EBUILD EBUILD_PHASE EBUILD_PHASE_FUNC \
EBUILD_SH_ARGS ECLASSDIR EMERGE_FROM FILESDIR MERGE_TYPE \
PM_EBUILD_HOOK_DIR \
PORTAGE_ACTUAL_DISTDIR PORTAGE_ARCHLIST PORTAGE_BASHRC \
PORTAGE_BINPKG_FILE PORTAGE_BINPKG_TAR_OPTS PORTAGE_BINPKG_TMPFILE \
- PORTAGE_BIN_PATH PORTAGE_BUILDDIR PORTAGE_BUNZIP2_COMMAND \
+ PORTAGE_BIN_PATH PORTAGE_BUILDDIR PORTAGE_BUILD_GROUP \
+ PORTAGE_BUILD_USER PORTAGE_BUNZIP2_COMMAND \
PORTAGE_BZIP2_COMMAND PORTAGE_COLORMAP PORTAGE_CONFIGROOT \
PORTAGE_DEBUG PORTAGE_DEPCACHEDIR PORTAGE_EBUILD_EXIT_FILE \
+ PORTAGE_ECLASS_LOCATIONS \
PORTAGE_GID PORTAGE_GRPNAME PORTAGE_INST_GID PORTAGE_INST_UID \
- PORTAGE_IPC_DAEMON PORTAGE_IUSE PORTAGE_LOG_FILE \
+ PORTAGE_INTERNAL_CALLER PORTAGE_IPC_DAEMON PORTAGE_IUSE PORTAGE_LOG_FILE \
PORTAGE_MUTABLE_FILTERED_VARS PORTAGE_OVERRIDE_EPREFIX \
- PORTAGE_PYM_PATH PORTAGE_PYTHON \
+ PORTAGE_PYM_PATH PORTAGE_PYTHON PORTAGE_PYTHONPATH \
PORTAGE_READONLY_METADATA PORTAGE_READONLY_VARS \
- PORTAGE_REPO_NAME PORTAGE_RESTRICT \
+ PORTAGE_REPO_NAME PORTAGE_REPOSITORIES PORTAGE_RESTRICT \
PORTAGE_SAVED_READONLY_VARS PORTAGE_SIGPIPE_STATUS \
PORTAGE_TMPDIR PORTAGE_UPDATE_ENV PORTAGE_USERNAME \
- PORTAGE_VERBOSE PORTAGE_WORKDIR_MODE PORTDIR PORTDIR_OVERLAY \
+ PORTAGE_VERBOSE PORTAGE_WORKDIR_MODE PORTAGE_XATTR_EXCLUDE \
+ PORTDIR \
PROFILE_PATHS REPLACING_VERSIONS REPLACED_BY_VERSION T WORKDIR \
- __PORTAGE_TEST_HARDLINK_LOCKS"
+ __PORTAGE_HELPER __PORTAGE_TEST_HARDLINK_LOCKS"
PORTAGE_SAVED_READONLY_VARS="A CATEGORY P PF PN PR PV PVR"
@@ -39,7 +42,7 @@ PORTAGE_SAVED_READONLY_VARS="A CATEGORY P PF PN PR PV PVR"
# it is saved or loaded (any mutations do not persist).
PORTAGE_MUTABLE_FILTERED_VARS="AA HOSTNAME"
-# @FUNCTION: filter_readonly_variables
+# @FUNCTION: __filter_readonly_variables
# @DESCRIPTION: [--filter-sandbox] [--allow-extra-vars]
# Read an environment from stdin and echo to stdout while filtering variables
# with names that are known to cause interference:
@@ -81,14 +84,14 @@ PORTAGE_MUTABLE_FILTERED_VARS="AA HOSTNAME"
# readonly variable cause the shell to exit while executing the "source"
# builtin command. To avoid this problem, this function filters those
# variables out and discards them. See bug #190128.
-filter_readonly_variables() {
+__filter_readonly_variables() {
local x filtered_vars
local readonly_bash_vars="BASHOPTS BASHPID DIRSTACK EUID
FUNCNAME GROUPS PIPESTATUS PPID SHELLOPTS UID"
local bash_misc_vars="BASH BASH_.* COLUMNS COMP_WORDBREAKS HISTCMD
HISTFILE HOSTNAME HOSTTYPE IFS LINENO MACHTYPE OLDPWD
OPTERR OPTIND OSTYPE POSIXLY_CORRECT PS4 PWD RANDOM
- SECONDS SHELL SHLVL _"
+ SECONDS SHLVL _"
local filtered_sandbox_vars="SANDBOX_ACTIVE SANDBOX_BASHRC
SANDBOX_DEBUG_LOG SANDBOX_DISABLED SANDBOX_LIB
SANDBOX_LOG SANDBOX_ON"
@@ -100,15 +103,9 @@ filter_readonly_variables() {
# Don't filter/interfere with prefix variables unless they are
# supported by the current EAPI.
- case "${EAPI:-0}" in
- 0|1|2)
- [[ " ${FEATURES} " == *" force-prefix "* ]] && \
- filtered_vars+=" ED EPREFIX EROOT"
- ;;
- *)
- filtered_vars+=" ED EPREFIX EROOT"
- ;;
- esac
+ if ___eapi_has_prefix_variables; then
+ filtered_vars+=" ED EPREFIX EROOT"
+ fi
if has --filter-sandbox $* ; then
filtered_vars="${filtered_vars} SANDBOX_.*"
@@ -140,14 +137,14 @@ filter_readonly_variables() {
"${PORTAGE_PYTHON:-/usr/bin/python}" "${PORTAGE_BIN_PATH}"/filter-bash-environment.py "${filtered_vars}" || die "filter-bash-environment.py failed"
}
-# @FUNCTION: preprocess_ebuild_env
+# @FUNCTION: __preprocess_ebuild_env
# @DESCRIPTION:
# Filter any readonly variables from ${T}/environment, source it, and then
-# save it via save_ebuild_env(). This process should be sufficient to prevent
+# save it via __save_ebuild_env(). This process should be sufficient to prevent
# any stale variables or functions from an arbitrary environment from
# interfering with the current environment. This is useful when an existing
# environment needs to be loaded from a binary or installed package.
-preprocess_ebuild_env() {
+__preprocess_ebuild_env() {
local _portage_filter_opts="--filter-features --filter-locale --filter-path --filter-sandbox"
# If environment.raw is present, this is a signal from the python side,
@@ -156,7 +153,7 @@ preprocess_ebuild_env() {
# Otherwise, we don't need to filter the environment.
[ -f "${T}/environment.raw" ] || return 0
- filter_readonly_variables $_portage_filter_opts < "${T}"/environment \
+ __filter_readonly_variables $_portage_filter_opts < "${T}"/environment \
>> "$T/environment.filtered" || return $?
unset _portage_filter_opts
mv "${T}"/environment.filtered "${T}"/environment || return $?
@@ -174,20 +171,20 @@ preprocess_ebuild_env() {
# until we've merged them with our current values.
export SANDBOX_ON=0
- # It's remotely possible that save_ebuild_env() has been overridden
+ # It's remotely possible that __save_ebuild_env() has been overridden
# by the above source command. To protect ourselves, we override it
# here with our own version. ${PORTAGE_BIN_PATH} is safe to use here
# because it's already filtered above.
source "${PORTAGE_BIN_PATH}/save-ebuild-env.sh" || exit $?
- # Rely on save_ebuild_env() to filter out any remaining variables
+ # Rely on __save_ebuild_env() to filter out any remaining variables
# and functions that could interfere with the current environment.
- save_ebuild_env || exit $?
+ __save_ebuild_env || exit $?
>> "$T/environment.success" || exit $?
) > "${T}/environment.filtered"
local retval
if [ -e "${T}/environment.success" ] ; then
- filter_readonly_variables --filter-features < \
+ __filter_readonly_variables --filter-features < \
"${T}/environment.filtered" > "${T}/environment"
retval=$?
else
@@ -197,62 +194,62 @@ preprocess_ebuild_env() {
return ${retval}
}
-ebuild_phase() {
- declare -F "$1" >/dev/null && qa_call $1
+__ebuild_phase() {
+ declare -F "$1" >/dev/null && __qa_call $1
}
-ebuild_phase_with_hooks() {
+__ebuild_phase_with_hooks() {
local x phase_name=${1}
for x in {pre_,,post_}${phase_name} ; do
- ebuild_phase ${x}
+ __ebuild_phase ${x}
done
}
-dyn_pretend() {
+__dyn_pretend() {
if [[ -e $PORTAGE_BUILDDIR/.pretended ]] ; then
- vecho ">>> It appears that '$PF' is already pretended; skipping."
- vecho ">>> Remove '$PORTAGE_BUILDDIR/.pretended' to force pretend."
+ __vecho ">>> It appears that '$PF' is already pretended; skipping."
+ __vecho ">>> Remove '$PORTAGE_BUILDDIR/.pretended' to force pretend."
return 0
fi
- ebuild_phase pre_pkg_pretend
- ebuild_phase pkg_pretend
+ __ebuild_phase pre_pkg_pretend
+ __ebuild_phase pkg_pretend
>> "$PORTAGE_BUILDDIR/.pretended" || \
die "Failed to create $PORTAGE_BUILDDIR/.pretended"
- ebuild_phase post_pkg_pretend
+ __ebuild_phase post_pkg_pretend
}
-dyn_setup() {
+__dyn_setup() {
if [[ -e $PORTAGE_BUILDDIR/.setuped ]] ; then
- vecho ">>> It appears that '$PF' is already setup; skipping."
- vecho ">>> Remove '$PORTAGE_BUILDDIR/.setuped' to force setup."
+ __vecho ">>> It appears that '$PF' is already setup; skipping."
+ __vecho ">>> Remove '$PORTAGE_BUILDDIR/.setuped' to force setup."
return 0
fi
- ebuild_phase pre_pkg_setup
- ebuild_phase pkg_setup
+ __ebuild_phase pre_pkg_setup
+ __ebuild_phase pkg_setup
>> "$PORTAGE_BUILDDIR/.setuped" || \
die "Failed to create $PORTAGE_BUILDDIR/.setuped"
- ebuild_phase post_pkg_setup
+ __ebuild_phase post_pkg_setup
}
-dyn_unpack() {
+__dyn_unpack() {
if [[ -f ${PORTAGE_BUILDDIR}/.unpacked ]] ; then
- vecho ">>> WORKDIR is up-to-date, keeping..."
+ __vecho ">>> WORKDIR is up-to-date, keeping..."
return 0
fi
if [ ! -d "${WORKDIR}" ]; then
install -m${PORTAGE_WORKDIR_MODE:-0700} -d "${WORKDIR}" || die "Failed to create dir '${WORKDIR}'"
fi
cd "${WORKDIR}" || die "Directory change failed: \`cd '${WORKDIR}'\`"
- ebuild_phase pre_src_unpack
- vecho ">>> Unpacking source..."
- ebuild_phase src_unpack
+ __ebuild_phase pre_src_unpack
+ __vecho ">>> Unpacking source..."
+ __ebuild_phase src_unpack
>> "$PORTAGE_BUILDDIR/.unpacked" || \
die "Failed to create $PORTAGE_BUILDDIR/.unpacked"
- vecho ">>> Source unpacked in ${WORKDIR}"
- ebuild_phase post_src_unpack
+ __vecho ">>> Source unpacked in ${WORKDIR}"
+ __ebuild_phase post_src_unpack
}
-dyn_clean() {
+__dyn_clean() {
if [ -z "${PORTAGE_BUILDDIR}" ]; then
echo "Aborting clean phase because PORTAGE_BUILDDIR is unset!"
return 1
@@ -299,7 +296,7 @@ dyn_clean() {
true
}
-abort_handler() {
+__abort_handler() {
local msg
if [ "$2" != "fail" ]; then
msg="${EBUILD}: ${1} aborted; exiting."
@@ -314,37 +311,37 @@ abort_handler() {
trap - SIGINT SIGQUIT
}
-abort_prepare() {
- abort_handler src_prepare $1
+__abort_prepare() {
+ __abort_handler src_prepare $1
rm -f "$PORTAGE_BUILDDIR/.prepared"
exit 1
}
-abort_configure() {
- abort_handler src_configure $1
+__abort_configure() {
+ __abort_handler src_configure $1
rm -f "$PORTAGE_BUILDDIR/.configured"
exit 1
}
-abort_compile() {
- abort_handler "src_compile" $1
+__abort_compile() {
+ __abort_handler "src_compile" $1
rm -f "${PORTAGE_BUILDDIR}/.compiled"
exit 1
}
-abort_test() {
- abort_handler "dyn_test" $1
+__abort_test() {
+ __abort_handler "__dyn_test" $1
rm -f "${PORTAGE_BUILDDIR}/.tested"
exit 1
}
-abort_install() {
- abort_handler "src_install" $1
+__abort_install() {
+ __abort_handler "src_install" $1
rm -rf "${PORTAGE_BUILDDIR}/image"
exit 1
}
-has_phase_defined_up_to() {
+__has_phase_defined_up_to() {
local phase
for phase in unpack prepare configure compile install; do
has ${phase} ${DEFINED_PHASES} && return 0
@@ -354,89 +351,89 @@ has_phase_defined_up_to() {
return 1
}
-dyn_prepare() {
+__dyn_prepare() {
if [[ -e $PORTAGE_BUILDDIR/.prepared ]] ; then
- vecho ">>> It appears that '$PF' is already prepared; skipping."
- vecho ">>> Remove '$PORTAGE_BUILDDIR/.prepared' to force prepare."
+ __vecho ">>> It appears that '$PF' is already prepared; skipping."
+ __vecho ">>> Remove '$PORTAGE_BUILDDIR/.prepared' to force prepare."
return 0
fi
if [[ -d $S ]] ; then
cd "${S}"
- elif has $EAPI 0 1 2 3 3_pre2 ; then
+ elif ___eapi_has_S_WORKDIR_fallback; then
cd "${WORKDIR}"
- elif [[ -z ${A} ]] && ! has_phase_defined_up_to prepare; then
+ elif [[ -z ${A} ]] && ! __has_phase_defined_up_to prepare; then
cd "${WORKDIR}"
else
die "The source directory '${S}' doesn't exist"
fi
- trap abort_prepare SIGINT SIGQUIT
+ trap __abort_prepare SIGINT SIGQUIT
- ebuild_phase pre_src_prepare
- vecho ">>> Preparing source in $PWD ..."
- ebuild_phase src_prepare
+ __ebuild_phase pre_src_prepare
+ __vecho ">>> Preparing source in $PWD ..."
+ __ebuild_phase src_prepare
>> "$PORTAGE_BUILDDIR/.prepared" || \
die "Failed to create $PORTAGE_BUILDDIR/.prepared"
- vecho ">>> Source prepared."
- ebuild_phase post_src_prepare
+ __vecho ">>> Source prepared."
+ __ebuild_phase post_src_prepare
trap - SIGINT SIGQUIT
}
-dyn_configure() {
+__dyn_configure() {
if [[ -e $PORTAGE_BUILDDIR/.configured ]] ; then
- vecho ">>> It appears that '$PF' is already configured; skipping."
- vecho ">>> Remove '$PORTAGE_BUILDDIR/.configured' to force configuration."
+ __vecho ">>> It appears that '$PF' is already configured; skipping."
+ __vecho ">>> Remove '$PORTAGE_BUILDDIR/.configured' to force configuration."
return 0
fi
if [[ -d $S ]] ; then
cd "${S}"
- elif has $EAPI 0 1 2 3 3_pre2 ; then
+ elif ___eapi_has_S_WORKDIR_fallback; then
cd "${WORKDIR}"
- elif [[ -z ${A} ]] && ! has_phase_defined_up_to configure; then
+ elif [[ -z ${A} ]] && ! __has_phase_defined_up_to configure; then
cd "${WORKDIR}"
else
die "The source directory '${S}' doesn't exist"
fi
- trap abort_configure SIGINT SIGQUIT
+ trap __abort_configure SIGINT SIGQUIT
- ebuild_phase pre_src_configure
+ __ebuild_phase pre_src_configure
- vecho ">>> Configuring source in $PWD ..."
- ebuild_phase src_configure
+ __vecho ">>> Configuring source in $PWD ..."
+ __ebuild_phase src_configure
>> "$PORTAGE_BUILDDIR/.configured" || \
die "Failed to create $PORTAGE_BUILDDIR/.configured"
- vecho ">>> Source configured."
+ __vecho ">>> Source configured."
- ebuild_phase post_src_configure
+ __ebuild_phase post_src_configure
trap - SIGINT SIGQUIT
}
-dyn_compile() {
+__dyn_compile() {
if [[ -e $PORTAGE_BUILDDIR/.compiled ]] ; then
- vecho ">>> It appears that '${PF}' is already compiled; skipping."
- vecho ">>> Remove '$PORTAGE_BUILDDIR/.compiled' to force compilation."
+ __vecho ">>> It appears that '${PF}' is already compiled; skipping."
+ __vecho ">>> Remove '$PORTAGE_BUILDDIR/.compiled' to force compilation."
return 0
fi
if [[ -d $S ]] ; then
cd "${S}"
- elif has $EAPI 0 1 2 3 3_pre2 ; then
+ elif ___eapi_has_S_WORKDIR_fallback; then
cd "${WORKDIR}"
- elif [[ -z ${A} ]] && ! has_phase_defined_up_to compile; then
+ elif [[ -z ${A} ]] && ! __has_phase_defined_up_to compile; then
cd "${WORKDIR}"
else
die "The source directory '${S}' doesn't exist"
fi
- trap abort_compile SIGINT SIGQUIT
+ trap __abort_compile SIGINT SIGQUIT
if has distcc $FEATURES && has distcc-pump $FEATURES ; then
if [[ -z $INCLUDE_SERVER_PORT ]] || [[ ! -w $INCLUDE_SERVER_PORT ]] ; then
@@ -445,90 +442,96 @@ dyn_compile() {
fi
fi
- ebuild_phase pre_src_compile
+ __ebuild_phase pre_src_compile
- vecho ">>> Compiling source in $PWD ..."
- ebuild_phase src_compile
+ __vecho ">>> Compiling source in $PWD ..."
+ __ebuild_phase src_compile
>> "$PORTAGE_BUILDDIR/.compiled" || \
die "Failed to create $PORTAGE_BUILDDIR/.compiled"
- vecho ">>> Source compiled."
+ __vecho ">>> Source compiled."
- ebuild_phase post_src_compile
+ __ebuild_phase post_src_compile
trap - SIGINT SIGQUIT
}
-dyn_test() {
+__dyn_test() {
if [[ -e $PORTAGE_BUILDDIR/.tested ]] ; then
- vecho ">>> It appears that ${PN} has already been tested; skipping."
- vecho ">>> Remove '${PORTAGE_BUILDDIR}/.tested' to force test."
+ __vecho ">>> It appears that ${PN} has already been tested; skipping."
+ __vecho ">>> Remove '${PORTAGE_BUILDDIR}/.tested' to force test."
return
fi
- if [ "${EBUILD_FORCE_TEST}" == "1" ] ; then
- # If USE came from ${T}/environment then it might not have USE=test
- # like it's supposed to here.
- ! has test ${USE} && export USE="${USE} test"
- fi
-
- trap "abort_test" SIGINT SIGQUIT
+ trap "__abort_test" SIGINT SIGQUIT
if [ -d "${S}" ]; then
cd "${S}"
else
cd "${WORKDIR}"
fi
- if ! has test $FEATURES && [ "${EBUILD_FORCE_TEST}" != "1" ]; then
- vecho ">>> Test phase [not enabled]: ${CATEGORY}/${PF}"
- elif has test $RESTRICT; then
+ if has test ${RESTRICT} ; then
einfo "Skipping make test/check due to ebuild restriction."
- vecho ">>> Test phase [explicitly disabled]: ${CATEGORY}/${PF}"
+ __vecho ">>> Test phase [disabled because of RESTRICT=test]: ${CATEGORY}/${PF}"
+
+ # If ${EBUILD_FORCE_TEST} == 1 and FEATURES came from ${T}/environment
+ # then it might not have FEATURES=test like it's supposed to here.
+ elif [[ ${EBUILD_FORCE_TEST} != 1 ]] && ! has test ${FEATURES} ; then
+ __vecho ">>> Test phase [not enabled]: ${CATEGORY}/${PF}"
else
+ # If ${EBUILD_FORCE_TEST} == 1 and USE came from ${T}/environment
+ # then it might not have USE=test like it's supposed to here.
+ if [[ ${EBUILD_FORCE_TEST} == 1 && test =~ ${PORTAGE_IUSE} ]] && \
+ ! has test ${USE} ; then
+ export USE="${USE} test"
+ fi
+
local save_sp=${SANDBOX_PREDICT}
addpredict /
- ebuild_phase pre_src_test
- ebuild_phase src_test
+ __ebuild_phase pre_src_test
+ __ebuild_phase src_test
>> "$PORTAGE_BUILDDIR/.tested" || \
die "Failed to create $PORTAGE_BUILDDIR/.tested"
- ebuild_phase post_src_test
+ __ebuild_phase post_src_test
SANDBOX_PREDICT=${save_sp}
fi
trap - SIGINT SIGQUIT
}
-dyn_install() {
+__dyn_install() {
[ -z "$PORTAGE_BUILDDIR" ] && die "${FUNCNAME}: PORTAGE_BUILDDIR is unset"
if has noauto $FEATURES ; then
rm -f "${PORTAGE_BUILDDIR}/.installed"
elif [[ -e $PORTAGE_BUILDDIR/.installed ]] ; then
- vecho ">>> It appears that '${PF}' is already installed; skipping."
- vecho ">>> Remove '${PORTAGE_BUILDDIR}/.installed' to force install."
+ __vecho ">>> It appears that '${PF}' is already installed; skipping."
+ __vecho ">>> Remove '${PORTAGE_BUILDDIR}/.installed' to force install."
return 0
fi
- trap "abort_install" SIGINT SIGQUIT
- ebuild_phase pre_src_install
+ trap "__abort_install" SIGINT SIGQUIT
+ __ebuild_phase pre_src_install
- _x=${ED}
- [[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) _x=${D} ;; esac
+ if ___eapi_has_prefix_variables; then
+ _x=${ED}
+ else
+ _x=${D}
+ fi
rm -rf "${D}"
mkdir -p "${_x}"
unset _x
if [[ -d $S ]] ; then
cd "${S}"
- elif has $EAPI 0 1 2 3 3_pre2 ; then
+ elif ___eapi_has_S_WORKDIR_fallback; then
cd "${WORKDIR}"
- elif [[ -z ${A} ]] && ! has_phase_defined_up_to install; then
+ elif [[ -z ${A} ]] && ! __has_phase_defined_up_to install; then
cd "${WORKDIR}"
else
die "The source directory '${S}' doesn't exist"
fi
- vecho
- vecho ">>> Install ${PF} into ${D} category ${CATEGORY}"
+ __vecho
+ __vecho ">>> Install ${PF} into ${D} category ${CATEGORY}"
#our custom version of libtool uses $S and $D to fix
#invalid paths in .la files
export S D
@@ -541,12 +544,12 @@ dyn_install() {
export _E_EXEDESTTREE_=""
export _E_DOCDESTTREE_=""
- ebuild_phase src_install
+ __ebuild_phase src_install
>> "$PORTAGE_BUILDDIR/.installed" || \
die "Failed to create $PORTAGE_BUILDDIR/.installed"
- vecho ">>> Completed installing ${PF} into ${D}"
- vecho
- ebuild_phase post_src_install
+ __vecho ">>> Completed installing ${PF} into ${D}"
+ __vecho
+ __ebuild_phase post_src_install
cd "${PORTAGE_BUILDDIR}"/build-info
set -f
@@ -560,10 +563,15 @@ dyn_install() {
if [[ $CATEGORY != virtual ]] ; then
for f in ASFLAGS CBUILD CC CFLAGS CHOST CTARGET CXX \
CXXFLAGS EXTRA_ECONF EXTRA_EINSTALL EXTRA_MAKE \
- LDFLAGS LIBCFLAGS LIBCXXFLAGS ; do
+ LDFLAGS LIBCFLAGS LIBCXXFLAGS QA_CONFIGURE_OPTIONS \
+ QA_DESKTOP_FILE ; do
x=$(echo -n ${!f})
[[ -n $x ]] && echo "$x" > $f
done
+ # whitespace preserved
+ for f in QA_AM_MAINTAINER_MODE ; do
+ [[ -n ${!f} ]] && echo "${!f}" > $f
+ done
fi
echo "${USE}" > USE
echo "${EAPI:-0}" > EAPI
@@ -571,24 +579,22 @@ dyn_install() {
# Save EPREFIX, since it makes it easy to use chpathtool to
# adjust the content of a binary package so that it will
# work in a different EPREFIX from the one is was built for.
- case "${EAPI:-0}" in
- 0|1|2)
- [[ " ${FEATURES} " == *" force-prefix "* ]] && \
- [ -n "${EPREFIX}" ] && echo "${EPREFIX}" > EPREFIX
- ;;
- *)
- [ -n "${EPREFIX}" ] && echo "${EPREFIX}" > EPREFIX
- ;;
- esac
+ if ___eapi_has_prefix_variables && [[ -n ${EPREFIX} ]]; then
+ echo "${EPREFIX}" > EPREFIX
+ fi
set +f
# local variables can leak into the saved environment.
unset f
- save_ebuild_env --exclude-init-phases | filter_readonly_variables \
- --filter-path --filter-sandbox --allow-extra-vars > environment
- assert "save_ebuild_env failed"
+ # Use safe cwd, avoiding unsafe import for bug #469338.
+ cd "${PORTAGE_PYM_PATH}"
+ __save_ebuild_env --exclude-init-phases | __filter_readonly_variables \
+ --filter-path --filter-sandbox --allow-extra-vars > \
+ "${PORTAGE_BUILDDIR}"/build-info/environment
+ assert "__save_ebuild_env failed"
+ cd "${PORTAGE_BUILDDIR}"/build-info || die
${PORTAGE_BZIP2_COMMAND} -f9 environment
@@ -601,15 +607,7 @@ dyn_install() {
trap - SIGINT SIGQUIT
}
-dyn_preinst() {
- if [ -z "${D}" ]; then
- eerror "${FUNCNAME}: D is unset"
- return 1
- fi
- ebuild_phase_with_hooks pkg_preinst
-}
-
-dyn_help() {
+__dyn_help() {
echo
echo "Portage"
echo "Copyright 1999-2010 Gentoo Foundation"
@@ -625,6 +623,7 @@ dyn_help() {
echo " pretend : execute package specific pretend actions"
echo " setup : execute package specific setup actions"
echo " fetch : download source archive(s) and patches"
+ echo " nofetch : display special fetch instructions"
echo " digest : create a manifest file for the package"
echo " manifest : create a manifest file for the package"
echo " unpack : unpack sources (auto-dependencies if needed)"
@@ -672,19 +671,18 @@ dyn_help() {
echo
}
-# @FUNCTION: _ebuild_arg_to_phase
+# @FUNCTION: __ebuild_arg_to_phase
# @DESCRIPTION:
# Translate a known ebuild(1) argument into the precise
# name of it's corresponding ebuild phase.
-_ebuild_arg_to_phase() {
- [ $# -ne 2 ] && die "expected exactly 2 args, got $#: $*"
- local eapi=$1
- local arg=$2
+__ebuild_arg_to_phase() {
+ [ $# -ne 1 ] && die "expected exactly 1 arg, got $#: $*"
+ local arg=$1
local phase_func=""
case "$arg" in
pretend)
- ! has $eapi 0 1 2 3 3_pre2 && \
+ ___eapi_has_pkg_pretend && \
phase_func=pkg_pretend
;;
setup)
@@ -697,11 +695,11 @@ _ebuild_arg_to_phase() {
phase_func=src_unpack
;;
prepare)
- ! has $eapi 0 1 && \
+ ___eapi_has_src_prepare && \
phase_func=src_prepare
;;
configure)
- ! has $eapi 0 1 && \
+ ___eapi_has_src_configure && \
phase_func=src_configure
;;
compile)
@@ -732,7 +730,7 @@ _ebuild_arg_to_phase() {
return 0
}
-_ebuild_phase_funcs() {
+__ebuild_phase_funcs() {
[ $# -ne 2 ] && die "expected exactly 2 args, got $#: $*"
local eapi=$1
local phase_func=$2
@@ -742,20 +740,20 @@ _ebuild_phase_funcs() {
for x in pkg_nofetch src_unpack src_test ; do
declare -F $x >/dev/null || \
- eval "$x() { _eapi0_$x \"\$@\" ; }"
+ eval "$x() { __eapi0_$x \"\$@\" ; }"
done
- case $eapi in
+ case "$eapi" in
0|1)
if ! declare -F src_compile >/dev/null ; then
- case $eapi in
+ case "$eapi" in
0)
- src_compile() { _eapi0_src_compile "$@" ; }
+ src_compile() { __eapi0_src_compile "$@" ; }
;;
*)
- src_compile() { _eapi1_src_compile "$@" ; }
+ src_compile() { __eapi1_src_compile "$@" ; }
;;
esac
fi
@@ -775,35 +773,35 @@ _ebuild_phase_funcs() {
*)
declare -F src_configure >/dev/null || \
- src_configure() { _eapi2_src_configure "$@" ; }
+ src_configure() { __eapi2_src_configure "$@" ; }
declare -F src_compile >/dev/null || \
- src_compile() { _eapi2_src_compile "$@" ; }
+ src_compile() { __eapi2_src_compile "$@" ; }
- has $eapi 2 3 3_pre2 || declare -F src_install >/dev/null || \
- src_install() { _eapi4_src_install "$@" ; }
+ has $eapi 2 3 || declare -F src_install >/dev/null || \
+ src_install() { __eapi4_src_install "$@" ; }
if has $phase_func $default_phases ; then
- _eapi2_pkg_nofetch () { _eapi0_pkg_nofetch "$@" ; }
- _eapi2_src_unpack () { _eapi0_src_unpack "$@" ; }
- _eapi2_src_prepare () { true ; }
- _eapi2_src_test () { _eapi0_src_test "$@" ; }
- _eapi2_src_install () { die "$FUNCNAME is not supported" ; }
+ __eapi2_pkg_nofetch () { __eapi0_pkg_nofetch "$@" ; }
+ __eapi2_src_unpack () { __eapi0_src_unpack "$@" ; }
+ __eapi2_src_prepare () { true ; }
+ __eapi2_src_test () { __eapi0_src_test "$@" ; }
+ __eapi2_src_install () { die "$FUNCNAME is not supported" ; }
for x in $default_phases ; do
- eval "default_$x() { _eapi2_$x \"\$@\" ; }"
+ eval "default_$x() { __eapi2_$x \"\$@\" ; }"
done
- eval "default() { _eapi2_$phase_func \"\$@\" ; }"
+ eval "default() { __eapi2_$phase_func \"\$@\" ; }"
- case $eapi in
+ case "$eapi" in
2|3)
;;
*)
- eval "default_src_install() { _eapi4_src_install \"\$@\" ; }"
+ eval "default_src_install() { __eapi4_src_install \"\$@\" ; }"
[[ $phase_func = src_install ]] && \
- eval "default() { _eapi4_$phase_func \"\$@\" ; }"
+ eval "default() { __eapi4_$phase_func \"\$@\" ; }"
;;
esac
@@ -825,14 +823,14 @@ _ebuild_phase_funcs() {
esac
}
-ebuild_main() {
+__ebuild_main() {
# Subshell/helper die support (must export for the die helper).
# Since this function is typically executed in a subshell,
# setup EBUILD_MASTER_PID to refer to the current $BASHPID,
# which seems to give the best results when further
# nested subshells call die.
- export EBUILD_MASTER_PID=$BASHPID
+ export EBUILD_MASTER_PID=${BASHPID:-$(__bashpid)}
trap 'exit 1' SIGTERM
#a reasonable default for $S
@@ -861,37 +859,39 @@ ebuild_main() {
# respect FEATURES="-ccache".
has ccache $FEATURES || export CCACHE_DISABLE=1
- local phase_func=$(_ebuild_arg_to_phase "$EAPI" "$EBUILD_PHASE")
- [[ -n $phase_func ]] && _ebuild_phase_funcs "$EAPI" "$phase_func"
+ local phase_func=$(__ebuild_arg_to_phase "$EBUILD_PHASE")
+ [[ -n $phase_func ]] && __ebuild_phase_funcs "$EAPI" "$phase_func"
unset phase_func
- source_all_bashrcs
+ __source_all_bashrcs
case ${1} in
nofetch)
- ebuild_phase_with_hooks pkg_nofetch
+ __ebuild_phase_with_hooks pkg_nofetch
;;
- prerm|postrm|postinst|config|info)
+ prerm|postrm|preinst|postinst|config|info)
if has "${1}" config info && \
! declare -F "pkg_${1}" >/dev/null ; then
ewarn "pkg_${1}() is not defined: '${EBUILD##*/}'"
fi
export SANDBOX_ON="0"
if [ "${PORTAGE_DEBUG}" != "1" ] || [ "${-/x/}" != "$-" ]; then
- ebuild_phase_with_hooks pkg_${1}
+ __ebuild_phase_with_hooks pkg_${1}
else
set -x
- ebuild_phase_with_hooks pkg_${1}
+ __ebuild_phase_with_hooks pkg_${1}
set +x
fi
- if [[ $EBUILD_PHASE == postinst ]] && [[ -n $PORTAGE_UPDATE_ENV ]]; then
+ if [[ -n $PORTAGE_UPDATE_ENV ]] ; then
# Update environment.bz2 in case installation phases
# need to pass some variables to uninstallation phases.
- save_ebuild_env --exclude-init-phases | \
- filter_readonly_variables --filter-path \
+ # Use safe cwd, avoiding unsafe import for bug #469338.
+ cd "${PORTAGE_PYM_PATH}"
+ __save_ebuild_env --exclude-init-phases | \
+ __filter_readonly_variables --filter-path \
--filter-sandbox --allow-extra-vars \
| ${PORTAGE_BZIP2_COMMAND} -c -f9 > "$PORTAGE_UPDATE_ENV"
- assert "save_ebuild_env failed"
+ assert "__save_ebuild_env failed"
fi
;;
unpack|prepare|configure|compile|test|clean|install)
@@ -917,7 +917,7 @@ ebuild_main() {
x=LIBDIR_$ABI
[ -z "$PKG_CONFIG_PATH" -a -n "$ABI" -a -n "${!x}" ] && \
- export PKG_CONFIG_PATH=/usr/${!x}/pkgconfig
+ export PKG_CONFIG_PATH=${EPREFIX}/usr/${!x}/pkgconfig
if has noauto $FEATURES && \
[[ ! -f $PORTAGE_BUILDDIR/.unpacked ]] ; then
@@ -952,24 +952,24 @@ ebuild_main() {
esac
if [ "${PORTAGE_DEBUG}" != "1" ] || [ "${-/x/}" != "$-" ]; then
- dyn_${1}
+ __dyn_${1}
else
set -x
- dyn_${1}
+ __dyn_${1}
set +x
fi
export SANDBOX_ON="0"
;;
- help|pretend|setup|preinst)
+ help|pretend|setup)
#pkg_setup needs to be out of the sandbox for tmp file creation;
#for example, awking and piping a file in /tmp requires a temp file to be created
#in /etc. If pkg_setup is in the sandbox, both our lilo and apache ebuilds break.
export SANDBOX_ON="0"
if [ "${PORTAGE_DEBUG}" != "1" ] || [ "${-/x/}" != "$-" ]; then
- dyn_${1}
+ __dyn_${1}
else
set -x
- dyn_${1}
+ __dyn_${1}
set +x
fi
;;
@@ -979,7 +979,7 @@ ebuild_main() {
export SANDBOX_ON="1"
echo "Unrecognized arg '${1}'"
echo
- dyn_help
+ __dyn_help
exit 1
;;
esac
@@ -987,11 +987,13 @@ ebuild_main() {
# Save the env only for relevant phases.
if ! has "${1}" clean help info nofetch ; then
umask 002
- save_ebuild_env | filter_readonly_variables \
+ # Use safe cwd, avoiding unsafe import for bug #469338.
+ cd "${PORTAGE_PYM_PATH}"
+ __save_ebuild_env | __filter_readonly_variables \
--filter-features > "$T/environment"
- assert "save_ebuild_env failed"
- chown portage:portage "$T/environment" &>/dev/null
- chmod g+w "$T/environment" &>/dev/null
+ assert "__save_ebuild_env failed"
+ chgrp "${PORTAGE_GRPNAME:-portage}" "$T/environment"
+ chmod g+w "$T/environment"
fi
[[ -n $PORTAGE_EBUILD_EXIT_FILE ]] && > "$PORTAGE_EBUILD_EXIT_FILE"
if [[ -n $PORTAGE_IPC_DAEMON ]] ; then
diff --git a/bin/phase-helpers.sh b/bin/phase-helpers.sh
index 946520b20..412decbe0 100644
--- a/bin/phase-helpers.sh
+++ b/bin/phase-helpers.sh
@@ -1,5 +1,5 @@
#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
+# Copyright 1999-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
export DESTTREE=/usr
@@ -11,6 +11,8 @@ export EXEOPTIONS="-m0755"
export LIBOPTIONS="-m0644"
export DIROPTIONS="-m0755"
export MOPREFIX=${PN}
+# Do not compress files which are smaller than this (in bytes). #169260
+export PORTAGE_DOCOMPRESS_SIZE_LIMIT="128"
declare -a PORTAGE_DOCOMPRESS=( /usr/share/{doc,info,man} )
declare -a PORTAGE_DOCOMPRESS_SKIP=( /usr/share/doc/${PF}/html )
@@ -19,13 +21,14 @@ into() {
export DESTTREE=""
else
export DESTTREE=$1
- [[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) local ED=${D} ;; esac
+ if ! ___eapi_has_prefix_variables; then
+ local ED=${D}
+ fi
if [ ! -d "${ED}${DESTTREE}" ]; then
install -d "${ED}${DESTTREE}"
local ret=$?
if [[ $ret -ne 0 ]] ; then
- helpers_die "${FUNCNAME[0]} failed"
+ __helpers_die "${FUNCNAME[0]} failed"
return $ret
fi
fi
@@ -37,13 +40,14 @@ insinto() {
export INSDESTTREE=""
else
export INSDESTTREE=$1
- [[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) local ED=${D} ;; esac
+ if ! ___eapi_has_prefix_variables; then
+ local ED=${D}
+ fi
if [ ! -d "${ED}${INSDESTTREE}" ]; then
install -d "${ED}${INSDESTTREE}"
local ret=$?
if [[ $ret -ne 0 ]] ; then
- helpers_die "${FUNCNAME[0]} failed"
+ __helpers_die "${FUNCNAME[0]} failed"
return $ret
fi
fi
@@ -55,13 +59,14 @@ exeinto() {
export _E_EXEDESTTREE_=""
else
export _E_EXEDESTTREE_="$1"
- [[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) local ED=${D} ;; esac
+ if ! ___eapi_has_prefix_variables; then
+ local ED=${D}
+ fi
if [ ! -d "${ED}${_E_EXEDESTTREE_}" ]; then
install -d "${ED}${_E_EXEDESTTREE_}"
local ret=$?
if [[ $ret -ne 0 ]] ; then
- helpers_die "${FUNCNAME[0]} failed"
+ __helpers_die "${FUNCNAME[0]} failed"
return $ret
fi
fi
@@ -73,13 +78,14 @@ docinto() {
export _E_DOCDESTTREE_=""
else
export _E_DOCDESTTREE_="$1"
- [[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) local ED=${D} ;; esac
+ if ! ___eapi_has_prefix_variables; then
+ local ED=${D}
+ fi
if [ ! -d "${ED}usr/share/doc/${PF}/${_E_DOCDESTTREE_}" ]; then
install -d "${ED}usr/share/doc/${PF}/${_E_DOCDESTTREE_}"
local ret=$?
if [[ $ret -ne 0 ]] ; then
- helpers_die "${FUNCNAME[0]} failed"
+ __helpers_die "${FUNCNAME[0]} failed"
return $ret
fi
fi
@@ -112,13 +118,13 @@ libopts() {
}
docompress() {
- has "${EAPI}" 0 1 2 3 && die "'docompress' not supported in this EAPI"
+ ___eapi_has_docompress || die "'docompress' not supported in this EAPI"
local f g
if [[ $1 = "-x" ]]; then
shift
for f; do
- f=$(strip_duplicate_slashes "${f}"); f=${f%/}
+ f=$(__strip_duplicate_slashes "${f}"); f=${f%/}
[[ ${f:0:1} = / ]] || f="/${f}"
for g in "${PORTAGE_DOCOMPRESS_SKIP[@]}"; do
[[ ${f} = "${g}" ]] && continue 2
@@ -127,7 +133,7 @@ docompress() {
done
else
for f; do
- f=$(strip_duplicate_slashes "${f}"); f=${f%/}
+ f=$(__strip_duplicate_slashes "${f}"); f=${f%/}
[[ ${f:0:1} = / ]] || f="/${f}"
for g in "${PORTAGE_DOCOMPRESS[@]}"; do
[[ ${f} = "${g}" ]] && continue 2
@@ -137,29 +143,6 @@ docompress() {
fi
}
-# adds ".keep" files so that dirs aren't auto-cleaned
-keepdir() {
- dodir "$@"
- local x
- [[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) local ED=${D} ;; esac
- if [ "$1" == "-R" ] || [ "$1" == "-r" ]; then
- shift
- find "$@" -type d -printf "${ED}%p/.keep_${CATEGORY}_${PN}-${SLOT}\n" \
- | tr "\n" "\0" | \
- while read -r -d $'\0' ; do
- >> "$REPLY" || \
- die "Failed to recursively create .keep files"
- done
- else
- for x in "$@"; do
- >> "${ED}${x}/.keep_${CATEGORY}_${PN}-${SLOT}" || \
- die "Failed to create .keep in ${ED}${x}"
- done
- fi
-}
-
-
useq() {
has $EBUILD_PHASE prerm postrm || eqawarn \
"QA Notice: The 'useq' function is deprecated (replaced by 'use')"
@@ -174,6 +157,17 @@ usev() {
return 1
}
+if ___eapi_has_usex; then
+ usex() {
+ if use "$1"; then
+ echo "${2-yes}$4"
+ else
+ echo "${3-no}$5"
+ fi
+ return 0
+ }
+fi
+
use() {
local u=$1
local found=0
@@ -194,18 +188,31 @@ use() {
#fi
true
- # Make sure we have this USE flag in IUSE
- elif [[ -n $PORTAGE_IUSE && -n $EBUILD_PHASE ]] ; then
- [[ $u =~ $PORTAGE_IUSE ]] || \
+ # Make sure we have this USE flag in IUSE, but exempt binary
+ # packages for API consumers like Entropy which do not require
+ # a full profile with IUSE_IMPLICIT and stuff (see bug #456830).
+ elif [[ -n $PORTAGE_IUSE && -n $EBUILD_PHASE &&
+ -n $PORTAGE_INTERNAL_CALLER ]] ; then
+ if [[ ! $u =~ $PORTAGE_IUSE ]] ; then
+ if [[ ! ${EAPI} =~ ^(0|1|2|3|4|4-python|4-slot-abi)$ ]] ; then
+ # This is only strict starting with EAPI 5, since implicit IUSE
+ # is not well defined for earlier EAPIs (see bug #449708).
+ die "USE Flag '${u}' not in IUSE for ${CATEGORY}/${PF}"
+ fi
eqawarn "QA Notice: USE Flag '${u}' not" \
"in IUSE for ${CATEGORY}/${PF}"
+ fi
fi
+ local IFS=$' \t\n' prev_shopts=$- ret
+ set -f
if has ${u} ${USE} ; then
- return ${found}
+ ret=${found}
else
- return $((!found))
+ ret=$((!found))
fi
+ [[ ${prev_shopts} == *f* ]] || set +f
+ return ${ret}
}
use_with() {
@@ -215,7 +222,7 @@ use_with() {
return 1
fi
- if ! has "${EAPI:-0}" 0 1 2 3 ; then
+ if ___eapi_use_enable_and_use_with_support_empty_third_argument; then
local UW_SUFFIX=${3+=$3}
else
local UW_SUFFIX=${3:+=$3}
@@ -237,7 +244,7 @@ use_enable() {
return 1
fi
- if ! has "${EAPI:-0}" 0 1 2 3 ; then
+ if ___eapi_use_enable_and_use_with_support_empty_third_argument; then
local UE_SUFFIX=${3+=$3}
else
local UE_SUFFIX=${3:+=$3}
@@ -255,15 +262,19 @@ use_enable() {
unpack() {
local srcdir
local x
- local y
+ local y y_insensitive
+ local suffix suffix_insensitive
local myfail
local eapi=${EAPI:-0}
[ -z "$*" ] && die "Nothing passed to the 'unpack' command"
for x in "$@"; do
- vecho ">>> Unpacking ${x} to ${PWD}"
+ __vecho ">>> Unpacking ${x} to ${PWD}"
+ suffix=${x##*.}
+ suffix_insensitive=$(LC_ALL=C tr "[:upper:]" "[:lower:]" <<< "${suffix}")
y=${x%.*}
y=${y##*.}
+ y_insensitive=$(LC_ALL=C tr "[:upper:]" "[:lower:]" <<< "${y}")
if [[ ${x} == "./"* ]] ; then
srcdir=""
@@ -276,10 +287,16 @@ unpack() {
fi
[[ ! -s ${srcdir}${x} ]] && die "${x} does not exist"
- _unpack_tar() {
- if [ "${y}" == "tar" ]; then
+ __unpack_tar() {
+ if [[ ${y_insensitive} == tar ]] ; then
+ if ___eapi_unpack_is_case_sensitive && \
+ [[ tar != ${y} ]] ; then
+ eqawarn "QA Notice: unpack called with" \
+ "secondary suffix '${y}' which is unofficially" \
+ "supported with EAPI '${EAPI}'. Instead use 'tar'."
+ fi
$1 -c -- "$srcdir$x" | tar xof -
- assert_sigpipe_ok "$myfail"
+ __assert_sigpipe_ok "$myfail"
else
local cwd_dest=${x##*/}
cwd_dest=${cwd_dest%.*}
@@ -288,30 +305,67 @@ unpack() {
}
myfail="failure unpacking ${x}"
- case "${x##*.}" in
+ case "${suffix_insensitive}" in
tar)
+ if ___eapi_unpack_is_case_sensitive && \
+ [[ tar != ${suffix} ]] ; then
+ eqawarn "QA Notice: unpack called with" \
+ "suffix '${suffix}' which is unofficially supported" \
+ "with EAPI '${EAPI}'. Instead use 'tar'."
+ fi
tar xof "$srcdir$x" || die "$myfail"
;;
tgz)
+ if ___eapi_unpack_is_case_sensitive && \
+ [[ tgz != ${suffix} ]] ; then
+ eqawarn "QA Notice: unpack called with" \
+ "suffix '${suffix}' which is unofficially supported" \
+ "with EAPI '${EAPI}'. Instead use 'tgz'."
+ fi
tar xozf "$srcdir$x" || die "$myfail"
;;
tbz|tbz2)
+ if ___eapi_unpack_is_case_sensitive && \
+ [[ " tbz tbz2 " != *" ${suffix} "* ]] ; then
+ eqawarn "QA Notice: unpack called with" \
+ "suffix '${suffix}' which is unofficially supported" \
+ "with EAPI '${EAPI}'. Instead use 'tbz' or 'tbz2'."
+ fi
${PORTAGE_BUNZIP2_COMMAND:-${PORTAGE_BZIP2_COMMAND} -d} -c -- "$srcdir$x" | tar xof -
- assert_sigpipe_ok "$myfail"
+ __assert_sigpipe_ok "$myfail"
;;
- ZIP|zip|jar)
+ zip|jar)
+ if ___eapi_unpack_is_case_sensitive && \
+ [[ " ZIP zip jar " != *" ${suffix} "* ]] ; then
+ eqawarn "QA Notice: unpack called with" \
+ "suffix '${suffix}' which is unofficially supported" \
+ "with EAPI '${EAPI}'." \
+ "Instead use 'ZIP', 'zip', or 'jar'."
+ fi
# unzip will interactively prompt under some error conditions,
# as reported in bug #336285
( set +x ; while true ; do echo n || break ; done ) | \
unzip -qo "${srcdir}${x}" || die "$myfail"
;;
- gz|Z|z)
- _unpack_tar "gzip -d"
+ gz|z)
+ if ___eapi_unpack_is_case_sensitive && \
+ [[ " gz z Z " != *" ${suffix} "* ]] ; then
+ eqawarn "QA Notice: unpack called with" \
+ "suffix '${suffix}' which is unofficially supported" \
+ "with EAPI '${EAPI}'. Instead use 'gz', 'z', or 'Z'."
+ fi
+ __unpack_tar "gzip -d"
;;
bz2|bz)
- _unpack_tar "${PORTAGE_BUNZIP2_COMMAND:-${PORTAGE_BZIP2_COMMAND} -d}"
+ if ___eapi_unpack_is_case_sensitive && \
+ [[ " bz bz2 " != *" ${suffix} "* ]] ; then
+ eqawarn "QA Notice: unpack called with" \
+ "suffix '${suffix}' which is unofficially supported" \
+ "with EAPI '${EAPI}'. Instead use 'bz' or 'bz2'."
+ fi
+ __unpack_tar "${PORTAGE_BUNZIP2_COMMAND:-${PORTAGE_BZIP2_COMMAND} -d}"
;;
- 7Z|7z)
+ 7z)
local my_output
my_output="$(7z x -y "${srcdir}${x}")"
if [ $? -ne 0 ]; then
@@ -319,16 +373,41 @@ unpack() {
die "$myfail"
fi
;;
- RAR|rar)
+ rar)
+ if ___eapi_unpack_is_case_sensitive && \
+ [[ " rar RAR " != *" ${suffix} "* ]] ; then
+ eqawarn "QA Notice: unpack called with" \
+ "suffix '${suffix}' which is unofficially supported" \
+ "with EAPI '${EAPI}'. Instead use 'rar' or 'RAR'."
+ fi
unrar x -idq -o+ "${srcdir}${x}" || die "$myfail"
;;
- LHa|LHA|lha|lzh)
+ lha|lzh)
+ if ___eapi_unpack_is_case_sensitive && \
+ [[ " LHA LHa lha lzh " != *" ${suffix} "* ]] ; then
+ eqawarn "QA Notice: unpack called with" \
+ "suffix '${suffix}' which is unofficially supported" \
+ "with EAPI '${EAPI}'." \
+ "Instead use 'LHA', 'LHa', 'lha', or 'lzh'."
+ fi
lha xfq "${srcdir}${x}" || die "$myfail"
;;
a)
+ if ___eapi_unpack_is_case_sensitive && \
+ [[ " a " != *" ${suffix} "* ]] ; then
+ eqawarn "QA Notice: unpack called with" \
+ "suffix '${suffix}' which is unofficially supported" \
+ "with EAPI '${EAPI}'. Instead use 'a'."
+ fi
ar x "${srcdir}${x}" || die "$myfail"
;;
deb)
+ if ___eapi_unpack_is_case_sensitive && \
+ [[ " deb " != *" ${suffix} "* ]] ; then
+ eqawarn "QA Notice: unpack called with" \
+ "suffix '${suffix}' which is unofficially supported" \
+ "with EAPI '${EAPI}'. Instead use 'deb'."
+ fi
# Unpacking .deb archives can not always be done with
# `ar`. For instance on AIX this doesn't work out. If
# we have `deb2targz` installed, prefer it over `ar` for
@@ -356,17 +435,29 @@ unpack() {
fi
;;
lzma)
- _unpack_tar "lzma -d"
+ if ___eapi_unpack_is_case_sensitive && \
+ [[ " lzma " != *" ${suffix} "* ]] ; then
+ eqawarn "QA Notice: unpack called with" \
+ "suffix '${suffix}' which is unofficially supported" \
+ "with EAPI '${EAPI}'. Instead use 'lzma'."
+ fi
+ __unpack_tar "lzma -d"
;;
xz)
- if has $eapi 0 1 2 ; then
- vecho "unpack ${x}: file format not recognized. Ignoring."
+ if ___eapi_unpack_is_case_sensitive && \
+ [[ " xz " != *" ${suffix} "* ]] ; then
+ eqawarn "QA Notice: unpack called with" \
+ "suffix '${suffix}' which is unofficially supported" \
+ "with EAPI '${EAPI}'. Instead use 'xz'."
+ fi
+ if ___eapi_unpack_supports_xz; then
+ __unpack_tar "xz -d"
else
- _unpack_tar "xz -d"
+ __vecho "unpack ${x}: file format not recognized. Ignoring."
fi
;;
*)
- vecho "unpack ${x}: file format not recognized. Ignoring."
+ __vecho "unpack ${x}: file format not recognized. Ignoring."
;;
esac
done
@@ -378,22 +469,24 @@ unpack() {
econf() {
local x
+ local pid=${BASHPID:-$(__bashpid)}
- [[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) local EPREFIX= ;; esac
+ if ! ___eapi_has_prefix_variables; then
+ local EPREFIX=
+ fi
- _hasg() {
+ __hasg() {
local x s=$1
shift
for x ; do [[ ${x} == ${s} ]] && echo "${x}" && return 0 ; done
return 1
}
- _hasgq() { _hasg "$@" >/dev/null ; }
+ __hasgq() { __hasg "$@" >/dev/null ; }
- local phase_func=$(_ebuild_arg_to_phase "$EAPI" "$EBUILD_PHASE")
+ local phase_func=$(__ebuild_arg_to_phase "$EBUILD_PHASE")
if [[ -n $phase_func ]] ; then
- if has "$EAPI" 0 1 ; then
+ if ! ___eapi_has_src_configure; then
[[ $phase_func != src_compile ]] && \
eqawarn "QA Notice: econf called in" \
"$phase_func instead of src_compile"
@@ -408,23 +501,44 @@ econf() {
if [ -x "${ECONF_SOURCE}/configure" ]; then
if [[ -n $CONFIG_SHELL && \
"$(head -n1 "$ECONF_SOURCE/configure")" =~ ^'#!'[[:space:]]*/bin/sh([[:space:]]|$) ]] ; then
- sed -e "1s:^#![[:space:]]*/bin/sh:#!$CONFIG_SHELL:" -i "$ECONF_SOURCE/configure" || \
- die "Substition of shebang in '$ECONF_SOURCE/configure' failed"
+ # preserve timestamp, see bug #440304
+ touch -r "${ECONF_SOURCE}/configure" "${ECONF_SOURCE}/configure._portage_tmp_.${pid}" || die
+ sed -i \
+ -e "1s:^#![[:space:]]*/bin/sh:#!$CONFIG_SHELL:" \
+ "${ECONF_SOURCE}/configure" \
+ || die "Substition of shebang in '${ECONF_SOURCE}/configure' failed"
+ touch -r "${ECONF_SOURCE}/configure._portage_tmp_.${pid}" "${ECONF_SOURCE}/configure" || die
+ rm -f "${ECONF_SOURCE}/configure._portage_tmp_.${pid}"
fi
if [ -e "${EPREFIX}"/usr/share/gnuconfig/ ]; then
find "${WORKDIR}" -type f '(' \
-name config.guess -o -name config.sub ')' -print0 | \
while read -r -d $'\0' x ; do
- vecho " * econf: updating ${x/${WORKDIR}\/} with ${EPREFIX}/usr/share/gnuconfig/${x##*/}"
- cp -f "${EPREFIX}"/usr/share/gnuconfig/"${x##*/}" "${x}"
+ __vecho " * econf: updating ${x/${WORKDIR}\/} with ${EPREFIX}/usr/share/gnuconfig/${x##*/}"
+ # Make sure we do this atomically incase we're run in parallel. #487478
+ cp -f "${EPREFIX}"/usr/share/gnuconfig/"${x##*/}" "${x}.${pid}"
+ mv -f "${x}.${pid}" "${x}"
done
fi
- # EAPI=4 adds --disable-dependency-tracking to econf
- if ! has "$EAPI" 0 1 2 3 3_pre2 && \
- "${ECONF_SOURCE}/configure" --help 2>/dev/null | \
- grep -q disable-dependency-tracking ; then
- set -- --disable-dependency-tracking "$@"
+ if ___eapi_econf_passes_--disable-dependency-tracking || ___eapi_econf_passes_--disable-silent-rules; then
+ local conf_help=$("${ECONF_SOURCE}/configure" --help 2>/dev/null)
+
+ if ___eapi_econf_passes_--disable-dependency-tracking; then
+ case "${conf_help}" in
+ *--disable-dependency-tracking*)
+ set -- --disable-dependency-tracking "$@"
+ ;;
+ esac
+ fi
+
+ if ___eapi_econf_passes_--disable-silent-rules; then
+ case "${conf_help}" in
+ *--disable-silent-rules*)
+ set -- --disable-silent-rules "$@"
+ ;;
+ esac
+ fi
fi
# if the profile defines a location to install libs to aside from default, pass it on.
@@ -433,16 +547,19 @@ econf() {
if [[ -n ${ABI} && -n ${!LIBDIR_VAR} ]] ; then
CONF_LIBDIR=${!LIBDIR_VAR}
fi
- if [[ -n ${CONF_LIBDIR} ]] && ! _hasgq --libdir=\* "$@" ; then
- export CONF_PREFIX=$(_hasg --exec-prefix=\* "$@")
- [[ -z ${CONF_PREFIX} ]] && CONF_PREFIX=$(_hasg --prefix=\* "$@")
+ if [[ -n ${CONF_LIBDIR} ]] && ! __hasgq --libdir=\* "$@" ; then
+ export CONF_PREFIX=$(__hasg --exec-prefix=\* "$@")
+ [[ -z ${CONF_PREFIX} ]] && CONF_PREFIX=$(__hasg --prefix=\* "$@")
: ${CONF_PREFIX:=${EPREFIX}/usr}
CONF_PREFIX=${CONF_PREFIX#*=}
[[ ${CONF_PREFIX} != /* ]] && CONF_PREFIX="/${CONF_PREFIX}"
[[ ${CONF_LIBDIR} != /* ]] && CONF_LIBDIR="/${CONF_LIBDIR}"
- set -- --libdir="$(strip_duplicate_slashes ${CONF_PREFIX}${CONF_LIBDIR})" "$@"
+ set -- --libdir="$(__strip_duplicate_slashes "${CONF_PREFIX}${CONF_LIBDIR}")" "$@"
fi
+ # Handle arguments containing quoted whitespace (see bug #457136).
+ eval "local -a EXTRA_ECONF=(${EXTRA_ECONF})"
+
set -- \
--prefix="${EPREFIX}"/usr \
${CBUILD:+--build=${CBUILD}} \
@@ -454,8 +571,8 @@ econf() {
--sysconfdir="${EPREFIX}"/etc \
--localstatedir="${EPREFIX}"/var/lib \
"$@" \
- ${EXTRA_ECONF}
- vecho "${ECONF_SOURCE}/configure" "$@"
+ "${EXTRA_ECONF[@]}"
+ __vecho "${ECONF_SOURCE}/configure" "$@"
if ! "${ECONF_SOURCE}/configure" "$@" ; then
@@ -476,8 +593,9 @@ econf() {
einstall() {
# CONF_PREFIX is only set if they didn't pass in libdir above.
local LOCAL_EXTRA_EINSTALL="${EXTRA_EINSTALL}"
- [[ " ${FEATURES} " == *" force-prefix "* ]] || \
- case "$EAPI" in 0|1|2) local ED=${D} ;; esac
+ if ! ___eapi_has_prefix_variables; then
+ local ED=${D}
+ fi
LIBDIR_VAR="LIBDIR_${ABI}"
if [ -n "${ABI}" -a -n "${!LIBDIR_VAR}" ]; then
CONF_LIBDIR="${!LIBDIR_VAR}"
@@ -485,7 +603,7 @@ einstall() {
unset LIBDIR_VAR
if [ -n "${CONF_LIBDIR}" ] && [ "${CONF_PREFIX:+set}" = set ]; then
EI_DESTLIBDIR="${D}/${CONF_PREFIX}/${CONF_LIBDIR}"
- EI_DESTLIBDIR="$(strip_duplicate_slashes ${EI_DESTLIBDIR})"
+ EI_DESTLIBDIR="$(__strip_duplicate_slashes "${EI_DESTLIBDIR}")"
LOCAL_EXTRA_EINSTALL="libdir=${EI_DESTLIBDIR} ${LOCAL_EXTRA_EINSTALL}"
unset EI_DESTLIBDIR
fi
@@ -516,7 +634,7 @@ einstall() {
fi
}
-_eapi0_pkg_nofetch() {
+__eapi0_pkg_nofetch() {
[ -z "${SRC_URI}" ] && return
elog "The following are listed in SRC_URI for ${PN}:"
@@ -526,55 +644,59 @@ _eapi0_pkg_nofetch() {
done
}
-_eapi0_src_unpack() {
+__eapi0_src_unpack() {
[[ -n ${A} ]] && unpack ${A}
}
-_eapi0_src_compile() {
+__eapi0_src_compile() {
if [ -x ./configure ] ; then
econf
fi
- _eapi2_src_compile
+ __eapi2_src_compile
}
-_eapi0_src_test() {
+__eapi0_src_test() {
# Since we don't want emake's automatic die
# support (EAPI 4 and later), and we also don't
# want the warning messages that it produces if
# we call it in 'nonfatal' mode, we use emake_cmd
# to emulate the desired parts of emake behavior.
local emake_cmd="${MAKE:-make} ${MAKEOPTS} ${EXTRA_EMAKE}"
- if $emake_cmd -j1 check -n &> /dev/null; then
- vecho ">>> Test phase [check]: ${CATEGORY}/${PF}"
- $emake_cmd -j1 check || \
+ local internal_opts=
+ if ___eapi_default_src_test_disables_parallel_jobs; then
+ internal_opts+=" -j1"
+ fi
+ if $emake_cmd ${internal_opts} check -n &> /dev/null; then
+ __vecho ">>> Test phase [check]: ${CATEGORY}/${PF}"
+ $emake_cmd ${internal_opts} check || \
die "Make check failed. See above for details."
- elif $emake_cmd -j1 test -n &> /dev/null; then
- vecho ">>> Test phase [test]: ${CATEGORY}/${PF}"
- $emake_cmd -j1 test || \
+ elif $emake_cmd ${internal_opts} test -n &> /dev/null; then
+ __vecho ">>> Test phase [test]: ${CATEGORY}/${PF}"
+ $emake_cmd ${internal_opts} test || \
die "Make test failed. See above for details."
else
- vecho ">>> Test phase [none]: ${CATEGORY}/${PF}"
+ __vecho ">>> Test phase [none]: ${CATEGORY}/${PF}"
fi
}
-_eapi1_src_compile() {
- _eapi2_src_configure
- _eapi2_src_compile
+__eapi1_src_compile() {
+ __eapi2_src_configure
+ __eapi2_src_compile
}
-_eapi2_src_configure() {
+__eapi2_src_configure() {
if [[ -x ${ECONF_SOURCE:-.}/configure ]] ; then
econf
fi
}
-_eapi2_src_compile() {
+__eapi2_src_compile() {
if [ -f Makefile ] || [ -f GNUmakefile ] || [ -f makefile ]; then
emake || die "emake failed"
fi
}
-_eapi4_src_install() {
+__eapi4_src_install() {
if [[ -f Makefile || -f GNUmakefile || -f makefile ]] ; then
emake DESTDIR="${D}" install
fi
@@ -593,71 +715,285 @@ _eapi4_src_install() {
}
# @FUNCTION: has_version
-# @USAGE: <DEPEND ATOM>
+# @USAGE: [--host-root] <DEPEND ATOM>
# @DESCRIPTION:
# Return true if given package is installed. Otherwise return false.
# Callers may override the ROOT variable in order to match packages from an
# alternative ROOT.
has_version() {
- local eroot
- case "$EAPI" in
- 0|1|2)
- [[ " ${FEATURES} " == *" force-prefix "* ]] && \
- eroot=${ROOT%/}${EPREFIX}/ || eroot=${ROOT}
- ;;
- *)
- eroot=${ROOT%/}${EPREFIX}/
- ;;
- esac
+ local atom eroot host_root=false root=${ROOT}
+ if [[ $1 == --host-root ]] ; then
+ host_root=true
+ shift
+ fi
+ atom=$1
+ shift
+ [ $# -gt 0 ] && die "${FUNCNAME[0]}: unused argument(s): $*"
+
+ if ${host_root} ; then
+ if ! ___eapi_best_version_and_has_version_support_--host-root; then
+ die "${FUNCNAME[0]}: option --host-root is not supported with EAPI ${EAPI}"
+ fi
+ root=/
+ fi
+
+ if ___eapi_has_prefix_variables; then
+ # [[ ${root} == / ]] would be ambiguous here,
+ # since both prefixes can share root=/ while
+ # having different EPREFIX offsets.
+ if ${host_root} ; then
+ eroot=${root%/}${PORTAGE_OVERRIDE_EPREFIX}/
+ else
+ eroot=${root%/}${EPREFIX}/
+ fi
+ else
+ eroot=${root}
+ fi
if [[ -n $PORTAGE_IPC_DAEMON ]] ; then
- "$PORTAGE_BIN_PATH"/ebuild-ipc has_version "${eroot}" "$1"
+ "$PORTAGE_BIN_PATH"/ebuild-ipc has_version "${eroot}" "${atom}"
else
- PYTHONPATH=${PORTAGE_PYM_PATH}${PYTHONPATH:+:}${PYTHONPATH} \
- "${PORTAGE_PYTHON:-/usr/bin/python}" "${PORTAGE_BIN_PATH}/portageq" has_version "${eroot}" "$1"
+ "${PORTAGE_BIN_PATH}/ebuild-helpers/portageq" has_version "${eroot}" "${atom}"
fi
local retval=$?
case "${retval}" in
0|1)
return ${retval}
;;
+ 2)
+ die "${FUNCNAME[0]}: invalid atom: ${atom}"
+ ;;
*)
- die "unexpected portageq exit code: ${retval}"
+ if [[ -n ${PORTAGE_IPC_DAEMON} ]]; then
+ die "${FUNCNAME[0]}: unexpected ebuild-ipc exit code: ${retval}"
+ else
+ die "${FUNCNAME[0]}: unexpected portageq exit code: ${retval}"
+ fi
;;
esac
}
# @FUNCTION: best_version
-# @USAGE: <DEPEND ATOM>
+# @USAGE: [--host-root] <DEPEND ATOM>
# @DESCRIPTION:
# Returns the best/most-current match.
# Callers may override the ROOT variable in order to match packages from an
# alternative ROOT.
best_version() {
- local eroot
- case "$EAPI" in
- 0|1|2)
- [[ " ${FEATURES} " == *" force-prefix "* ]] && \
- eroot=${ROOT%/}${EPREFIX}/ || eroot=${ROOT}
- ;;
- *)
- eroot=${ROOT%/}${EPREFIX}/
- ;;
- esac
+ local atom eroot host_root=false root=${ROOT}
+ if [[ $1 == --host-root ]] ; then
+ host_root=true
+ shift
+ fi
+ atom=$1
+ shift
+ [ $# -gt 0 ] && die "${FUNCNAME[0]}: unused argument(s): $*"
+
+ if ${host_root} ; then
+ if ! ___eapi_best_version_and_has_version_support_--host-root; then
+ die "${FUNCNAME[0]}: option --host-root is not supported with EAPI ${EAPI}"
+ fi
+ root=/
+ fi
+
+ if ___eapi_has_prefix_variables; then
+ # [[ ${root} == / ]] would be ambiguous here,
+ # since both prefixes can share root=/ while
+ # having different EPREFIX offsets.
+ if ${host_root} ; then
+ eroot=${root%/}${PORTAGE_OVERRIDE_EPREFIX}/
+ else
+ eroot=${root%/}${EPREFIX}/
+ fi
+ else
+ eroot=${root}
+ fi
if [[ -n $PORTAGE_IPC_DAEMON ]] ; then
- "$PORTAGE_BIN_PATH"/ebuild-ipc best_version "${eroot}" "$1"
+ "$PORTAGE_BIN_PATH"/ebuild-ipc best_version "${eroot}" "${atom}"
else
- PYTHONPATH=${PORTAGE_PYM_PATH}${PYTHONPATH:+:}${PYTHONPATH} \
- "${PORTAGE_PYTHON:-/usr/bin/python}" "${PORTAGE_BIN_PATH}/portageq" best_version "${eroot}" "$1"
+ "${PORTAGE_BIN_PATH}/ebuild-helpers/portageq" best_version "${eroot}" "${atom}"
fi
local retval=$?
case "${retval}" in
0|1)
return ${retval}
;;
+ 2)
+ die "${FUNCNAME[0]}: invalid atom: ${atom}"
+ ;;
*)
- die "unexpected portageq exit code: ${retval}"
+ if [[ -n ${PORTAGE_IPC_DAEMON} ]]; then
+ die "${FUNCNAME[0]}: unexpected ebuild-ipc exit code: ${retval}"
+ else
+ die "${FUNCNAME[0]}: unexpected portageq exit code: ${retval}"
+ fi
;;
esac
}
+
+if ___eapi_has_master_repositories; then
+ master_repositories() {
+ local output repository=$1 retval
+ shift
+ [[ $# -gt 0 ]] && die "${FUNCNAME[0]}: unused argument(s): $*"
+
+ if [[ -n ${PORTAGE_IPC_DAEMON} ]]; then
+ "${PORTAGE_BIN_PATH}/ebuild-ipc" master_repositories "${EROOT}" "${repository}"
+ else
+ output=$("${PORTAGE_BIN_PATH}/ebuild-helpers/portageq" master_repositories "${EROOT}" "${repository}")
+ fi
+ retval=$?
+ [[ -n ${output} ]] && echo "${output}"
+ case "${retval}" in
+ 0|1)
+ return ${retval}
+ ;;
+ 2)
+ die "${FUNCNAME[0]}: invalid repository: ${repository}"
+ ;;
+ *)
+ if [[ -n ${PORTAGE_IPC_DAEMON} ]]; then
+ die "${FUNCNAME[0]}: unexpected ebuild-ipc exit code: ${retval}"
+ else
+ die "${FUNCNAME[0]}: unexpected portageq exit code: ${retval}"
+ fi
+ ;;
+ esac
+ }
+fi
+
+if ___eapi_has_repository_path; then
+ repository_path() {
+ local output repository=$1 retval
+ shift
+ [[ $# -gt 0 ]] && die "${FUNCNAME[0]}: unused argument(s): $*"
+
+ if [[ -n ${PORTAGE_IPC_DAEMON} ]]; then
+ "${PORTAGE_BIN_PATH}/ebuild-ipc" repository_path "${EROOT}" "${repository}"
+ else
+ output=$("${PORTAGE_BIN_PATH}/ebuild-helpers/portageq" get_repo_path "${EROOT}" "${repository}")
+ fi
+ retval=$?
+ [[ -n ${output} ]] && echo "${output}"
+ case "${retval}" in
+ 0|1)
+ return ${retval}
+ ;;
+ 2)
+ die "${FUNCNAME[0]}: invalid repository: ${repository}"
+ ;;
+ *)
+ if [[ -n ${PORTAGE_IPC_DAEMON} ]]; then
+ die "${FUNCNAME[0]}: unexpected ebuild-ipc exit code: ${retval}"
+ else
+ die "${FUNCNAME[0]}: unexpected portageq exit code: ${retval}"
+ fi
+ ;;
+ esac
+ }
+fi
+
+if ___eapi_has_available_eclasses; then
+ available_eclasses() {
+ local output repository=${PORTAGE_REPO_NAME} retval
+ [[ $# -gt 0 ]] && die "${FUNCNAME[0]}: unused argument(s): $*"
+
+ if [[ -n ${PORTAGE_IPC_DAEMON} ]]; then
+ "${PORTAGE_BIN_PATH}/ebuild-ipc" available_eclasses "${EROOT}" "${repository}"
+ else
+ output=$("${PORTAGE_BIN_PATH}/ebuild-helpers/portageq" available_eclasses "${EROOT}" "${repository}")
+ fi
+ retval=$?
+ [[ -n ${output} ]] && echo "${output}"
+ case "${retval}" in
+ 0|1)
+ return ${retval}
+ ;;
+ 2)
+ die "${FUNCNAME[0]}: invalid repository: ${repository}"
+ ;;
+ *)
+ if [[ -n ${PORTAGE_IPC_DAEMON} ]]; then
+ die "${FUNCNAME[0]}: unexpected ebuild-ipc exit code: ${retval}"
+ else
+ die "${FUNCNAME[0]}: unexpected portageq exit code: ${retval}"
+ fi
+ ;;
+ esac
+ }
+fi
+
+if ___eapi_has_eclass_path; then
+ eclass_path() {
+ local eclass=$1 output repository=${PORTAGE_REPO_NAME} retval
+ shift
+ [[ $# -gt 0 ]] && die "${FUNCNAME[0]}: unused argument(s): $*"
+
+ if [[ -n ${PORTAGE_IPC_DAEMON} ]]; then
+ "${PORTAGE_BIN_PATH}/ebuild-ipc" eclass_path "${EROOT}" "${repository}" "${eclass}"
+ else
+ output=$("${PORTAGE_BIN_PATH}/ebuild-helpers/portageq" eclass_path "${EROOT}" "${repository}" "${eclass}")
+ fi
+ retval=$?
+ [[ -n ${output} ]] && echo "${output}"
+ case "${retval}" in
+ 0|1)
+ return ${retval}
+ ;;
+ 2)
+ die "${FUNCNAME[0]}: invalid repository: ${repository}"
+ ;;
+ *)
+ if [[ -n ${PORTAGE_IPC_DAEMON} ]]; then
+ die "${FUNCNAME[0]}: unexpected ebuild-ipc exit code: ${retval}"
+ else
+ die "${FUNCNAME[0]}: unexpected portageq exit code: ${retval}"
+ fi
+ ;;
+ esac
+ }
+fi
+
+if ___eapi_has_license_path; then
+ license_path() {
+ local license=$1 output repository=${PORTAGE_REPO_NAME} retval
+ shift
+ [[ $# -gt 0 ]] && die "${FUNCNAME[0]}: unused argument(s): $*"
+
+ if [[ -n ${PORTAGE_IPC_DAEMON} ]]; then
+ "${PORTAGE_BIN_PATH}/ebuild-ipc" license_path "${EROOT}" "${repository}" "${license}"
+ else
+ output=$("${PORTAGE_BIN_PATH}/ebuild-helpers/portageq" license_path "${EROOT}" "${repository}" "${license}")
+ fi
+ retval=$?
+ [[ -n ${output} ]] && echo "${output}"
+ case "${retval}" in
+ 0|1)
+ return ${retval}
+ ;;
+ 2)
+ die "${FUNCNAME[0]}: invalid repository: ${repository}"
+ ;;
+ *)
+ if [[ -n ${PORTAGE_IPC_DAEMON} ]]; then
+ die "${FUNCNAME[0]}: unexpected ebuild-ipc exit code: ${retval}"
+ else
+ die "${FUNCNAME[0]}: unexpected portageq exit code: ${retval}"
+ fi
+ ;;
+ esac
+ }
+fi
+
+if ___eapi_has_package_manager_build_user; then
+ package_manager_build_user() {
+ echo "${PORTAGE_BUILD_USER}"
+ }
+fi
+
+if ___eapi_has_package_manager_build_group; then
+ package_manager_build_group() {
+ echo "${PORTAGE_BUILD_GROUP}"
+ }
+fi
diff --git a/bin/portageq b/bin/portageq
index d9abb0bad..79818f679 100755
--- a/bin/portageq
+++ b/bin/portageq
@@ -1,15 +1,15 @@
-#!/usr/bin/python -O
-# Copyright 1999-2012 Gentoo Foundation
+#!/usr/bin/python -bO
+# Copyright 1999-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-from __future__ import print_function
+from __future__ import print_function, unicode_literals
import signal
import sys
# This block ensures that ^C interrupts are handled quietly.
try:
- def exithandler(signum, frame):
+ def exithandler(signum, _frame):
signal.signal(signal.SIGINT, signal.SIG_IGN)
signal.signal(signal.SIGTERM, signal.SIG_IGN)
sys.exit(128 + signum)
@@ -34,23 +34,22 @@ if os.environ.get("SANDBOX_ON") == "1":
":".join(filter(None, sandbox_write))
del sandbox_write
-try:
- import portage
-except ImportError:
- sys.path.insert(0, pym_path)
- import portage
-del pym_path
-
+sys.path.insert(0, pym_path)
+import portage
+portage._internal_caller = True
from portage import os
from portage.eapi import eapi_has_repo_deps
from portage.util import writemsg, writemsg_stdout
-from portage.output import colormap
+from portage.util._argparse import ArgumentParser
portage.proxy.lazyimport.lazyimport(globals(),
+ 're',
'subprocess',
'_emerge.Package:Package',
'_emerge.RootConfig:RootConfig',
+ '_emerge.is_valid_package_atom:insert_category_into_atom',
'portage.dbapi._expand_new_virt:expand_new_virt',
'portage._sets.base:InternalPackageSet',
+ 'portage.xml.metadata:MetaDataXML'
)
def eval_atom_use(atom):
@@ -59,6 +58,10 @@ def eval_atom_use(atom):
atom = atom.evaluate_conditionals(use)
return atom
+def uses_eroot(function):
+ function.uses_eroot = True
+ return function
+
#-----------------------------------------------------------------------------
#
# To add functionality to this tool, add a function below.
@@ -80,13 +83,14 @@ def eval_atom_use(atom):
# and will automaticly add a command by the same name as the function!
#
+@uses_eroot
def has_version(argv):
"""<eroot> <category/package>
Return code 0 if it's available, 1 otherwise.
"""
if (len(argv) < 2):
print("ERROR: insufficient parameters!")
- return 2
+ return 3
warnings = []
@@ -105,9 +109,7 @@ def has_version(argv):
try:
atom = portage.dep.Atom(argv[1], allow_repo=allow_repo, eapi=eapi)
except portage.exception.InvalidAtom as e:
- warnings.append(
- portage._unicode_decode("QA Notice: %s: %s") % \
- ('has_version', e))
+ warnings.append("QA Notice: %s: %s" % ('has_version', e))
atom = eval_atom_use(atom)
if warnings:
@@ -125,16 +127,16 @@ def has_version(argv):
portage.writemsg("ERROR: Invalid atom: '%s'\n" % argv[1],
noiselevel=-1)
return 2
-has_version.uses_root = True
+@uses_eroot
def best_version(argv):
"""<eroot> <category/package>
Returns category/package-version (without .ebuild).
"""
if (len(argv) < 2):
print("ERROR: insufficient parameters!")
- return 2
+ return 3
warnings = []
@@ -153,9 +155,7 @@ def best_version(argv):
try:
atom = portage.dep.Atom(argv[1], allow_repo=allow_repo, eapi=eapi)
except portage.exception.InvalidAtom as e:
- warnings.append(
- portage._unicode_decode("QA Notice: %s: %s") % \
- ('best_version', e))
+ warnings.append("QA Notice: %s: %s" % ('best_version', e))
atom = eval_atom_use(atom)
if warnings:
@@ -166,9 +166,9 @@ def best_version(argv):
print(portage.best(mylist))
except KeyError:
return 1
-best_version.uses_root = True
+@uses_eroot
def mass_best_version(argv):
"""<eroot> [<category/package>]+
Returns category/package-version (without .ebuild).
@@ -178,23 +178,25 @@ def mass_best_version(argv):
return 2
try:
for pack in argv[1:]:
- mylist=portage.db[argv[0]]["vartree"].dbapi.match(pack)
- print(pack+":"+portage.best(mylist))
+ mylist = portage.db[argv[0]]['vartree'].dbapi.match(pack)
+ print('%s:%s' % (pack, portage.best(mylist)))
except KeyError:
return 1
-mass_best_version.uses_root = True
+
+@uses_eroot
def metadata(argv):
if (len(argv) < 4):
- print("ERROR: insufficient parameters!", file=sys.stderr)
+ print('ERROR: insufficient parameters!', file=sys.stderr)
return 2
eroot, pkgtype, pkgspec = argv[0:3]
metakeys = argv[3:]
type_map = {
- "ebuild":"porttree",
- "binary":"bintree",
- "installed":"vartree"}
+ 'ebuild': 'porttree',
+ 'binary': 'bintree',
+ 'installed': 'vartree'
+ }
if pkgtype not in type_map:
print("Unrecognized package type: '%s'" % pkgtype, file=sys.stderr)
return 1
@@ -202,9 +204,9 @@ def metadata(argv):
repo = portage.dep.dep_getrepo(pkgspec)
pkgspec = portage.dep.remove_slot(pkgspec)
try:
- values = trees[eroot][type_map[pkgtype]].dbapi.aux_get(
- pkgspec, metakeys, myrepo=repo)
- writemsg_stdout(''.join('%s\n' % x for x in values), noiselevel=-1)
+ values = trees[eroot][type_map[pkgtype]].dbapi.aux_get(
+ pkgspec, metakeys, myrepo=repo)
+ writemsg_stdout(''.join('%s\n' % x for x in values), noiselevel=-1)
except KeyError:
print("Package not found: '%s'" % pkgspec, file=sys.stderr)
return 1
@@ -216,8 +218,8 @@ Available keys: %s
""" % ','.join(sorted(x for x in portage.auxdbkeys \
if not x.startswith('UNUSED_')))
-metadata.uses_root = True
+@uses_eroot
def contents(argv):
"""<eroot> <category/package>
List the files that are installed for a given package, with
@@ -238,8 +240,9 @@ def contents(argv):
treetype="vartree", vartree=vartree)
writemsg_stdout(''.join('%s\n' % x for x in sorted(db.getcontents())),
noiselevel=-1)
-contents.uses_root = True
+
+@uses_eroot
def owners(argv):
"""<eroot> [<filename>]+
Given a list of files, print the packages that own the files and which
@@ -253,7 +256,6 @@ def owners(argv):
sys.stderr.flush()
return 2
- from portage import catsplit, dblink
eroot = argv[0]
vardb = portage.db[eroot]["vartree"].dbapi
root = portage.settings['ROOT']
@@ -319,8 +321,8 @@ def owners(argv):
return 0
return 1
-owners.uses_root = True
+@uses_eroot
def is_protected(argv):
"""<eroot> <filename>
Given a single filename, return code 0 if it's protected, 1 otherwise.
@@ -366,8 +368,8 @@ def is_protected(argv):
return 0
return 1
-is_protected.uses_root = True
+@uses_eroot
def filter_protected(argv):
"""<eroot>
Read filenames from stdin and write them to stdout if they are protected.
@@ -395,7 +397,6 @@ def filter_protected(argv):
settings.get("CONFIG_PROTECT_MASK", ""))
protect_obj = ConfigProtect(root, protect, protect_mask)
- protected = 0
errors = 0
for line in sys.stdin:
@@ -417,7 +418,6 @@ def filter_protected(argv):
continue
if protect_obj.isprotected(f):
- protected += 1
out.write("%s\n" % filename)
out.flush()
@@ -426,8 +426,8 @@ def filter_protected(argv):
return 0
-filter_protected.uses_root = True
+@uses_eroot
def best_visible(argv):
"""<eroot> [pkgtype] <atom>
Returns category/package-version (without .ebuild).
@@ -465,8 +465,7 @@ def best_visible(argv):
noiselevel=-1)
return 2
- root_config = RootConfig(portage.settings,
- portage.db[eroot], None)
+ root_config = RootConfig(portage.settings, portage.db[eroot], None)
if hasattr(db, "xmatch"):
cpv_list = db.xmatch("match-all-cpv-only", atom)
@@ -508,11 +507,11 @@ def best_visible(argv):
writemsg_stdout("\n", noiselevel=-1)
return 1
-best_visible.uses_root = True
+@uses_eroot
def mass_best_visible(argv):
- """<root> [<type>] [<category/package>]+
+ """<eroot> [<type>] [<category/package>]+
Returns category/package-version (without .ebuild).
The pkgtype argument defaults to "ebuild" if unspecified,
otherwise it must be one of ebuild, binary, or installed.
@@ -535,9 +534,9 @@ def mass_best_visible(argv):
best_visible([root, pkgtype, pack])
except KeyError:
return 1
-mass_best_visible.uses_root = True
+@uses_eroot
def all_best_visible(argv):
"""<eroot>
Returns all best_visible packages (without .ebuild).
@@ -552,9 +551,9 @@ def all_best_visible(argv):
mybest=portage.best(portage.db[argv[0]]["porttree"].dbapi.match(pkg))
if mybest:
print(mybest)
-all_best_visible.uses_root = True
+@uses_eroot
def match(argv):
"""<eroot> <atom>
Returns a \\n separated list of category/package-version.
@@ -601,8 +600,9 @@ def match(argv):
results = vardb.match(atom)
for cpv in results:
print(cpv)
-match.uses_root = True
+
+@uses_eroot
def expand_virtual(argv):
"""<eroot> <atom>
Returns a \\n separated list of atoms expanded from a
@@ -637,9 +637,8 @@ def expand_virtual(argv):
return os.EX_OK
-expand_virtual.uses_root = True
-def vdb_path(argv):
+def vdb_path(_argv):
"""
Returns the path used for the var(installed) package database for the
set environment/configuration options.
@@ -649,56 +648,79 @@ def vdb_path(argv):
out.flush()
return os.EX_OK
-def gentoo_mirrors(argv):
+def gentoo_mirrors(_argv):
"""
Returns the mirrors set to use in the portage configuration.
"""
print(portage.settings["GENTOO_MIRRORS"])
-def portdir(argv):
+@uses_eroot
+def repositories_configuration(argv):
+ """<eroot>
+ Returns the configuration of repositories.
+ """
+ if len(argv) < 1:
+ print("ERROR: insufficient parameters!", file=sys.stderr)
+ return 3
+ sys.stdout.write(portage.db[argv[0]]["vartree"].settings.repositories.config_string())
+ sys.stdout.flush()
+
+@uses_eroot
+def repos_config(argv):
+ """
+ <eroot>
+ This is an alias for the repositories_configuration command.
+ """
+ return repositories_configuration(argv)
+
+def portdir(_argv):
"""
Returns the PORTDIR path.
+ Deprecated in favor of repositories_configuration command.
"""
+ print("WARNING: 'portageq portdir' is deprecated. Use 'portageq repositories_configuration' instead.", file=sys.stderr)
print(portage.settings["PORTDIR"])
-def config_protect(argv):
+def config_protect(_argv):
"""
Returns the CONFIG_PROTECT paths.
"""
print(portage.settings["CONFIG_PROTECT"])
-def config_protect_mask(argv):
+def config_protect_mask(_argv):
"""
Returns the CONFIG_PROTECT_MASK paths.
"""
print(portage.settings["CONFIG_PROTECT_MASK"])
-def portdir_overlay(argv):
+def portdir_overlay(_argv):
"""
Returns the PORTDIR_OVERLAY path.
+ Deprecated in favor of repositories_configuration command.
"""
+ print("WARNING: 'portageq portdir_overlay' is deprecated. Use 'portageq repositories_configuration' instead.", file=sys.stderr)
print(portage.settings["PORTDIR_OVERLAY"])
-def pkgdir(argv):
+def pkgdir(_argv):
"""
Returns the PKGDIR path.
"""
print(portage.settings["PKGDIR"])
-def distdir(argv):
+def distdir(_argv):
"""
Returns the DISTDIR path.
"""
print(portage.settings["DISTDIR"])
-def colormap(argv):
+def colormap(_argv):
"""
Display the color.map as environment variables.
"""
@@ -719,11 +741,15 @@ def envvar(argv):
return 2
for arg in argv:
+ if arg in ("PORTDIR", "PORTDIR_OVERLAY", "SYNC"):
+ print("WARNING: 'portageq envvar %s' is deprecated. Use 'portageq repositories_configuration' instead." % arg, file=sys.stderr)
if verbose:
- print(arg +"='"+ portage.settings[arg] +"'")
+ print(arg + "=" + portage._shell_quote(portage.settings[arg]))
else:
print(portage.settings[arg])
+
+@uses_eroot
def get_repos(argv):
"""<eroot>
Returns all repos with names (repo_name file) argv[0] = $EROOT
@@ -731,25 +757,137 @@ def get_repos(argv):
if len(argv) < 1:
print("ERROR: insufficient parameters!")
return 2
- print(" ".join(portage.db[argv[0]]["porttree"].dbapi.getRepositories()))
+ print(" ".join(reversed(portage.db[argv[0]]["vartree"].settings.repositories.prepos_order)))
+
+
+@uses_eroot
+def master_repositories(argv):
+ """<eroot> <repo_id>+
+ Returns space-separated list of master repositories for specified repository.
+ """
+ if len(argv) < 2:
+ print("ERROR: insufficient parameters!", file=sys.stderr)
+ return 3
+ for arg in argv[1:]:
+ if portage.dep._repo_name_re.match(arg) is None:
+ print("ERROR: invalid repository: %s" % arg, file=sys.stderr)
+ return 2
+ try:
+ repo = portage.db[argv[0]]["vartree"].settings.repositories[arg]
+ except KeyError:
+ print("")
+ return 1
+ else:
+ print(" ".join(x.name for x in repo.masters))
-get_repos.uses_root = True
+@uses_eroot
+def master_repos(argv):
+ """<eroot> <repo_id>+
+ This is an alias for the master_repositories command.
+ """
+ return master_repositories(argv)
+@uses_eroot
def get_repo_path(argv):
"""<eroot> <repo_id>+
Returns the path to the repo named argv[1], argv[0] = $EROOT
"""
if len(argv) < 2:
- print("ERROR: insufficient parameters!")
- return 2
+ print("ERROR: insufficient parameters!", file=sys.stderr)
+ return 3
for arg in argv[1:]:
- path = portage.db[argv[0]]["porttree"].dbapi.getRepositoryPath(arg)
+ if portage.dep._repo_name_re.match(arg) is None:
+ print("ERROR: invalid repository: %s" % arg, file=sys.stderr)
+ return 2
+ path = portage.db[argv[0]]["vartree"].settings.repositories.treemap.get(arg)
if path is None:
- path = ""
+ print("")
+ return 1
print(path)
-get_repo_path.uses_root = True
+@uses_eroot
+def available_eclasses(argv):
+ """<eroot> <repo_id>+
+ Returns space-separated list of available eclasses for specified repository.
+ """
+ if len(argv) < 2:
+ print("ERROR: insufficient parameters!", file=sys.stderr)
+ return 3
+ for arg in argv[1:]:
+ if portage.dep._repo_name_re.match(arg) is None:
+ print("ERROR: invalid repository: %s" % arg, file=sys.stderr)
+ return 2
+ try:
+ repo = portage.db[argv[0]]["vartree"].settings.repositories[arg]
+ except KeyError:
+ print("")
+ return 1
+ else:
+ print(" ".join(sorted(repo.eclass_db.eclasses)))
+
+
+@uses_eroot
+def eclass_path(argv):
+ """<eroot> <repo_id> <eclass>+
+ Returns the path to specified eclass for specified repository.
+ """
+ if len(argv) < 3:
+ print("ERROR: insufficient parameters!", file=sys.stderr)
+ return 3
+ if portage.dep._repo_name_re.match(argv[1]) is None:
+ print("ERROR: invalid repository: %s" % argv[1], file=sys.stderr)
+ return 2
+ try:
+ repo = portage.db[argv[0]]["vartree"].settings.repositories[argv[1]]
+ except KeyError:
+ print("")
+ return 1
+ else:
+ retval = 0
+ for arg in argv[2:]:
+ try:
+ eclass = repo.eclass_db.eclasses[arg]
+ except KeyError:
+ print("")
+ retval = 1
+ else:
+ print(eclass.location)
+ return retval
+
+
+@uses_eroot
+def license_path(argv):
+ """<eroot> <repo_id> <license>+
+ Returns the path to specified license for specified repository.
+ """
+ if len(argv) < 3:
+ print("ERROR: insufficient parameters!", file=sys.stderr)
+ return 3
+ if portage.dep._repo_name_re.match(argv[1]) is None:
+ print("ERROR: invalid repository: %s" % argv[1], file=sys.stderr)
+ return 2
+ try:
+ repo = portage.db[argv[0]]["vartree"].settings.repositories[argv[1]]
+ except KeyError:
+ print("")
+ return 1
+ else:
+ retval = 0
+ for arg in argv[2:]:
+ eclass_path = ""
+ paths = reversed([os.path.join(x.location, 'licenses', arg) for x in list(repo.masters) + [repo]])
+ for path in paths:
+ if os.path.exists(path):
+ eclass_path = path
+ break
+ if eclass_path == "":
+ retval = 1
+ print(eclass_path)
+ return retval
+
+
+@uses_eroot
def list_preserved_libs(argv):
"""<eroot>
Print a list of libraries preserved during a package update in the form
@@ -771,21 +909,296 @@ def list_preserved_libs(argv):
msg.append('\n')
writemsg_stdout(''.join(msg), noiselevel=-1)
return rValue
-list_preserved_libs.uses_root = True
+
+
+class MaintainerEmailMatcher(object):
+ def __init__(self, maintainer_emails):
+ self._re = re.compile("^(%s)$" % "|".join(maintainer_emails))
+
+ def __call__(self, metadata_xml):
+ match = False
+ matcher = self._re.match
+ for x in metadata_xml.maintainers():
+ if x.email is not None and matcher(x.email) is not None:
+ match = True
+ break
+ return match
+
+class HerdMatcher(object):
+ def __init__(self, herds):
+ self._herds = frozenset(herds)
+
+ def __call__(self, metadata_xml):
+ herds = self._herds
+ return any(x in herds for x in metadata_xml.herds())
+
+
+def pquery(parser, opts, args):
+ """[options] [atom]+
+ Emulates a subset of Pkgcore's pquery tool.
+ """
+
+ portdb = portage.db[portage.root]['porttree'].dbapi
+ root_config = RootConfig(portdb.settings,
+ portage.db[portage.root], None)
+
+ def _pkg(cpv, repo_name):
+ try:
+ metadata = dict(zip(
+ Package.metadata_keys,
+ portdb.aux_get(cpv,
+ Package.metadata_keys,
+ myrepo=repo_name)))
+ except KeyError:
+ raise portage.exception.PackageNotFound(cpv)
+ return Package(built=False, cpv=cpv,
+ installed=False, metadata=metadata,
+ root_config=root_config,
+ type_name="ebuild")
+
+ need_metadata = False
+ atoms = []
+ for arg in args:
+ if "/" not in arg.split(":")[0]:
+ atom = insert_category_into_atom(arg, '*')
+ if atom is None:
+ writemsg("ERROR: Invalid atom: '%s'\n" % arg,
+ noiselevel=-1)
+ return 2
+ else:
+ atom = arg
+
+ try:
+ atom = portage.dep.Atom(atom, allow_wildcard=True, allow_repo=True)
+ except portage.exception.InvalidAtom:
+ writemsg("ERROR: Invalid atom: '%s'\n" % arg,
+ noiselevel=-1)
+ return 2
+
+ if atom.slot is not None:
+ need_metadata = True
+
+ atoms.append(atom)
+
+ if "*/*" in atoms:
+ del atoms[:]
+ need_metadata = False
+
+ if not opts.no_filters:
+ need_metadata = True
+
+ xml_matchers = []
+ if opts.maintainer_email:
+ maintainer_emails = []
+ for x in opts.maintainer_email:
+ maintainer_emails.extend(x.split(","))
+ xml_matchers.append(MaintainerEmailMatcher(maintainer_emails))
+ if opts.herd is not None:
+ herds = []
+ for x in opts.herd:
+ herds.extend(x.split(","))
+ xml_matchers.append(HerdMatcher(herds))
+
+ repos = []
+ if opts.all_repos:
+ repos.extend(portdb.repositories.get_repo_for_location(location)
+ for location in portdb.porttrees)
+ elif opts.repo is not None:
+ repos.append(portdb.repositories[opts.repo])
+ else:
+ repos.append(portdb.repositories.mainRepo())
+
+ if not atoms:
+ names = None
+ categories = list(portdb.categories)
+ else:
+ category_wildcard = False
+ name_wildcard = False
+ categories = []
+ names = []
+ for atom in atoms:
+ category, name = portage.catsplit(atom.cp)
+ categories.append(category)
+ names.append(name)
+ if "*" in category:
+ category_wildcard = True
+ if "*" in name:
+ name_wildcard = True
+
+ if category_wildcard:
+ categories = list(portdb.categories)
+ else:
+ categories = list(set(categories))
+
+ if name_wildcard:
+ names = None
+ else:
+ names = sorted(set(names))
+
+ no_version = opts.no_version
+ categories.sort()
+
+ for category in categories:
+ if names is None:
+ cp_list = portdb.cp_all(categories=(category,))
+ else:
+ cp_list = [category + "/" + name for name in names]
+ for cp in cp_list:
+ matches = []
+ for repo in repos:
+ match = True
+ if xml_matchers:
+ metadata_xml_path = os.path.join(
+ repo.location, cp, 'metadata.xml')
+ try:
+ metadata_xml = MetaDataXML(metadata_xml_path, None)
+ except (EnvironmentError, SyntaxError):
+ match = False
+ else:
+ for matcher in xml_matchers:
+ if not matcher(metadata_xml):
+ match = False
+ break
+ if not match:
+ continue
+ cpv_list = portdb.cp_list(cp, mytree=[repo.location])
+ if atoms:
+ for cpv in cpv_list:
+ pkg = None
+ for atom in atoms:
+ if atom.repo is not None and \
+ atom.repo != repo.name:
+ continue
+ if not portage.match_from_list(atom, [cpv]):
+ continue
+ if need_metadata:
+ if pkg is None:
+ try:
+ pkg = _pkg(cpv, repo.name)
+ except portage.exception.PackageNotFound:
+ continue
+
+ if not (opts.no_filters or pkg.visible):
+ continue
+ if not portage.match_from_list(atom, [pkg]):
+ continue
+ matches.append(cpv)
+ break
+ if no_version and matches:
+ break
+ elif opts.no_filters:
+ matches.extend(cpv_list)
+ else:
+ for cpv in cpv_list:
+ try:
+ pkg = _pkg(cpv, repo.name)
+ except portage.exception.PackageNotFound:
+ continue
+ else:
+ if pkg.visible:
+ matches.append(cpv)
+ if no_version:
+ break
+
+ if no_version and matches:
+ break
+
+ if not matches:
+ continue
+
+ if no_version:
+ writemsg_stdout("%s\n" % (cp,), noiselevel=-1)
+ else:
+ matches = list(set(matches))
+ portdb._cpv_sort_ascending(matches)
+ for cpv in matches:
+ writemsg_stdout("%s\n" % (cpv,), noiselevel=-1)
+
+ return os.EX_OK
+
#-----------------------------------------------------------------------------
#
# DO NOT CHANGE CODE BEYOND THIS POINT - IT'S NOT NEEDED!
#
-if not portage.const._ENABLE_PRESERVE_LIBS:
- del list_preserved_libs
-
-non_commands = frozenset(['elog', 'eval_atom_use',
- 'exithandler', 'expand_new_virt', 'main',
- 'usage', 'writemsg', 'writemsg_stdout'])
+non_commands = frozenset(['elog', 'eval_atom_use', 'exithandler', 'main', 'usage', 'uses_eroot'])
commands = sorted(k for k, v in globals().items() \
- if k not in non_commands and isinstance(v, types.FunctionType))
+ if k not in non_commands and isinstance(v, types.FunctionType) and v.__module__ == "__main__")
+
+
+def add_pquery_arguments(parser):
+ pquery_option_groups = (
+ (
+ 'Repository matching options',
+ (
+ {
+ "longopt": "--no-filters",
+ "action": "store_true",
+ "help": "no visibility filters (ACCEPT_KEYWORDS, package masking, etc)"
+ },
+ {
+ "longopt": "--repo",
+ "help": "repo to use (default is PORTDIR if omitted)"
+ },
+ {
+ "longopt": "--all-repos",
+ "help": "search all repos"
+ }
+ )
+ ),
+ (
+ 'Package matching options',
+ (
+ {
+ "longopt": "--herd",
+ "action": "append",
+ "help": "exact match on a herd"
+ },
+ {
+ "longopt": "--maintainer-email",
+ "action": "append",
+ "help": "comma-separated list of maintainer email regexes to search for"
+ }
+ )
+ ),
+ (
+ 'Output formatting',
+ (
+ {
+ "shortopt": "-n",
+ "longopt": "--no-version",
+ "action": "store_true",
+ "help": "collapse multiple matching versions together"
+ },
+ )
+ ),
+ )
+
+ for group_title, opt_data in pquery_option_groups:
+ arg_group = parser.add_argument_group(group_title)
+ for opt_info in opt_data:
+ pargs = []
+ try:
+ pargs.append(opt_info["shortopt"])
+ except KeyError:
+ pass
+ try:
+ pargs.append(opt_info["longopt"])
+ except KeyError:
+ pass
+
+ kwargs = {}
+ try:
+ kwargs["action"] = opt_info["action"]
+ except KeyError:
+ pass
+ try:
+ kwargs["help"] = opt_info["help"]
+ except KeyError:
+ pass
+ arg_group.add_argument(*pargs, **portage._native_kwargs(kwargs))
+
def usage(argv):
print(">>> Portage information query tool")
@@ -798,7 +1211,7 @@ def usage(argv):
# Show our commands -- we do this by scanning the functions in this
# file, and formatting each functions documentation.
#
- help_mode = '--help' in sys.argv
+ help_mode = '--help' in argv
for name in commands:
# Drop non-functions
obj = globals()[name]
@@ -812,12 +1225,21 @@ def usage(argv):
lines = doc.lstrip("\n").split("\n")
print(" " + name + " " + lines[0].strip())
- if (len(sys.argv) > 1):
+ if len(argv) > 1:
if (not help_mode):
lines = lines[:-1]
for line in lines[1:]:
print(" " + line.strip())
- if (len(sys.argv) == 1):
+
+ print()
+ print('Pkgcore pquery compatible options:')
+ print()
+ parser = ArgumentParser(add_help=False,
+ usage='portageq pquery [options] [atom ...]')
+ add_pquery_arguments(parser)
+ parser.print_help()
+
+ if len(argv) == 1:
print("\nRun portageq with --help for info")
atom_validate_strict = "EBUILD_PHASE" in os.environ
@@ -836,52 +1258,84 @@ else:
def elog(elog_funcname, lines):
pass
-def main():
+def main(argv):
+
+ argv = portage._decode_argv(argv)
nocolor = os.environ.get('NOCOLOR')
if nocolor in ('yes', 'true'):
portage.output.nocolor()
- if len(sys.argv) < 2:
- usage(sys.argv)
- sys.exit(os.EX_USAGE)
+ parser = ArgumentParser(add_help=False)
- for x in sys.argv:
- if x in ("-h", "--help"):
- usage(sys.argv)
- sys.exit(os.EX_OK)
- elif x == "--version":
- print("Portage", portage.VERSION)
- sys.exit(os.EX_OK)
-
- cmd = sys.argv[1]
- function = globals().get(cmd)
- if function is None or cmd not in commands:
- usage(sys.argv)
+ # used by envvar
+ parser.add_argument("-v", dest="verbose", action="store_true")
+
+ actions = parser.add_argument_group('Actions')
+ actions.add_argument("-h", "--help", action="store_true")
+ actions.add_argument("--version", action="store_true")
+
+ add_pquery_arguments(parser)
+
+ opts, args = parser.parse_known_args(argv[1:])
+
+ if opts.help:
+ usage(argv)
+ return os.EX_OK
+ elif opts.version:
+ print("Portage", portage.VERSION)
+ return os.EX_OK
+
+ cmd = None
+ if args and args[0] in commands:
+ cmd = args[0]
+
+ if cmd == 'pquery':
+ cmd = None
+ args = args[1:]
+
+ if cmd is None:
+ return pquery(parser, opts, args)
+
+ if opts.verbose:
+ # used by envvar
+ args.append("-v")
+
+ argv = argv[:1] + args
+
+ if len(argv) < 2:
+ usage(argv)
sys.exit(os.EX_USAGE)
+
function = globals()[cmd]
- uses_root = getattr(function, "uses_root", False) and len(sys.argv) > 2
- if uses_root:
- if not os.path.isdir(sys.argv[2]):
- sys.stderr.write("Not a directory: '%s'\n" % sys.argv[2])
+ uses_eroot = getattr(function, "uses_eroot", False) and len(argv) > 2
+ if uses_eroot:
+ if not os.path.isdir(argv[2]):
+ sys.stderr.write("Not a directory: '%s'\n" % argv[2])
sys.stderr.write("Run portageq with --help for info\n")
sys.stderr.flush()
sys.exit(os.EX_USAGE)
- eprefix = portage.const.EPREFIX
- eroot = portage.util.normalize_path(sys.argv[2])
+ eprefix = portage.settings["EPREFIX"]
+ eroot = portage.util.normalize_path(argv[2])
+
if eprefix:
- root = eroot[:1-len(eprefix)]
+ if not eroot.endswith(eprefix):
+ sys.stderr.write("ERROR: This version of portageq"
+ " only supports <eroot>s ending in"
+ " '%s'. The provided <eroot>, '%s',"
+ " doesn't.\n" % (eprefix, eroot))
+ sys.stderr.flush()
+ sys.exit(os.EX_USAGE)
+ root = eroot[:1 - len(eprefix)]
else:
root = eroot
+
os.environ["ROOT"] = root
- args = sys.argv[2:]
- if args and isinstance(args[0], bytes):
- for i in range(len(args)):
- args[i] = portage._unicode_decode(args[i])
+ args = argv[2:]
try:
- if uses_root:
+ if uses_eroot:
args[0] = portage.settings['EROOT']
retval = function(args)
if retval:
@@ -902,6 +1356,7 @@ def main():
portage.writemsg("\nPlease use a more specific atom.\n", noiselevel=-1)
sys.exit(1)
-main()
+if __name__ == '__main__':
+ sys.exit(main(sys.argv))
#-----------------------------------------------------------------------------
diff --git a/bin/quickpkg b/bin/quickpkg
index 76259c5c1..90277ade3 100755
--- a/bin/quickpkg
+++ b/bin/quickpkg
@@ -1,23 +1,20 @@
-#!/usr/bin/python
-# Copyright 1999-2012 Gentoo Foundation
+#!/usr/bin/python -b
+# Copyright 1999-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
from __future__ import print_function
import errno
import math
-import optparse
import signal
import sys
import tarfile
-try:
- import portage
-except ImportError:
- from os import path as osp
- sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
- import portage
-
+from os import path as osp
+pym_path = osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")
+sys.path.insert(0, pym_path)
+import portage
+portage._internal_caller = True
from portage import os
from portage import xpak
from portage.dbapi.dep_expand import dep_expand
@@ -28,6 +25,7 @@ from portage.util import ConfigProtect, ensure_dirs, shlex_split
from portage.dbapi.vartree import dblink, tar_contents
from portage.checksum import perform_md5
from portage._sets import load_default_config, SETPREFIX
+from portage.util._argparse import ArgumentParser
def quickpkg_atom(options, infos, arg, eout):
settings = portage.settings
@@ -291,29 +289,28 @@ def quickpkg_main(options, args, eout):
if __name__ == "__main__":
usage = "quickpkg [options] <list of package atoms or package sets>"
- parser = optparse.OptionParser(usage=usage)
- parser.add_option("--umask",
+ parser = ArgumentParser(usage=usage)
+ parser.add_argument("--umask",
default="0077",
help="umask used during package creation (default is 0077)")
- parser.add_option("--ignore-default-opts",
+ parser.add_argument("--ignore-default-opts",
action="store_true",
help="do not use the QUICKPKG_DEFAULT_OPTS environment variable")
- parser.add_option("--include-config",
- type="choice",
+ parser.add_argument("--include-config",
choices=["y","n"],
default="n",
metavar="<y|n>",
help="include all files protected by CONFIG_PROTECT (as a security precaution, default is 'n')")
- parser.add_option("--include-unmodified-config",
- type="choice",
+ parser.add_argument("--include-unmodified-config",
choices=["y","n"],
default="n",
metavar="<y|n>",
help="include files protected by CONFIG_PROTECT that have not been modified since installation (as a security precaution, default is 'n')")
- options, args = parser.parse_args(sys.argv[1:])
+ options, args = parser.parse_known_args(sys.argv[1:])
if not options.ignore_default_opts:
- default_opts = portage.settings.get("QUICKPKG_DEFAULT_OPTS","").split()
- options, args = parser.parse_args(default_opts + sys.argv[1:])
+ default_opts = shlex_split(
+ portage.settings.get("QUICKPKG_DEFAULT_OPTS", ""))
+ options, args = parser.parse_known_args(default_opts + sys.argv[1:])
if not args:
parser.error("no packages atoms given")
try:
diff --git a/bin/regenworld b/bin/regenworld
index 3199fdf90..32e8e5c33 100755
--- a/bin/regenworld
+++ b/bin/regenworld
@@ -1,17 +1,15 @@
-#!/usr/bin/python
-# Copyright 1999-2011 Gentoo Foundation
+#!/usr/bin/python -b
+# Copyright 1999-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
from __future__ import print_function
import sys
-try:
- import portage
-except ImportError:
- from os import path as osp
- sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
- import portage
-
+from os import path as osp
+pym_path = osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")
+sys.path.insert(0, pym_path)
+import portage
+portage._internal_caller = True
from portage import os
from portage._sets.files import StaticFileSet, WorldSelectedSet
diff --git a/bin/repoman b/bin/repoman
index 795c7ce77..888892b30 100755
--- a/bin/repoman
+++ b/bin/repoman
@@ -1,20 +1,19 @@
-#!/usr/bin/python -O
-# Copyright 1999-2012 Gentoo Foundation
+#!/usr/bin/python -bO
+# Copyright 1999-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# Next to do: dep syntax checking in mask files
# Then, check to make sure deps are satisfiable (to avoid "can't find match for" problems)
# that last one is tricky because multiple profiles need to be checked.
-from __future__ import print_function
+from __future__ import print_function, unicode_literals
-import calendar
+import codecs
import copy
import errno
import formatter
import io
import logging
-import optparse
import re
import signal
import stat
@@ -24,23 +23,20 @@ import tempfile
import textwrap
import time
import platform
-
-try:
- from urllib.request import urlopen as urllib_request_urlopen
-except ImportError:
- from urllib import urlopen as urllib_request_urlopen
-
from itertools import chain
from stat import S_ISDIR
try:
- import portage
+ from urllib.parse import urlparse
except ImportError:
- from os import path as osp
- sys.path.insert(0, osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym"))
- import portage
+ from urlparse import urlparse
+
+from os import path as osp
+pym_path = osp.join(osp.dirname(osp.dirname(osp.realpath(__file__))), "pym")
+sys.path.insert(0, pym_path)
+import portage
+portage._internal_caller = True
portage._disable_legacy_globals()
-portage.dep._internal_warnings = True
try:
import xml.etree.ElementTree
@@ -58,9 +54,9 @@ except (ImportError, SystemError, RuntimeError, Exception):
sys.exit(1)
from portage import os
-from portage import subprocess_getstatusoutput
from portage import _encodings
from portage import _unicode_encode
+import repoman.checks
from repoman.checks import run_checks
from repoman import utilities
from repoman.herdbase import make_herd_base
@@ -69,18 +65,18 @@ from _emerge.RootConfig import RootConfig
from _emerge.userquery import userquery
import portage.checksum
import portage.const
+import portage.repository.config
from portage import cvstree, normalize_path
from portage import util
-from portage.exception import (FileNotFound, MissingParameter,
+from portage.exception import (FileNotFound, InvalidAtom, MissingParameter,
ParseError, PermissionDenied)
-from portage.manifest import _prohibited_filename_chars_re as \
- disallowed_filename_chars_re
+from portage.dep import Atom
from portage.process import find_binary, spawn
from portage.output import bold, create_color_func, \
green, nocolor, red
from portage.output import ConsoleStyleFile, StyleWriter
from portage.util import writemsg_level
-from portage.util._desktop_entry import validate_desktop_entry
+from portage.util._argparse import ArgumentParser
from portage.package.ebuild.digestgen import digestgen
from portage.eapi import eapi_has_iuse_defaults, eapi_has_required_use
@@ -93,6 +89,7 @@ util.initialize_logger()
max_desc_len = 100
allowed_filename_chars="a-zA-Z0-9._-+:"
pv_toolong_re = re.compile(r'[0-9]{19,}')
+GPG_KEY_ID_REGEX = r'(0x)?([0-9a-fA-F]{8}|[0-9a-fA-F]{16}|[0-9a-fA-F]{24}|[0-9a-fA-F]{32}|[0-9a-fA-F]{40})!?'
bad = create_color_func("BAD")
# A sane umask is needed for files that portage creates.
@@ -116,41 +113,14 @@ def err(txt):
warn(txt)
sys.exit(1)
-def exithandler(signum=None, frame=None):
+def exithandler(signum=None, _frame=None):
logging.fatal("Interrupted; exiting...")
if signum is None:
sys.exit(1)
else:
sys.exit(128 + signum)
-signal.signal(signal.SIGINT,exithandler)
-
-class RepomanHelpFormatter(optparse.IndentedHelpFormatter):
- """Repoman needs it's own HelpFormatter for now, because the default ones
- murder the help text."""
-
- def __init__(self, indent_increment=1, max_help_position=24, width=150, short_first=1):
- optparse.HelpFormatter.__init__(self, indent_increment, max_help_position, width, short_first)
-
- def format_description(self, description):
- return description
-
-class RepomanOptionParser(optparse.OptionParser):
- """Add the on_tail function, ruby has it, optionParser should too
- """
-
- def __init__(self, *args, **kwargs):
- optparse.OptionParser.__init__(self, *args, **kwargs)
- self.tail = ""
-
- def on_tail(self, description):
- self.tail += description
-
- def format_help(self, formatter=None):
- result = optparse.OptionParser.format_help(self, formatter)
- result += self.tail
- return result
-
+signal.signal(signal.SIGINT, exithandler)
def ParseArgs(argv, qahelp):
"""This function uses a customized optionParser to parse command line arguments for repoman
@@ -161,8 +131,7 @@ def ParseArgs(argv, qahelp):
(opts, args), just like a call to parser.parse_args()
"""
- if argv and isinstance(argv[0], bytes):
- argv = [portage._unicode_decode(x) for x in argv]
+ argv = portage._decode_argv(argv)
modes = {
'commit' : 'Run a scan then commit changes',
@@ -172,102 +141,113 @@ def ParseArgs(argv, qahelp):
'help' : 'Show this screen',
'manifest' : 'Generate a Manifest (fetches files if necessary)',
'manifest-check' : 'Check Manifests for missing or incorrect digests',
- 'scan' : 'Scan directory tree for QA issues'
+ 'scan' : 'Scan directory tree for QA issues'
+ }
+
+ output_choices = {
+ 'default' : 'The normal output format',
+ 'column' : 'Columnar output suitable for use with grep'
}
mode_keys = list(modes)
mode_keys.sort()
- parser = RepomanOptionParser(formatter=RepomanHelpFormatter(), usage="%prog [options] [mode]")
- parser.description = green(" ".join((os.path.basename(argv[0]), "1.2")))
- parser.description += "\nCopyright 1999-2007 Gentoo Foundation"
- parser.description += "\nDistributed under the terms of the GNU General Public License v2"
- parser.description += "\nmodes: " + " | ".join(map(green,mode_keys))
+ output_keys = sorted(output_choices)
- parser.add_option('-a', '--ask', dest='ask', action='store_true', default=False,
+ parser = ArgumentParser(usage="repoman [options] [mode]",
+ description="Modes: %s" % " | ".join(mode_keys),
+ epilog="For more help consult the man page.")
+
+ parser.add_argument('-a', '--ask', dest='ask', action='store_true', default=False,
help='Request a confirmation before commiting')
- parser.add_option('-m', '--commitmsg', dest='commitmsg',
+ parser.add_argument('-m', '--commitmsg', dest='commitmsg',
help='specify a commit message on the command line')
- parser.add_option('-M', '--commitmsgfile', dest='commitmsgfile',
+ parser.add_argument('-M', '--commitmsgfile', dest='commitmsgfile',
help='specify a path to a file that contains a commit message')
- parser.add_option('--digest',
- type='choice', choices=('y', 'n'), metavar='<y|n>',
+ parser.add_argument('--digest',
+ choices=('y', 'n'), metavar='<y|n>',
help='Automatically update Manifest digests for modified files')
- parser.add_option('-p', '--pretend', dest='pretend', default=False,
+ parser.add_argument('-p', '--pretend', dest='pretend', default=False,
action='store_true', help='don\'t commit or fix anything; just show what would be done')
-
- parser.add_option('-q', '--quiet', dest="quiet", action="count", default=0,
+
+ parser.add_argument('-q', '--quiet', dest="quiet", action="count", default=0,
help='do not print unnecessary messages')
- parser.add_option(
- '--echangelog', type='choice', choices=('y', 'n', 'force'), metavar="<y|n|force>",
+ parser.add_argument(
+ '--echangelog', choices=('y', 'n', 'force'), metavar="<y|n|force>",
help='for commit mode, call echangelog if ChangeLog is unmodified (or '
'regardless of modification if \'force\' is specified)')
- parser.add_option('-f', '--force', dest='force', default=False, action='store_true',
+ parser.add_argument('--experimental-inherit', choices=('y', 'n'),
+ metavar="<y|n>", default='n',
+ help='Enable experimental inherit.missing checks which may misbehave'
+ ' when the internal eclass database becomes outdated')
+
+ parser.add_argument('-f', '--force', dest='force', default=False, action='store_true',
help='Commit with QA violations')
- parser.add_option('--vcs', dest='vcs',
+ parser.add_argument('--vcs', dest='vcs',
help='Force using specific VCS instead of autodetection')
- parser.add_option('-v', '--verbose', dest="verbosity", action='count',
+ parser.add_argument('-v', '--verbose', dest="verbosity", action='count',
help='be very verbose in output', default=0)
- parser.add_option('-V', '--version', dest='version', action='store_true',
+ parser.add_argument('-V', '--version', dest='version', action='store_true',
help='show version info')
- parser.add_option('-x', '--xmlparse', dest='xml_parse', action='store_true',
+ parser.add_argument('-x', '--xmlparse', dest='xml_parse', action='store_true',
default=False, help='forces the metadata.xml parse check to be carried out')
- parser.add_option(
- '--if-modified', type='choice', choices=('y', 'n'), default='n',
+ parser.add_argument(
+ '--if-modified', choices=('y', 'n'), default='n',
metavar="<y|n>",
help='only check packages that have uncommitted modifications')
- parser.add_option('-i', '--ignore-arches', dest='ignore_arches', action='store_true',
+ parser.add_argument('-i', '--ignore-arches', dest='ignore_arches', action='store_true',
default=False, help='ignore arch-specific failures (where arch != host)')
- parser.add_option("--ignore-default-opts",
+ parser.add_argument("--ignore-default-opts",
action="store_true",
help="do not use the REPOMAN_DEFAULT_OPTS environment variable")
- parser.add_option('-I', '--ignore-masked', dest='ignore_masked', action='store_true',
+ parser.add_argument('-I', '--ignore-masked', dest='ignore_masked', action='store_true',
default=False, help='ignore masked packages (not allowed with commit mode)')
- parser.add_option('-d', '--include-dev', dest='include_dev', action='store_true',
+ parser.add_argument('--include-arches', dest='include_arches',
+ metavar='ARCHES', action='append',
+ help='A space separated list of arches used to '
+ 'filter the selection of profiles for dependency checks')
+
+ parser.add_argument('-d', '--include-dev', dest='include_dev', action='store_true',
default=False, help='include dev profiles in dependency checks')
- parser.add_option('--unmatched-removal', dest='unmatched_removal', action='store_true',
+ parser.add_argument('-e', '--include-exp-profiles', choices=('y', 'n'),
+ default=False, help='include exp profiles in dependency checks',
+ metavar='<y|n>')
+
+ parser.add_argument('--unmatched-removal', dest='unmatched_removal', action='store_true',
default=False, help='enable strict checking of package.mask and package.unmask files for unmatched removal atoms')
- parser.add_option('--without-mask', dest='without_mask', action='store_true',
+ parser.add_argument('--without-mask', dest='without_mask', action='store_true',
default=False, help='behave as if no package.mask entries exist (not allowed with commit mode)')
- parser.add_option('--mode', type='choice', dest='mode', choices=list(modes),
- help='specify which mode repoman will run in (default=full)')
-
- parser.on_tail("\n " + green("Modes".ljust(20) + " Description\n"))
+ parser.add_argument('--output-style', dest='output_style', choices=output_keys,
+ help='select output type', default='default')
- for k in mode_keys:
- parser.on_tail(" %s %s\n" % (k.ljust(20), modes[k]))
-
- parser.on_tail("\n " + green("QA keyword".ljust(20) + " Description\n"))
-
- sorted_qa = list(qahelp)
- sorted_qa.sort()
- for k in sorted_qa:
- parser.on_tail(" %s %s\n" % (k.ljust(20), qahelp[k]))
+ parser.add_argument('--mode', dest='mode', choices=mode_keys,
+ help='specify which mode repoman will run in (default=full)')
- opts, args = parser.parse_args(argv[1:])
+ opts, args = parser.parse_known_args(argv[1:])
if not opts.ignore_default_opts:
- default_opts = repoman_settings.get("REPOMAN_DEFAULT_OPTS", "").split()
+ default_opts = portage.util.shlex_split(
+ repoman_settings.get("REPOMAN_DEFAULT_OPTS", ""))
if default_opts:
- opts, args = parser.parse_args(default_opts + sys.argv[1:])
+ opts, args = parser.parse_known_args(default_opts + sys.argv[1:])
if opts.mode == 'help':
parser.print_help(short=False)
@@ -282,16 +262,10 @@ def ParseArgs(argv, qahelp):
if not opts.mode:
opts.mode = 'full'
-
+
if opts.mode == 'ci':
opts.mode = 'commit' # backwards compat shortcut
- if opts.mode == 'commit' and not (opts.force or opts.pretend):
- if opts.ignore_masked:
- parser.error('Commit mode and --ignore-masked are not compatible')
- if opts.without_mask:
- parser.error('Commit mode and --without-mask are not compatible')
-
# Use the verbosity and quiet options to fiddle with the loglevel appropriately
for val in range(opts.verbosity):
logger = logging.getLogger()
@@ -301,101 +275,99 @@ def ParseArgs(argv, qahelp):
logger = logging.getLogger()
logger.setLevel(logger.getEffectiveLevel() + 10)
+ if opts.mode == 'commit' and not (opts.force or opts.pretend):
+ if opts.ignore_masked:
+ opts.ignore_masked = False
+ logging.warn('Commit mode automatically disables --ignore-masked')
+ if opts.without_mask:
+ opts.without_mask = False
+ logging.warn('Commit mode automatically disables --without-mask')
+
return (opts, args)
-qahelp={
- "CVS/Entries.IO_error":"Attempting to commit, and an IO error was encountered access the Entries file",
- "desktop.invalid":"desktop-file-validate reports errors in a *.desktop file",
- "ebuild.invalidname":"Ebuild files with a non-parseable or syntactically incorrect name (or using 2.1 versioning extensions)",
- "ebuild.namenomatch":"Ebuild files that do not have the same name as their parent directory",
- "changelog.ebuildadded":"An ebuild was added but the ChangeLog was not modified",
- "changelog.missing":"Missing ChangeLog files",
- "ebuild.notadded":"Ebuilds that exist but have not been added to cvs",
- "ebuild.patches":"PATCHES variable should be a bash array to ensure white space safety",
- "changelog.notadded":"ChangeLogs that exist but have not been added to cvs",
- "dependency.unknown" : "Ebuild has a dependency that refers to an unknown package (which may be valid if it is a blocker for a renamed/removed package, or is an alternative choice provided by an overlay)",
- "file.executable":"Ebuilds, digests, metadata.xml, Manifest, and ChangeLog do not need the executable bit",
- "file.size":"Files in the files directory must be under 20 KiB",
- "file.size.fatal":"Files in the files directory must be under 60 KiB",
- "file.name":"File/dir name must be composed of only the following chars: %s " % allowed_filename_chars,
- "file.UTF8":"File is not UTF8 compliant",
- "inherit.deprecated":"Ebuild inherits a deprecated eclass",
- "inherit.missing":"Ebuild uses functions from an eclass but does not inherit it",
- "inherit.unused":"Ebuild inherits an eclass but does not use it",
- "java.eclassesnotused":"With virtual/jdk in DEPEND you must inherit a java eclass",
- "wxwidgets.eclassnotused":"Ebuild DEPENDs on x11-libs/wxGTK without inheriting wxwidgets.eclass",
- "KEYWORDS.dropped":"Ebuilds that appear to have dropped KEYWORDS for some arch",
- "KEYWORDS.missing":"Ebuilds that have a missing or empty KEYWORDS variable",
- "KEYWORDS.stable":"Ebuilds that have been added directly with stable KEYWORDS",
- "KEYWORDS.stupid":"Ebuilds that use KEYWORDS=-* instead of package.mask",
- "LICENSE.missing":"Ebuilds that have a missing or empty LICENSE variable",
- "LICENSE.virtual":"Virtuals that have a non-empty LICENSE variable",
- "DESCRIPTION.missing":"Ebuilds that have a missing or empty DESCRIPTION variable",
- "DESCRIPTION.toolong":"DESCRIPTION is over %d characters" % max_desc_len,
- "EAPI.definition":"EAPI definition does not conform to PMS section 7.3.1 (first non-comment, non-blank line)",
- "EAPI.deprecated":"Ebuilds that use features that are deprecated in the current EAPI",
- "EAPI.incompatible":"Ebuilds that use features that are only available with a different EAPI",
- "EAPI.unsupported":"Ebuilds that have an unsupported EAPI version (you must upgrade portage)",
- "SLOT.invalid":"Ebuilds that have a missing or invalid SLOT variable value",
- "HOMEPAGE.missing":"Ebuilds that have a missing or empty HOMEPAGE variable",
- "HOMEPAGE.virtual":"Virtuals that have a non-empty HOMEPAGE variable",
- "DEPEND.bad":"User-visible ebuilds with bad DEPEND settings (matched against *visible* ebuilds)",
- "RDEPEND.bad":"User-visible ebuilds with bad RDEPEND settings (matched against *visible* ebuilds)",
- "PDEPEND.bad":"User-visible ebuilds with bad PDEPEND settings (matched against *visible* ebuilds)",
- "DEPEND.badmasked":"Masked ebuilds with bad DEPEND settings (matched against *all* ebuilds)",
- "RDEPEND.badmasked":"Masked ebuilds with RDEPEND settings (matched against *all* ebuilds)",
- "PDEPEND.badmasked":"Masked ebuilds with PDEPEND settings (matched against *all* ebuilds)",
- "DEPEND.badindev":"User-visible ebuilds with bad DEPEND settings (matched against *visible* ebuilds) in developing arch",
- "RDEPEND.badindev":"User-visible ebuilds with bad RDEPEND settings (matched against *visible* ebuilds) in developing arch",
- "PDEPEND.badindev":"User-visible ebuilds with bad PDEPEND settings (matched against *visible* ebuilds) in developing arch",
- "DEPEND.badmaskedindev":"Masked ebuilds with bad DEPEND settings (matched against *all* ebuilds) in developing arch",
- "RDEPEND.badmaskedindev":"Masked ebuilds with RDEPEND settings (matched against *all* ebuilds) in developing arch",
- "PDEPEND.badmaskedindev":"Masked ebuilds with PDEPEND settings (matched against *all* ebuilds) in developing arch",
- "PDEPEND.suspect":"PDEPEND contains a package that usually only belongs in DEPEND.",
- "DEPEND.syntax":"Syntax error in DEPEND (usually an extra/missing space/parenthesis)",
- "RDEPEND.syntax":"Syntax error in RDEPEND (usually an extra/missing space/parenthesis)",
- "PDEPEND.syntax":"Syntax error in PDEPEND (usually an extra/missing space/parenthesis)",
- "DEPEND.badtilde":"DEPEND uses the ~ dep operator with a non-zero revision part, which is useless (the revision is ignored)",
- "RDEPEND.badtilde":"RDEPEND uses the ~ dep operator with a non-zero revision part, which is useless (the revision is ignored)",
- "PDEPEND.badtilde":"PDEPEND uses the ~ dep operator with a non-zero revision part, which is useless (the revision is ignored)",
- "LICENSE.syntax":"Syntax error in LICENSE (usually an extra/missing space/parenthesis)",
- "PROVIDE.syntax":"Syntax error in PROVIDE (usually an extra/missing space/parenthesis)",
- "PROPERTIES.syntax":"Syntax error in PROPERTIES (usually an extra/missing space/parenthesis)",
- "RESTRICT.syntax":"Syntax error in RESTRICT (usually an extra/missing space/parenthesis)",
- "REQUIRED_USE.syntax":"Syntax error in REQUIRED_USE (usually an extra/missing space/parenthesis)",
- "SRC_URI.syntax":"Syntax error in SRC_URI (usually an extra/missing space/parenthesis)",
- "SRC_URI.mirror":"A uri listed in profiles/thirdpartymirrors is found in SRC_URI",
- "ebuild.syntax":"Error generating cache entry for ebuild; typically caused by ebuild syntax error or digest verification failure",
- "ebuild.output":"A simple sourcing of the ebuild produces output; this breaks ebuild policy.",
- "ebuild.nesteddie":"Placing 'die' inside ( ) prints an error, but doesn't stop the ebuild.",
- "variable.invalidchar":"A variable contains an invalid character that is not part of the ASCII character set",
- "variable.readonly":"Assigning a readonly variable",
- "variable.usedwithhelpers":"Ebuild uses D, ROOT, ED, EROOT or EPREFIX with helpers",
- "LIVEVCS.stable":"This ebuild is a live checkout from a VCS but has stable keywords.",
- "LIVEVCS.unmasked":"This ebuild is a live checkout from a VCS but has keywords and is not masked in the global package.mask.",
- "IUSE.invalid":"This ebuild has a variable in IUSE that is not in the use.desc or its metadata.xml file",
- "IUSE.missing":"This ebuild has a USE conditional which references a flag that is not listed in IUSE",
- "IUSE.undefined":"This ebuild does not define IUSE (style guideline says to define IUSE even when empty)",
- "LICENSE.invalid":"This ebuild is listing a license that doesnt exist in portages license/ dir.",
- "KEYWORDS.invalid":"This ebuild contains KEYWORDS that are not listed in profiles/arch.list or for which no valid profile was found",
- "RDEPEND.implicit":"RDEPEND is unset in the ebuild which triggers implicit RDEPEND=$DEPEND assignment (prior to EAPI 4)",
- "RDEPEND.suspect":"RDEPEND contains a package that usually only belongs in DEPEND.",
- "RESTRICT.invalid":"This ebuild contains invalid RESTRICT values.",
- "digest.assumed":"Existing digest must be assumed correct (Package level only)",
- "digest.missing":"Some files listed in SRC_URI aren't referenced in the Manifest",
- "digest.unused":"Some files listed in the Manifest aren't referenced in SRC_URI",
- "ebuild.majorsyn":"This ebuild has a major syntax error that may cause the ebuild to fail partially or fully",
- "ebuild.minorsyn":"This ebuild has a minor syntax error that contravenes gentoo coding style",
- "ebuild.badheader":"This ebuild has a malformed header",
- "manifest.bad":"Manifest has missing or incorrect digests",
- "metadata.missing":"Missing metadata.xml files",
- "metadata.bad":"Bad metadata.xml files",
- "metadata.warning":"Warnings in metadata.xml files",
- "portage.internal":"The ebuild uses an internal Portage function",
- "virtual.oldstyle":"The ebuild PROVIDEs an old-style virtual (see GLEP 37)",
- "virtual.suspect":"Ebuild contains a package that usually should be pulled via virtual/, not directly.",
- "usage.obsolete":"The ebuild makes use of an obsolete construct",
- "upstream.workaround":"The ebuild works around an upstream bug, an upstream bug should be filed and tracked in bugs.gentoo.org"
+qahelp = {
+ "CVS/Entries.IO_error": "Attempting to commit, and an IO error was encountered access the Entries file",
+ "ebuild.invalidname": "Ebuild files with a non-parseable or syntactically incorrect name (or using 2.1 versioning extensions)",
+ "ebuild.namenomatch": "Ebuild files that do not have the same name as their parent directory",
+ "changelog.ebuildadded": "An ebuild was added but the ChangeLog was not modified",
+ "changelog.missing": "Missing ChangeLog files",
+ "ebuild.notadded": "Ebuilds that exist but have not been added to cvs",
+ "ebuild.patches": "PATCHES variable should be a bash array to ensure white space safety",
+ "changelog.notadded": "ChangeLogs that exist but have not been added to cvs",
+ "dependency.bad": "User-visible ebuilds with unsatisfied dependencies (matched against *visible* ebuilds)",
+ "dependency.badmasked": "Masked ebuilds with unsatisfied dependencies (matched against *all* ebuilds)",
+ "dependency.badindev": "User-visible ebuilds with unsatisfied dependencies (matched against *visible* ebuilds) in developing arch",
+ "dependency.badmaskedindev": "Masked ebuilds with unsatisfied dependencies (matched against *all* ebuilds) in developing arch",
+ "dependency.badtilde": "Uses the ~ dep operator with a non-zero revision part, which is useless (the revision is ignored)",
+ "dependency.syntax": "Syntax error in dependency string (usually an extra/missing space/parenthesis)",
+ "dependency.unknown": "Ebuild has a dependency that refers to an unknown package (which may be valid if it is a blocker for a renamed/removed package, or is an alternative choice provided by an overlay)",
+ "file.executable": "Ebuilds, digests, metadata.xml, Manifest, and ChangeLog do not need the executable bit",
+ "file.size": "Files in the files directory must be under 20 KiB",
+ "file.size.fatal": "Files in the files directory must be under 60 KiB",
+ "file.name": "File/dir name must be composed of only the following chars: %s " % allowed_filename_chars,
+ "file.UTF8": "File is not UTF8 compliant",
+ "inherit.deprecated": "Ebuild inherits a deprecated eclass",
+ "inherit.missing": "Ebuild uses functions from an eclass but does not inherit it",
+ "inherit.unused": "Ebuild inherits an eclass but does not use it",
+ "java.eclassesnotused": "With virtual/jdk in DEPEND you must inherit a java eclass",
+ "wxwidgets.eclassnotused": "Ebuild DEPENDs on x11-libs/wxGTK without inheriting wxwidgets.eclass",
+ "KEYWORDS.dropped": "Ebuilds that appear to have dropped KEYWORDS for some arch",
+ "KEYWORDS.missing": "Ebuilds that have a missing or empty KEYWORDS variable",
+ "KEYWORDS.stable": "Ebuilds that have been added directly with stable KEYWORDS",
+ "KEYWORDS.stupid": "Ebuilds that use KEYWORDS=-* instead of package.mask",
+ "LICENSE.missing": "Ebuilds that have a missing or empty LICENSE variable",
+ "LICENSE.virtual": "Virtuals that have a non-empty LICENSE variable",
+ "DESCRIPTION.missing": "Ebuilds that have a missing or empty DESCRIPTION variable",
+ "DESCRIPTION.toolong": "DESCRIPTION is over %d characters" % max_desc_len,
+ "EAPI.definition": "EAPI definition does not conform to PMS section 7.3.1 (first non-comment, non-blank line)",
+ "EAPI.deprecated": "Ebuilds that use features that are deprecated in the current EAPI",
+ "EAPI.incompatible": "Ebuilds that use features that are only available with a different EAPI",
+ "EAPI.unsupported": "Ebuilds that have an unsupported EAPI version (you must upgrade portage)",
+ "SLOT.invalid": "Ebuilds that have a missing or invalid SLOT variable value",
+ "HOMEPAGE.missing": "Ebuilds that have a missing or empty HOMEPAGE variable",
+ "HOMEPAGE.virtual": "Virtuals that have a non-empty HOMEPAGE variable",
+ "PDEPEND.suspect": "PDEPEND contains a package that usually only belongs in DEPEND.",
+ "LICENSE.syntax": "Syntax error in LICENSE (usually an extra/missing space/parenthesis)",
+ "PROVIDE.syntax": "Syntax error in PROVIDE (usually an extra/missing space/parenthesis)",
+ "PROPERTIES.syntax": "Syntax error in PROPERTIES (usually an extra/missing space/parenthesis)",
+ "RESTRICT.syntax": "Syntax error in RESTRICT (usually an extra/missing space/parenthesis)",
+ "REQUIRED_USE.syntax": "Syntax error in REQUIRED_USE (usually an extra/missing space/parenthesis)",
+ "SRC_URI.syntax": "Syntax error in SRC_URI (usually an extra/missing space/parenthesis)",
+ "SRC_URI.mirror": "A uri listed in profiles/thirdpartymirrors is found in SRC_URI",
+ "ebuild.syntax": "Error generating cache entry for ebuild; typically caused by ebuild syntax error or digest verification failure",
+ "ebuild.output": "A simple sourcing of the ebuild produces output; this breaks ebuild policy.",
+ "ebuild.nesteddie": "Placing 'die' inside ( ) prints an error, but doesn't stop the ebuild.",
+ "variable.invalidchar": "A variable contains an invalid character that is not part of the ASCII character set",
+ "variable.readonly": "Assigning a readonly variable",
+ "variable.usedwithhelpers": "Ebuild uses D, ROOT, ED, EROOT or EPREFIX with helpers",
+ "LIVEVCS.stable": "This ebuild is a live checkout from a VCS but has stable keywords.",
+ "LIVEVCS.unmasked": "This ebuild is a live checkout from a VCS but has keywords and is not masked in the global package.mask.",
+ "IUSE.invalid": "This ebuild has a variable in IUSE that is not in the use.desc or its metadata.xml file",
+ "IUSE.missing": "This ebuild has a USE conditional which references a flag that is not listed in IUSE",
+ "IUSE.rubydeprecated": "The ebuild has set a ruby interpreter in USE_RUBY, that is not available as a ruby target anymore",
+ "LICENSE.invalid": "This ebuild is listing a license that doesnt exist in portages license/ dir.",
+ "LICENSE.deprecated": "This ebuild is listing a deprecated license.",
+ "KEYWORDS.invalid": "This ebuild contains KEYWORDS that are not listed in profiles/arch.list or for which no valid profile was found",
+ "RDEPEND.implicit": "RDEPEND is unset in the ebuild which triggers implicit RDEPEND=$DEPEND assignment (prior to EAPI 4)",
+ "RDEPEND.suspect": "RDEPEND contains a package that usually only belongs in DEPEND.",
+ "RESTRICT.invalid": "This ebuild contains invalid RESTRICT values.",
+ "digest.assumed": "Existing digest must be assumed correct (Package level only)",
+ "digest.missing": "Some files listed in SRC_URI aren't referenced in the Manifest",
+ "digest.unused": "Some files listed in the Manifest aren't referenced in SRC_URI",
+ "ebuild.majorsyn": "This ebuild has a major syntax error that may cause the ebuild to fail partially or fully",
+ "ebuild.minorsyn": "This ebuild has a minor syntax error that contravenes gentoo coding style",
+ "ebuild.badheader": "This ebuild has a malformed header",
+ "manifest.bad": "Manifest has missing or incorrect digests",
+ "metadata.missing": "Missing metadata.xml files",
+ "metadata.bad": "Bad metadata.xml files",
+ "metadata.warning": "Warnings in metadata.xml files",
+ "portage.internal": "The ebuild uses an internal Portage function or variable",
+ "repo.eapi.banned": "The ebuild uses an EAPI which is banned by the repository's metadata/layout.conf settings",
+ "repo.eapi.deprecated": "The ebuild uses an EAPI which is deprecated by the repository's metadata/layout.conf settings",
+ "virtual.oldstyle": "The ebuild PROVIDEs an old-style virtual (see GLEP 37)",
+ "virtual.suspect": "Ebuild contains a package that usually should be pulled via virtual/, not directly.",
+ "usage.obsolete": "The ebuild makes use of an obsolete construct",
+ "upstream.workaround": "The ebuild works around an upstream bug, an upstream bug should be filed and tracked in bugs.gentoo.org"
}
qacats = list(qahelp)
@@ -409,19 +381,18 @@ qawarnings = set((
"digest.unused",
"ebuild.notadded",
"ebuild.nesteddie",
-"desktop.invalid",
-"DEPEND.badmasked","RDEPEND.badmasked","PDEPEND.badmasked",
-"DEPEND.badindev","RDEPEND.badindev","PDEPEND.badindev",
-"DEPEND.badmaskedindev","RDEPEND.badmaskedindev","PDEPEND.badmaskedindev",
-"DEPEND.badtilde", "RDEPEND.badtilde", "PDEPEND.badtilde",
+"dependency.badmasked",
+"dependency.badindev",
+"dependency.badmaskedindev",
+"dependency.badtilde",
"DESCRIPTION.toolong",
"EAPI.deprecated",
"HOMEPAGE.virtual",
+"LICENSE.deprecated",
"LICENSE.virtual",
"KEYWORDS.dropped",
"KEYWORDS.stupid",
"KEYWORDS.missing",
-"IUSE.undefined",
"PDEPEND.suspect",
"RDEPEND.implicit",
"RDEPEND.suspect",
@@ -437,23 +408,21 @@ qawarnings = set((
"wxwidgets.eclassnotused",
"metadata.warning",
"portage.internal",
+"repo.eapi.deprecated",
"usage.obsolete",
"upstream.workaround",
"LIVEVCS.stable",
"LIVEVCS.unmasked",
+"IUSE.rubydeprecated",
))
-if portage.const._ENABLE_INHERIT_CHECK:
- # This is experimental, so it's non-fatal.
- qawarnings.add("inherit.missing")
-
non_ascii_re = re.compile(r'[^\x00-\x7f]')
missingvars = ["KEYWORDS", "LICENSE", "DESCRIPTION", "HOMEPAGE"]
allvars = set(x for x in portage.auxdbkeys if not x.startswith("UNUSED_"))
allvars.update(Package.metadata_keys)
allvars = sorted(allvars)
-commitmessage=None
+commitmessage = None
for x in missingvars:
x += ".missing"
if x not in qacats:
@@ -462,19 +431,10 @@ for x in missingvars:
qawarnings.add(x)
valid_restrict = frozenset(["binchecks", "bindist",
- "fetch", "installsources", "mirror",
- "primaryuri", "strip", "test", "userpriv"])
-
-live_eclasses = frozenset([
- "bzr",
- "cvs",
- "darcs",
- "git",
- "git-2",
- "mercurial",
- "subversion",
- "tla",
-])
+ "fetch", "installsources", "mirror", "preserve-libs",
+ "primaryuri", "splitdebug", "strip", "test", "userpriv"])
+
+live_eclasses = portage.const.LIVE_ECLASSES
suspect_rdepend = frozenset([
"app-arch/cabextract",
@@ -520,14 +480,25 @@ suspect_virtual = {
"dev-util/pkgconf":"virtual/pkgconfig",
"dev-util/pkgconfig":"virtual/pkgconfig",
"dev-util/pkgconfig-openbsd":"virtual/pkgconfig",
+ "dev-libs/libusb":"virtual/libusb",
+ "dev-libs/libusbx":"virtual/libusb",
+ "dev-libs/libusb-compat":"virtual/libusb",
}
+ruby_deprecated = frozenset([
+ "ruby_targets_ree18",
+])
+
+metadata_xml_encoding = 'UTF-8'
+metadata_xml_declaration = '<?xml version="1.0" encoding="%s"?>' % \
+ (metadata_xml_encoding,)
+metadata_doctype_name = 'pkgmetadata'
metadata_dtd_uri = 'http://www.gentoo.org/dtd/metadata.dtd'
# force refetch if the local copy creation time is older than this
metadata_dtd_ctime_interval = 60 * 60 * 24 * 7 # 7 days
# file.executable
-no_exec = frozenset(["Manifest","ChangeLog","metadata.xml"])
+no_exec = frozenset(["Manifest", "ChangeLog", "metadata.xml"])
options, arguments = ParseArgs(sys.argv, qahelp)
@@ -535,6 +506,11 @@ if options.version:
print("Portage", portage.VERSION)
sys.exit(0)
+if options.experimental_inherit == 'y':
+ # This is experimental, so it's non-fatal.
+ qawarnings.add("inherit.missing")
+ repoman.checks._init(experimental_inherit=True)
+
# Set this to False when an extraordinary issue (generally
# something other than a QA issue) makes it impossible to
# commit (like if Manifest generation fails).
@@ -584,14 +560,29 @@ if options.mode == 'commit' and not options.pretend and not vcs:
logging.info("Not in a version controlled repository; enabling pretend mode.")
options.pretend = True
-# Ensure that PORTDIR_OVERLAY contains the repository corresponding to $PWD.
-repoman_settings['PORTDIR_OVERLAY'] = "%s %s" % \
- (repoman_settings.get('PORTDIR_OVERLAY', ''),
- portage._shell_quote(portdir_overlay))
-# We have to call the config constructor again so
-# that config.repositories is initialized correctly.
-repoman_settings = portage.config(config_root=config_root, local_config=False,
- env=dict(os.environ, PORTDIR_OVERLAY=repoman_settings['PORTDIR_OVERLAY']))
+# Ensure that current repository is in the list of enabled repositories.
+repodir = os.path.realpath(portdir_overlay)
+try:
+ repoman_settings.repositories.get_repo_for_location(repodir)
+except KeyError:
+ repo_name = portage.repository.config.RepoConfig._read_valid_repo_name(portdir_overlay)[0]
+ layout_conf_data = portage.repository.config.parse_layout_conf(portdir_overlay)[0]
+ if layout_conf_data['repo-name']:
+ repo_name = layout_conf_data['repo-name']
+ tmp_conf_file = io.StringIO(textwrap.dedent("""
+ [%s]
+ location = %s
+ """) % (repo_name, portdir_overlay))
+ # Ensure that the repository corresponding to $PWD overrides a
+ # repository of the same name referenced by the existing PORTDIR
+ # or PORTDIR_OVERLAY settings.
+ repoman_settings['PORTDIR_OVERLAY'] = "%s %s" % \
+ (repoman_settings.get('PORTDIR_OVERLAY', ''),
+ portage._shell_quote(portdir_overlay))
+ repositories = portage.repository.config.load_repository_config(repoman_settings, extra_files=[tmp_conf_file])
+ # We have to call the config constructor again so that attributes
+ # dependent on config.repositories are initialized correctly.
+ repoman_settings = portage.config(config_root=config_root, local_config=False, repositories=repositories)
root = repoman_settings['EROOT']
trees = {
@@ -601,10 +592,15 @@ portdb = trees[root]['porttree'].dbapi
# Constrain dependency resolution to the master(s)
# that are specified in layout.conf.
-repodir = os.path.realpath(portdir_overlay)
repo_config = repoman_settings.repositories.get_repo_for_location(repodir)
portdb.porttrees = list(repo_config.eclass_db.porttrees)
portdir = portdb.porttrees[0]
+commit_env = os.environ.copy()
+# list() is for iteration on a copy.
+for repo in list(repoman_settings.repositories):
+ # all paths are canonical
+ if repo.location not in repo_config.eclass_db.porttrees:
+ del repoman_settings.repositories[repo.name]
if repo_config.allow_provide_virtual:
qawarnings.add("virtual.oldstyle")
@@ -615,6 +611,15 @@ if repo_config.sign_commit:
# the commit arguments. If key_id is unspecified, then it must be
# configured by `git config user.signingkey key_id`.
vcs_local_opts.append("--gpg-sign")
+ if repoman_settings.get("PORTAGE_GPG_DIR"):
+ # Pass GNUPGHOME to git for bug #462362.
+ commit_env["GNUPGHOME"] = repoman_settings["PORTAGE_GPG_DIR"]
+
+ # Pass GPG_TTY to git for bug #477728.
+ try:
+ commit_env["GPG_TTY"] = os.ttyname(sys.stdin.fileno())
+ except OSError:
+ pass
# In order to disable manifest signatures, repos may set
# "sign-manifests = false" in metadata/layout.conf. This
@@ -623,6 +628,25 @@ if repo_config.sign_commit:
sign_manifests = "sign" in repoman_settings.features and \
repo_config.sign_manifest
+if repo_config.sign_manifest and repo_config.name == "gentoo" and \
+ options.mode in ("commit",) and not sign_manifests:
+ msg = ("The '%s' repository has manifest signatures enabled, "
+ "but FEATURES=sign is currently disabled. In order to avoid this "
+ "warning, enable FEATURES=sign in make.conf. Alternatively, "
+ "repositories can disable manifest signatures by setting "
+ "'sign-manifests = false' in metadata/layout.conf.") % \
+ (repo_config.name,)
+ for line in textwrap.wrap(msg, 60):
+ logging.warn(line)
+
+if sign_manifests and options.mode in ("commit",) and \
+ repoman_settings.get("PORTAGE_GPG_KEY") and \
+ re.match(r'^%s$' % GPG_KEY_ID_REGEX,
+ repoman_settings["PORTAGE_GPG_KEY"]) is None:
+ logging.error("PORTAGE_GPG_KEY value is invalid: %s" %
+ repoman_settings["PORTAGE_GPG_KEY"])
+ sys.exit(1)
+
manifest_hashes = repo_config.manifest_hashes
if manifest_hashes is None:
manifest_hashes = portage.const.MANIFEST2_HASH_DEFAULTS
@@ -652,19 +676,6 @@ if options.mode in ("commit", "fix", "manifest"):
logging.error(line)
sys.exit(1)
-if "commit" == options.mode and \
- repo_config.name == "gentoo" and \
- "RMD160" in manifest_hashes and \
- "RMD160" not in portage.checksum.hashorigin_map:
- msg = "Please install " \
- "pycrypto or enable python's ssl USE flag in order " \
- "to enable RMD160 hash support. See bug #198398 for " \
- "more information."
- prefix = bad(" * ")
- for line in textwrap.wrap(msg, 70):
- print(prefix + line)
- sys.exit(1)
-
if options.echangelog is None and repo_config.update_changelog:
options.echangelog = 'y'
@@ -689,18 +700,9 @@ logging.debug("vcs: %s" % (vcs,))
logging.debug("repo config: %s" % (repo_config,))
logging.debug("options: %s" % (options,))
-# Generate an appropriate PORTDIR_OVERLAY value for passing into the
-# profile-specific config constructor calls.
-env = os.environ.copy()
-env['PORTDIR'] = portdir
-env['PORTDIR_OVERLAY'] = ' '.join(portdb.porttrees[1:])
-
-logging.info('Setting paths:')
-logging.info('PORTDIR = "' + portdir + '"')
-logging.info('PORTDIR_OVERLAY = "%s"' % env['PORTDIR_OVERLAY'])
-
# It's confusing if these warnings are displayed without the user
# being told which profile they come from, so disable them.
+env = os.environ.copy()
env['FEATURES'] = env.get('FEATURES', '') + ' -unknown-features-warn'
categories = []
@@ -724,7 +726,7 @@ repolevel = len(reposplit)
# check if it's in $PORTDIR/$CATEGORY/$PN , otherwise bail if commiting.
# Reason for this is if they're trying to commit in just $FILESDIR/*, the Manifest needs updating.
# this check ensures that repoman knows where it is, and the manifest recommit is at least possible.
-if options.mode == 'commit' and repolevel not in [1,2,3]:
+if options.mode == 'commit' and repolevel not in [1, 2, 3]:
print(red("***")+" Commit attempts *must* be from within a vcs co, category, or package directory.")
print(red("***")+" Attempting to commit from a packages files directory will be blocked for instance.")
print(red("***")+" This is intended behaviour, to ensure the manifest is recommitted for a package.")
@@ -737,10 +739,76 @@ if repolevel == 1:
startdir = repodir
else:
startdir = normalize_path(mydir)
- startdir = os.path.join(repodir, *startdir.split(os.sep)[-2-repolevel+3:])
+ startdir = os.path.join(repodir, *startdir.split(os.sep)[-2 - repolevel + 3:])
def caterror(mycat):
- err(mycat+" is not an official category. Skipping QA checks in this directory.\nPlease ensure that you add "+catdir+" to "+repodir+"/profiles/categories\nif it is a new category.")
+ err(mycat + " is not an official category. Skipping QA checks in this directory.\nPlease ensure that you add " + catdir + " to " + repodir + "/profiles/categories\nif it is a new category.")
+
+def repoman_getstatusoutput(cmd):
+ """
+ Implements an interface similar to getstatusoutput(), but with
+ customized unicode handling (see bug #310789) and without the shell.
+ """
+ args = portage.util.shlex_split(cmd)
+
+ if sys.hexversion < 0x3020000 and sys.hexversion >= 0x3000000 and \
+ not os.path.isabs(args[0]):
+ # Python 3.1 _execvp throws TypeError for non-absolute executable
+ # path passed as bytes (see http://bugs.python.org/issue8513).
+ fullname = find_binary(args[0])
+ if fullname is None:
+ raise portage.exception.CommandNotFound(args[0])
+ args[0] = fullname
+
+ encoding = _encodings['fs']
+ args = [_unicode_encode(x,
+ encoding=encoding, errors='strict') for x in args]
+ proc = subprocess.Popen(args, stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT)
+ output = portage._unicode_decode(proc.communicate()[0],
+ encoding=encoding, errors='strict')
+ if output and output[-1] == "\n":
+ # getstatusoutput strips one newline
+ output = output[:-1]
+ return (proc.wait(), output)
+
+class repoman_popen(portage.proxy.objectproxy.ObjectProxy):
+ """
+ Implements an interface similar to os.popen(), but with customized
+ unicode handling (see bug #310789) and without the shell.
+ """
+
+ __slots__ = ('_proc', '_stdout')
+
+ def __init__(self, cmd):
+ args = portage.util.shlex_split(cmd)
+
+ if sys.hexversion < 0x3020000 and sys.hexversion >= 0x3000000 and \
+ not os.path.isabs(args[0]):
+ # Python 3.1 _execvp throws TypeError for non-absolute executable
+ # path passed as bytes (see http://bugs.python.org/issue8513).
+ fullname = find_binary(args[0])
+ if fullname is None:
+ raise portage.exception.CommandNotFound(args[0])
+ args[0] = fullname
+
+ encoding = _encodings['fs']
+ args = [_unicode_encode(x,
+ encoding=encoding, errors='strict') for x in args]
+ proc = subprocess.Popen(args, stdout=subprocess.PIPE)
+ object.__setattr__(self, '_proc', proc)
+ object.__setattr__(self, '_stdout',
+ codecs.getreader(encoding)(proc.stdout, 'strict'))
+
+ def _get_target(self):
+ return object.__getattribute__(self, '_stdout')
+
+ __enter__ = _get_target
+
+ def __exit__(self, exc_type, exc_value, traceback):
+ proc = object.__getattribute__(self, '_proc')
+ proc.wait()
+ proc.stdout.close()
class ProfileDesc(object):
__slots__ = ('abs_path', 'arch', 'status', 'sub_path', 'tree_path',)
@@ -818,18 +886,18 @@ for path in portdb.porttrees:
continue
if len(arch) != 3:
err("wrong format: \"" + bad(x.strip()) + "\" in " + \
- desc_path + " line %d" % (i+1, ))
+ desc_path + " line %d" % (i + 1, ))
elif arch[0] not in kwlist:
err("invalid arch: \"" + bad(arch[0]) + "\" in " + \
- desc_path + " line %d" % (i+1, ))
+ desc_path + " line %d" % (i + 1, ))
elif arch[2] not in valid_profile_types:
err("invalid profile type: \"" + bad(arch[2]) + "\" in " + \
- desc_path + " line %d" % (i+1, ))
+ desc_path + " line %d" % (i + 1, ))
profile_desc = ProfileDesc(arch[0], arch[2], arch[1], path)
if not os.path.isdir(profile_desc.abs_path):
logging.error(
"Invalid %s profile (%s) for arch %s in %s line %d",
- arch[2], arch[1], arch[0], desc_path, i+1)
+ arch[2], arch[1], arch[0], desc_path, i + 1)
continue
if os.path.exists(
os.path.join(profile_desc.abs_path, 'deprecated')):
@@ -876,11 +944,16 @@ for x in repoman_settings.archlist():
if x[0] == "~":
continue
if x not in profiles:
- print(red("\""+x+"\" doesn't have a valid profile listed in profiles.desc."))
+ print(red("\"" + x + "\" doesn't have a valid profile listed in profiles.desc."))
print(red("You need to either \"cvs update\" your profiles dir or follow this"))
- print(red("up with the "+x+" team."))
+ print(red("up with the " + x + " team."))
print()
+liclist_deprecated = set()
+if "DEPRECATED" in repoman_settings._license_manager._license_groups:
+ liclist_deprecated.update(
+ repoman_settings._license_manager.expandLicenseTokens(["@DEPRECATED"]))
+
if not liclist:
logging.fatal("Couldn't find licenses?")
sys.exit(1)
@@ -893,34 +966,34 @@ if not uselist:
logging.fatal("Couldn't find use.desc?")
sys.exit(1)
-scanlist=[]
-if repolevel==2:
- #we are inside a category directory
- catdir=reposplit[-1]
+scanlist = []
+if repolevel == 2:
+ # we are inside a category directory
+ catdir = reposplit[-1]
if catdir not in categories:
caterror(catdir)
- mydirlist=os.listdir(startdir)
+ mydirlist = os.listdir(startdir)
for x in mydirlist:
if x == "CVS" or x.startswith("."):
continue
- if os.path.isdir(startdir+"/"+x):
- scanlist.append(catdir+"/"+x)
+ if os.path.isdir(startdir + "/" + x):
+ scanlist.append(catdir + "/" + x)
repo_subdir = catdir + os.sep
-elif repolevel==1:
+elif repolevel == 1:
for x in categories:
- if not os.path.isdir(startdir+"/"+x):
+ if not os.path.isdir(startdir + "/" + x):
continue
- for y in os.listdir(startdir+"/"+x):
+ for y in os.listdir(startdir + "/" + x):
if y == "CVS" or y.startswith("."):
continue
- if os.path.isdir(startdir+"/"+x+"/"+y):
- scanlist.append(x+"/"+y)
+ if os.path.isdir(startdir + "/" + x + "/" + y):
+ scanlist.append(x + "/" + y)
repo_subdir = ""
-elif repolevel==3:
+elif repolevel == 3:
catdir = reposplit[-2]
if catdir not in categories:
caterror(catdir)
- scanlist.append(catdir+"/"+reposplit[-1])
+ scanlist.append(catdir + "/" + reposplit[-1])
repo_subdir = scanlist[-1] + os.sep
else:
msg = 'Repoman is unable to determine PORTDIR or PORTDIR_OVERLAY' + \
@@ -952,7 +1025,7 @@ def vcs_files_to_cps(vcs_file_iter):
if category in categories:
for filename in vcs_file_iter:
f_split = filename.split(os.sep)
- # ['.', pn,...]
+ # ['.', pn, ...]
if len(f_split) > 2:
modified_cps.append(category + "/" + f_split[1])
@@ -960,7 +1033,7 @@ def vcs_files_to_cps(vcs_file_iter):
# repolevel == 1
for filename in vcs_file_iter:
f_split = filename.split(os.sep)
- # ['.', category, pn,...]
+ # ['.', category, pn, ...]
if len(f_split) > 3 and f_split[1] in categories:
modified_cps.append("/".join(f_split[1:3]))
@@ -968,12 +1041,12 @@ def vcs_files_to_cps(vcs_file_iter):
def git_supports_gpg_sign():
status, cmd_output = \
- subprocess_getstatusoutput("git --version")
+ repoman_getstatusoutput("git --version")
cmd_output = cmd_output.split()
if cmd_output:
version = re.match(r'^(\d+)\.(\d+)\.(\d+)', cmd_output[-1])
if version is not None:
- version = [int(x) for x in version.groups()[1:]]
+ version = [int(x) for x in version.groups()]
if version[0] > 1 or \
(version[0] == 1 and version[1] > 7) or \
(version[0] == 1 and version[1] == 7 and version[2] >= 9):
@@ -1002,47 +1075,16 @@ def dev_keywords(profiles):
dev_keywords = dev_keywords(profiles)
-stats={}
-fails={}
-
-# provided by the desktop-file-utils package
-desktop_file_validate = find_binary("desktop-file-validate")
-desktop_pattern = re.compile(r'.*\.desktop$')
+stats = {}
+fails = {}
for x in qacats:
- stats[x]=0
- fails[x]=[]
+ stats[x] = 0
+ fails[x] = []
xmllint_capable = False
metadata_dtd = os.path.join(repoman_settings["DISTDIR"], 'metadata.dtd')
-def parsedate(s):
- """Parse a RFC 822 date and time string.
- This is required for python3 compatibility, since the
- rfc822.parsedate() function is not available."""
-
- s_split = []
- for x in s.upper().split():
- for y in x.split(','):
- if y:
- s_split.append(y)
-
- if len(s_split) != 6:
- return None
-
- # %a, %d %b %Y %H:%M:%S %Z
- a, d, b, Y, H_M_S, Z = s_split
-
- # Convert month to integer, since strptime %w is locale-dependent.
- month_map = {'JAN':1, 'FEB':2, 'MAR':3, 'APR':4, 'MAY':5, 'JUN':6,
- 'JUL':7, 'AUG':8, 'SEP':9, 'OCT':10, 'NOV':11, 'DEC':12}
- m = month_map.get(b)
- if m is None:
- return None
- m = str(m).rjust(2, '0')
-
- return time.strptime(':'.join((Y, m, d, H_M_S)), '%Y:%m:%d:%H:%M:%S')
-
def fetch_metadata_dtd():
"""
Fetch metadata.dtd if it doesn't exist or the ctime is older than
@@ -1071,45 +1113,40 @@ def fetch_metadata_dtd():
print(green("***") + " the local copy of metadata.dtd " + \
"needs to be refetched, doing that now")
print()
+ parsed_url = urlparse(metadata_dtd_uri)
+ setting = 'FETCHCOMMAND_' + parsed_url.scheme.upper()
+ fcmd = repoman_settings.get(setting)
+ if not fcmd:
+ fcmd = repoman_settings.get('FETCHCOMMAND')
+ if not fcmd:
+ logging.error("FETCHCOMMAND is unset")
+ return False
+
+ destdir = repoman_settings["DISTDIR"]
+ fd, metadata_dtd_tmp = tempfile.mkstemp(
+ prefix='metadata.dtd.', dir=destdir)
+ os.close(fd)
+
try:
- url_f = urllib_request_urlopen(metadata_dtd_uri)
- msg_info = url_f.info()
- last_modified = msg_info.get('last-modified')
- if last_modified is not None:
- last_modified = parsedate(last_modified)
- if last_modified is not None:
- last_modified = calendar.timegm(last_modified)
-
- metadata_dtd_tmp = "%s.%s" % (metadata_dtd, os.getpid())
- try:
- local_f = open(metadata_dtd_tmp, mode='wb')
- local_f.write(url_f.read())
- local_f.close()
- if last_modified is not None:
- try:
- os.utime(metadata_dtd_tmp,
- (int(last_modified), int(last_modified)))
- except OSError:
- # This fails on some odd non-unix-like filesystems.
- # We don't really need the mtime to be preserved
- # anyway here (currently we use ctime to trigger
- # fetch), so just ignore it.
- pass
- os.rename(metadata_dtd_tmp, metadata_dtd)
- finally:
- try:
- os.unlink(metadata_dtd_tmp)
- except OSError:
- pass
+ if not portage.getbinpkg.file_get(metadata_dtd_uri,
+ destdir, fcmd=fcmd,
+ filename=os.path.basename(metadata_dtd_tmp)):
+ logging.error("failed to fetch metadata.dtd from '%s'" %
+ metadata_dtd_uri)
+ return False
- url_f.close()
+ try:
+ portage.util.apply_secpass_permissions(metadata_dtd_tmp,
+ gid=portage.data.portage_gid, mode=0o664, mask=0o2)
+ except portage.exception.PortageException:
+ pass
- except EnvironmentError as e:
- print()
- print(red("!!!")+" attempting to fetch '%s', caught" % metadata_dtd_uri)
- print(red("!!!")+" exception '%s' though." % (e,))
- print(red("!!!")+" fetching new metadata.dtd failed, aborting")
- return False
+ os.rename(metadata_dtd_tmp, metadata_dtd)
+ finally:
+ try:
+ os.unlink(metadata_dtd_tmp)
+ except OSError:
+ pass
return True
@@ -1117,14 +1154,14 @@ if options.mode == "manifest":
pass
elif not find_binary('xmllint'):
print(red("!!! xmllint not found. Can't check metadata.xml.\n"))
- if options.xml_parse or repolevel==3:
+ if options.xml_parse or repolevel == 3:
print(red("!!!")+" sorry, xmllint is needed. failing\n")
sys.exit(1)
else:
if not fetch_metadata_dtd():
sys.exit(1)
- #this can be problematic if xmllint changes their output
- xmllint_capable=True
+ # this can be problematic if xmllint changes their output
+ xmllint_capable = True
if options.mode == 'commit' and vcs:
utilities.detect_vcs_conflicts(options, vcs)
@@ -1151,45 +1188,46 @@ if vcs == "cvs":
myremoved = cvstree.findremoved(mycvstree, recursive=1, basedir="./")
elif vcs == "svn":
- with os.popen("svn status") as f:
+ with repoman_popen("svn status") as f:
svnstatus = f.readlines()
- mychanged = [ "./" + elem.split()[-1:][0] for elem in svnstatus if elem and elem[:1] in "MR" ]
- mynew = [ "./" + elem.split()[-1:][0] for elem in svnstatus if elem.startswith("A") ]
+ mychanged = ["./" + elem.split()[-1:][0] for elem in svnstatus if elem and elem[:1] in "MR"]
+ mynew = ["./" + elem.split()[-1:][0] for elem in svnstatus if elem.startswith("A")]
if options.if_modified == "y":
- myremoved = [ "./" + elem.split()[-1:][0] for elem in svnstatus if elem.startswith("D")]
+ myremoved = ["./" + elem.split()[-1:][0] for elem in svnstatus if elem.startswith("D")]
elif vcs == "git":
- with os.popen("git diff-index --name-only "
+ with repoman_popen("git diff-index --name-only "
"--relative --diff-filter=M HEAD") as f:
mychanged = f.readlines()
mychanged = ["./" + elem[:-1] for elem in mychanged]
- with os.popen("git diff-index --name-only "
+ with repoman_popen("git diff-index --name-only "
"--relative --diff-filter=A HEAD") as f:
mynew = f.readlines()
mynew = ["./" + elem[:-1] for elem in mynew]
if options.if_modified == "y":
- with os.popen("git diff-index --name-only "
+ with repoman_popen("git diff-index --name-only "
"--relative --diff-filter=D HEAD") as f:
myremoved = f.readlines()
myremoved = ["./" + elem[:-1] for elem in myremoved]
elif vcs == "bzr":
- with os.popen("bzr status -S .") as f:
+ with repoman_popen("bzr status -S .") as f:
bzrstatus = f.readlines()
- mychanged = [ "./" + elem.split()[-1:][0].split('/')[-1:][0] for elem in bzrstatus if elem and elem[1:2] == "M" ]
- mynew = [ "./" + elem.split()[-1:][0].split('/')[-1:][0] for elem in bzrstatus if elem and ( elem[1:2] == "NK" or elem[0:1] == "R" ) ]
+ mychanged = ["./" + elem.split()[-1:][0].split('/')[-1:][0] for elem in bzrstatus if elem and elem[1:2] == "M"]
+ mynew = ["./" + elem.split()[-1:][0].split('/')[-1:][0] for elem in bzrstatus if elem and (elem[1:2] == "NK" or elem[0:1] == "R")]
if options.if_modified == "y":
- myremoved = [ "./" + elem.split()[-3:-2][0].split('/')[-1:][0] for elem in bzrstatus if elem and ( elem[1:2] == "K" or elem[0:1] == "R" ) ]
+ myremoved = ["./" + elem.split()[-3:-2][0].split('/')[-1:][0] for elem in bzrstatus if elem and (elem[1:2] == "K" or elem[0:1] == "R")]
elif vcs == "hg":
- with os.popen("hg status --no-status --modified .") as f:
+ with repoman_popen("hg status --no-status --modified .") as f:
mychanged = f.readlines()
mychanged = ["./" + elem.rstrip() for elem in mychanged]
- mynew = os.popen("hg status --no-status --added .").readlines()
+ with repoman_popen("hg status --no-status --added .") as f:
+ mynew = f.readlines()
mynew = ["./" + elem.rstrip() for elem in mynew]
if options.if_modified == "y":
- with os.popen("hg status --no-status --removed .") as f:
+ with repoman_popen("hg status --no-status --removed .") as f:
myremoved = f.readlines()
myremoved = ["./" + elem.rstrip() for elem in myremoved]
@@ -1211,10 +1249,15 @@ dofail = 0
# NOTE: match-all caches are not shared due to potential
# differences between profiles in _get_implicit_iuse.
-arch_caches={}
+arch_caches = {}
arch_xmatch_caches = {}
shared_xmatch_caches = {"cp-list":{}}
+include_arches = None
+if options.include_arches:
+ include_arches = set()
+ include_arches.update(*[x.split() for x in options.include_arches])
+
# Disable the "ebuild.notadded" check when not in commit mode and
# running `svn status` in every package dir will be too expensive.
@@ -1222,12 +1265,37 @@ check_ebuild_notadded = not \
(vcs == "svn" and repolevel < 3 and options.mode != "commit")
# Build a regex from thirdpartymirrors for the SRC_URI.mirror check.
-thirdpartymirrors = []
-for v in repoman_settings.thirdpartymirrors().values():
+thirdpartymirrors = {}
+for k, v in repoman_settings.thirdpartymirrors().items():
for v in v:
if not v.endswith("/"):
v += "/"
- thirdpartymirrors.append(v)
+ thirdpartymirrors[v] = k
+
+class _XMLParser(xml.etree.ElementTree.XMLParser):
+
+ def __init__(self, data, **kwargs):
+ xml.etree.ElementTree.XMLParser.__init__(self, **kwargs)
+ self._portage_data = data
+ if hasattr(self, 'parser'):
+ self._base_XmlDeclHandler = self.parser.XmlDeclHandler
+ self.parser.XmlDeclHandler = self._portage_XmlDeclHandler
+ self._base_StartDoctypeDeclHandler = \
+ self.parser.StartDoctypeDeclHandler
+ self.parser.StartDoctypeDeclHandler = \
+ self._portage_StartDoctypeDeclHandler
+
+ def _portage_XmlDeclHandler(self, version, encoding, standalone):
+ if self._base_XmlDeclHandler is not None:
+ self._base_XmlDeclHandler(version, encoding, standalone)
+ self._portage_data["XML_DECLARATION"] = (version, encoding, standalone)
+
+ def _portage_StartDoctypeDeclHandler(self, doctypeName, systemId, publicId,
+ has_internal_subset):
+ if self._base_StartDoctypeDeclHandler is not None:
+ self._base_StartDoctypeDeclHandler(doctypeName, systemId, publicId,
+ has_internal_subset)
+ self._portage_data["DOCTYPE"] = (doctypeName, systemId, publicId)
class _MetadataTreeBuilder(xml.etree.ElementTree.TreeBuilder):
"""
@@ -1252,13 +1320,13 @@ if options.if_modified == "y":
chain(mychanged, mynew, myremoved)))
for x in effective_scanlist:
- #ebuilds and digests added to cvs respectively.
+ # ebuilds and digests added to cvs respectively.
logging.info("checking package %s" % x)
# save memory by discarding xmatch caches from previous package(s)
arch_xmatch_caches.clear()
- eadded=[]
- catdir,pkgdir=x.split("/")
- checkdir=repodir+"/"+x
+ eadded = []
+ catdir, pkgdir = x.split("/")
+ checkdir = repodir + "/" + x
checkdir_relative = ""
if repolevel < 3:
checkdir_relative = os.path.join(pkgdir, checkdir_relative)
@@ -1340,15 +1408,15 @@ for x in effective_scanlist:
if options.mode == 'manifest-check':
continue
- checkdirlist=os.listdir(checkdir)
- ebuildlist=[]
+ checkdirlist = os.listdir(checkdir)
+ ebuildlist = []
pkgs = {}
allvalid = True
for y in checkdirlist:
if (y in no_exec or y.endswith(".ebuild")) and \
- stat.S_IMODE(os.stat(os.path.join(checkdir, y)).st_mode) & 0o111:
- stats["file.executable"] += 1
- fails["file.executable"].append(os.path.join(checkdir, y))
+ stat.S_IMODE(os.stat(os.path.join(checkdir, y)).st_mode) & 0o111:
+ stats["file.executable"] += 1
+ fails["file.executable"].append(os.path.join(checkdir, y))
if y.endswith(".ebuild"):
pf = y[:-7]
ebuildlist.append(pf)
@@ -1389,19 +1457,19 @@ for x in effective_scanlist:
ebuildlist = [pkg.pf for pkg in ebuildlist]
for y in checkdirlist:
- m = disallowed_filename_chars_re.search(y.strip(os.sep))
- if m is not None:
+ index = repo_config.find_invalid_path_char(y)
+ if index != -1:
y_relative = os.path.join(checkdir_relative, y)
if vcs is not None and not vcs_new_changed(y_relative):
# If the file isn't in the VCS new or changed set, then
# assume that it's an irrelevant temporary file (Manifest
# entries are not generated for file names containing
# prohibited characters). See bug #406877.
- m = None
- if m is not None:
+ index = -1
+ if index != -1:
stats["file.name"] += 1
fails["file.name"].append("%s/%s: char '%s'" % \
- (checkdir, y, m.group(0)))
+ (checkdir, y, y[index]))
if not (y in ("ChangeLog", "metadata.xml") or y.endswith(".ebuild")):
continue
@@ -1412,7 +1480,7 @@ for x in effective_scanlist:
encoding=_encodings['fs'], errors='strict'),
mode='r', encoding=_encodings['repo.content'])
for l in f:
- line +=1
+ line += 1
except UnicodeDecodeError as ue:
stats["file.UTF8"] += 1
s = ue.object[:ue.start]
@@ -1427,10 +1495,10 @@ for x in effective_scanlist:
if vcs in ("git", "hg") and check_ebuild_notadded:
if vcs == "git":
- myf = os.popen("git ls-files --others %s" % \
+ myf = repoman_popen("git ls-files --others %s" % \
(portage._shell_quote(checkdir_relative),))
if vcs == "hg":
- myf = os.popen("hg status --no-status --unknown %s" % \
+ myf = repoman_popen("hg status --no-status --unknown %s" % \
(portage._shell_quote(checkdir_relative),))
for l in myf:
if l[:-1][-7:] == ".ebuild":
@@ -1442,21 +1510,23 @@ for x in effective_scanlist:
if vcs in ("cvs", "svn", "bzr") and check_ebuild_notadded:
try:
if vcs == "cvs":
- myf=open(checkdir+"/CVS/Entries","r")
+ myf = open(checkdir + "/CVS/Entries", "r")
if vcs == "svn":
- myf = os.popen("svn status --depth=files --verbose " + checkdir)
+ myf = repoman_popen("svn status --depth=files --verbose " +
+ portage._shell_quote(checkdir))
if vcs == "bzr":
- myf = os.popen("bzr ls -v --kind=file " + checkdir)
+ myf = repoman_popen("bzr ls -v --kind=file " +
+ portage._shell_quote(checkdir))
myl = myf.readlines()
myf.close()
for l in myl:
if vcs == "cvs":
- if l[0]!="/":
+ if l[0] != "/":
continue
- splitl=l[1:].split("/")
+ splitl = l[1:].split("/")
if not len(splitl):
continue
- if splitl[0][-7:]==".ebuild":
+ if splitl[0][-7:] == ".ebuild":
eadded.append(splitl[0][:-7])
if vcs == "svn":
if l[:1] == "?":
@@ -1474,8 +1544,9 @@ for x in effective_scanlist:
if l[-7:] == ".ebuild":
eadded.append(os.path.basename(l[:-7]))
if vcs == "svn":
- myf = os.popen("svn status " + checkdir)
- myl=myf.readlines()
+ myf = repoman_popen("svn status " +
+ portage._shell_quote(checkdir))
+ myl = myf.readlines()
myf.close()
for l in myl:
if l[0] == "A":
@@ -1485,7 +1556,7 @@ for x in effective_scanlist:
except IOError:
if vcs == "cvs":
stats["CVS/Entries.IO_error"] += 1
- fails["CVS/Entries.IO_error"].append(checkdir+"/CVS/Entries")
+ fails["CVS/Entries.IO_error"].append(checkdir + "/CVS/Entries")
else:
raise
continue
@@ -1493,7 +1564,7 @@ for x in effective_scanlist:
mf = repoman_settings.repositories.get_repo_for_location(
os.path.dirname(os.path.dirname(checkdir)))
mf = mf.load_manifest(checkdir, repoman_settings["DISTDIR"])
- mydigests=mf.getTypeDigests("DIST")
+ mydigests = mf.getTypeDigests("DIST")
fetchlist_dict = portage.FetchlistDict(checkdir, repoman_settings, portdb)
myfiles_all = []
@@ -1509,7 +1580,7 @@ for x in effective_scanlist:
# This will be reported as an "ebuild.syntax" error.
pass
else:
- stats["SRC_URI.syntax"] = stats["SRC_URI.syntax"] + 1
+ stats["SRC_URI.syntax"] += 1
fails["SRC_URI.syntax"].append(
"%s.ebuild SRC_URI: %s" % (mykey, e))
del fetchlist_dict
@@ -1523,15 +1594,15 @@ for x in effective_scanlist:
for entry in mydigests:
if entry not in myfiles_all:
stats["digest.unused"] += 1
- fails["digest.unused"].append(checkdir+"::"+entry)
+ fails["digest.unused"].append(checkdir + "::" + entry)
for entry in myfiles_all:
if entry not in mydigests:
stats["digest.missing"] += 1
- fails["digest.missing"].append(checkdir+"::"+entry)
+ fails["digest.missing"].append(checkdir + "::" + entry)
del myfiles_all
- if os.path.exists(checkdir+"/files"):
- filesdirlist=os.listdir(checkdir+"/files")
+ if os.path.exists(checkdir + "/files"):
+ filesdirlist = os.listdir(checkdir + "/files")
# recurse through files directory
# use filesdirlist as a stack, appending directories as needed so people can't hide > 20k files in a subdirectory.
@@ -1551,77 +1622,110 @@ for x in effective_scanlist:
# !!! VCS "portability" alert! Need some function isVcsDir() or alike !!!
if y == "CVS" or y == ".svn":
continue
- for z in os.listdir(checkdir+"/files/"+y):
+ for z in os.listdir(checkdir + "/files/" + y):
if z == "CVS" or z == ".svn":
continue
- filesdirlist.append(y+"/"+z)
+ filesdirlist.append(y + "/" + z)
# Current policy is no files over 20 KiB, these are the checks. File size between
# 20 KiB and 60 KiB causes a warning, while file size over 60 KiB causes an error.
elif mystat.st_size > 61440:
stats["file.size.fatal"] += 1
- fails["file.size.fatal"].append("("+ str(mystat.st_size//1024) + " KiB) "+x+"/files/"+y)
+ fails["file.size.fatal"].append("(" + str(mystat.st_size//1024) + " KiB) " + x + "/files/" + y)
elif mystat.st_size > 20480:
stats["file.size"] += 1
- fails["file.size"].append("("+ str(mystat.st_size//1024) + " KiB) "+x+"/files/"+y)
+ fails["file.size"].append("(" + str(mystat.st_size//1024) + " KiB) " + x + "/files/" + y)
- m = disallowed_filename_chars_re.search(
- os.path.basename(y.rstrip(os.sep)))
- if m is not None:
+ index = repo_config.find_invalid_path_char(y)
+ if index != -1:
y_relative = os.path.join(checkdir_relative, "files", y)
if vcs is not None and not vcs_new_changed(y_relative):
# If the file isn't in the VCS new or changed set, then
# assume that it's an irrelevant temporary file (Manifest
# entries are not generated for file names containing
# prohibited characters). See bug #406877.
- m = None
- if m is not None:
+ index = -1
+ if index != -1:
stats["file.name"] += 1
fails["file.name"].append("%s/files/%s: char '%s'" % \
- (checkdir, y, m.group(0)))
-
- if desktop_file_validate and desktop_pattern.match(y):
- cmd_output = validate_desktop_entry(full_path)
- if cmd_output:
- # Note: in the future we may want to grab the
- # warnings in addition to the errors. We're
- # just doing errors now since we don't want
- # to generate too much noise at first.
- error_re = re.compile(r'.*\s*error:\s*(.*)')
- for line in cmd_output:
- error_match = error_re.match(line)
- if error_match is None:
- continue
- stats["desktop.invalid"] += 1
- fails["desktop.invalid"].append(
- relative_path + ': %s' % error_match.group(1))
-
+ (checkdir, y, y[index]))
del mydigests
if check_changelog and "ChangeLog" not in checkdirlist:
- stats["changelog.missing"]+=1
- fails["changelog.missing"].append(x+"/ChangeLog")
-
+ stats["changelog.missing"] += 1
+ fails["changelog.missing"].append(x + "/ChangeLog")
+
musedict = {}
- #metadata.xml file check
+ # metadata.xml file check
if "metadata.xml" not in checkdirlist:
- stats["metadata.missing"]+=1
- fails["metadata.missing"].append(x+"/metadata.xml")
- #metadata.xml parse check
+ stats["metadata.missing"] += 1
+ fails["metadata.missing"].append(x + "/metadata.xml")
+ # metadata.xml parse check
else:
metadata_bad = False
+ xml_info = {}
+ xml_parser = _XMLParser(xml_info, target=_MetadataTreeBuilder())
# read metadata.xml into memory
try:
_metadata_xml = xml.etree.ElementTree.parse(
- os.path.join(checkdir, "metadata.xml"),
- parser=xml.etree.ElementTree.XMLParser(
- target=_MetadataTreeBuilder()))
+ _unicode_encode(os.path.join(checkdir, "metadata.xml"),
+ encoding=_encodings['fs'], errors='strict'),
+ parser=xml_parser)
except (ExpatError, SyntaxError, EnvironmentError) as e:
metadata_bad = True
stats["metadata.bad"] += 1
fails["metadata.bad"].append("%s/metadata.xml: %s" % (x, e))
del e
else:
+ if not hasattr(xml_parser, 'parser') or \
+ sys.hexversion < 0x2070000 or \
+ (sys.hexversion > 0x3000000 and sys.hexversion < 0x3020000):
+ # doctype is not parsed with python 2.6 or 3.1
+ pass
+ else:
+ if "XML_DECLARATION" not in xml_info:
+ stats["metadata.bad"] += 1
+ fails["metadata.bad"].append("%s/metadata.xml: "
+ "xml declaration is missing on first line, "
+ "should be '%s'" % (x, metadata_xml_declaration))
+ else:
+ xml_version, xml_encoding, xml_standalone = \
+ xml_info["XML_DECLARATION"]
+ if xml_encoding is None or \
+ xml_encoding.upper() != metadata_xml_encoding:
+ stats["metadata.bad"] += 1
+ if xml_encoding is None:
+ encoding_problem = "but it is undefined"
+ else:
+ encoding_problem = "not '%s'" % xml_encoding
+ fails["metadata.bad"].append("%s/metadata.xml: "
+ "xml declaration encoding should be '%s', %s" %
+ (x, metadata_xml_encoding, encoding_problem))
+
+ if "DOCTYPE" not in xml_info:
+ metadata_bad = True
+ stats["metadata.bad"] += 1
+ fails["metadata.bad"].append("%s/metadata.xml: %s" % (x,
+ "DOCTYPE is missing"))
+ else:
+ doctype_name, doctype_system, doctype_pubid = \
+ xml_info["DOCTYPE"]
+ if doctype_system != metadata_dtd_uri:
+ stats["metadata.bad"] += 1
+ if doctype_system is None:
+ system_problem = "but it is undefined"
+ else:
+ system_problem = "not '%s'" % doctype_system
+ fails["metadata.bad"].append("%s/metadata.xml: "
+ "DOCTYPE: SYSTEM should refer to '%s', %s" %
+ (x, metadata_dtd_uri, system_problem))
+
+ if doctype_name != metadata_doctype_name:
+ stats["metadata.bad"] += 1
+ fails["metadata.bad"].append("%s/metadata.xml: "
+ "DOCTYPE: name should be '%s', not '%s'" %
+ (x, metadata_doctype_name, doctype_name))
+
# load USE flags from metadata.xml
try:
musedict = utilities.parse_metadata_use(_metadata_xml)
@@ -1629,6 +1733,22 @@ for x in effective_scanlist:
metadata_bad = True
stats["metadata.bad"] += 1
fails["metadata.bad"].append("%s/metadata.xml: %s" % (x, e))
+ else:
+ for atom in chain(*musedict.values()):
+ if atom is None:
+ continue
+ try:
+ atom = Atom(atom)
+ except InvalidAtom as e:
+ stats["metadata.bad"] += 1
+ fails["metadata.bad"].append(
+ "%s/metadata.xml: Invalid atom: %s" % (x, e))
+ else:
+ if atom.cp != x:
+ stats["metadata.bad"] += 1
+ fails["metadata.bad"].append(
+ ("%s/metadata.xml: Atom contains "
+ "unexpected cat/pn: %s") % (x, atom))
# Run other metadata.xml checkers
try:
@@ -1639,19 +1759,20 @@ for x in effective_scanlist:
fails["metadata.bad"].append("%s/metadata.xml: %s" % (x, e))
del e
- #Only carry out if in package directory or check forced
+ # Only carry out if in package directory or check forced
if xmllint_capable and not metadata_bad:
# xmlint can produce garbage output even on success, so only dump
# the ouput when it fails.
- st, out = subprocess_getstatusoutput(
- "xmllint --nonet --noout --dtdvalid '%s' '%s'" % \
- (metadata_dtd, os.path.join(checkdir, "metadata.xml")))
+ st, out = repoman_getstatusoutput(
+ "xmllint --nonet --noout --dtdvalid %s %s" % \
+ (portage._shell_quote(metadata_dtd),
+ portage._shell_quote(os.path.join(checkdir, "metadata.xml"))))
if st != os.EX_OK:
print(red("!!!") + " metadata.xml is invalid:")
for z in out.splitlines():
- print(red("!!! ")+z)
- stats["metadata.bad"]+=1
- fails["metadata.bad"].append(x+"/metadata.xml")
+ print(red("!!! ") + z)
+ stats["metadata.bad"] += 1
+ fails["metadata.bad"].append(x + "/metadata.xml")
del metadata_bad
muselist = frozenset(musedict)
@@ -1677,20 +1798,20 @@ for x in effective_scanlist:
fails['changelog.ebuildadded'].append(relative_path)
if vcs in ("cvs", "svn", "bzr") and check_ebuild_notadded and y not in eadded:
- #ebuild not added to vcs
- stats["ebuild.notadded"]=stats["ebuild.notadded"]+1
- fails["ebuild.notadded"].append(x+"/"+y+".ebuild")
- myesplit=portage.pkgsplit(y)
+ # ebuild not added to vcs
+ stats["ebuild.notadded"] += 1
+ fails["ebuild.notadded"].append(x + "/" + y + ".ebuild")
+ myesplit = portage.pkgsplit(y)
if myesplit is None or myesplit[0] != x.split("/")[-1] \
or pv_toolong_re.search(myesplit[1]) \
or pv_toolong_re.search(myesplit[2]):
- stats["ebuild.invalidname"]=stats["ebuild.invalidname"]+1
- fails["ebuild.invalidname"].append(x+"/"+y+".ebuild")
+ stats["ebuild.invalidname"] += 1
+ fails["ebuild.invalidname"].append(x + "/" + y + ".ebuild")
continue
- elif myesplit[0]!=pkgdir:
- print(pkgdir,myesplit[0])
- stats["ebuild.namenomatch"]=stats["ebuild.namenomatch"]+1
- fails["ebuild.namenomatch"].append(x+"/"+y+".ebuild")
+ elif myesplit[0] != pkgdir:
+ print(pkgdir, myesplit[0])
+ stats["ebuild.namenomatch"] += 1
+ fails["ebuild.namenomatch"].append(x + "/" + y + ".ebuild")
continue
pkg = pkgs[y]
@@ -1699,15 +1820,25 @@ for x in effective_scanlist:
allvalid = False
for k, msgs in pkg.invalid.items():
for msg in msgs:
- stats[k] = stats[k] + 1
- fails[k].append("%s %s" % (relative_path, msg))
+ stats[k] += 1
+ fails[k].append("%s: %s" % (relative_path, msg))
continue
- myaux = pkg.metadata
+ myaux = pkg._metadata
eapi = myaux["EAPI"]
inherited = pkg.inherited
live_ebuild = live_eclasses.intersection(inherited)
+ if repo_config.eapi_is_banned(eapi):
+ stats["repo.eapi.banned"] += 1
+ fails["repo.eapi.banned"].append(
+ "%s: %s" % (relative_path, eapi))
+
+ elif repo_config.eapi_is_deprecated(eapi):
+ stats["repo.eapi.deprecated"] += 1
+ fails["repo.eapi.deprecated"].append(
+ "%s: %s" % (relative_path, eapi))
+
for k, v in myaux.items():
if not isinstance(v, basestring):
continue
@@ -1724,20 +1855,21 @@ for x in effective_scanlist:
for uri in portage.dep.use_reduce( \
myaux["SRC_URI"], matchall=True, is_src_uri=True, eapi=eapi, flat=True):
contains_mirror = False
- for mirror in thirdpartymirrors:
+ for mirror, mirror_alias in thirdpartymirrors.items():
if uri.startswith(mirror):
contains_mirror = True
break
if not contains_mirror:
continue
+ new_uri = "mirror://%s/%s" % (mirror_alias, uri[len(mirror):])
stats["SRC_URI.mirror"] += 1
fails["SRC_URI.mirror"].append(
- "%s: '%s' found in thirdpartymirrors" % \
- (relative_path, mirror))
+ "%s: '%s' found in thirdpartymirrors, use '%s'" % \
+ (relative_path, mirror, new_uri))
if myaux.get("PROVIDE"):
- stats["virtual.oldstyle"]+=1
+ stats["virtual.oldstyle"] += 1
fails["virtual.oldstyle"].append(relative_path)
for pos, missing_var in enumerate(missingvars):
@@ -1747,15 +1879,15 @@ for x in effective_scanlist:
continue
if live_ebuild and missing_var == "KEYWORDS":
continue
- myqakey=missingvars[pos]+".missing"
- stats[myqakey]=stats[myqakey]+1
- fails[myqakey].append(x+"/"+y+".ebuild")
+ myqakey = missingvars[pos] + ".missing"
+ stats[myqakey] += 1
+ fails[myqakey].append(x + "/" + y + ".ebuild")
if catdir == "virtual":
for var in ("HOMEPAGE", "LICENSE"):
if myaux.get(var):
myqakey = var + ".virtual"
- stats[myqakey] = stats[myqakey] + 1
+ stats[myqakey] += 1
fails[myqakey].append(relative_path)
# 14 is the length of DESCRIPTION=""
@@ -1772,7 +1904,7 @@ for x in effective_scanlist:
not keyword.startswith("-"):
stable_keywords.append(keyword)
if stable_keywords:
- if ebuild_path in new_ebuilds:
+ if ebuild_path in new_ebuilds and catdir != "virtual":
stable_keywords.sort()
stats["KEYWORDS.stable"] += 1
fails["KEYWORDS.stable"].append(
@@ -1782,10 +1914,10 @@ for x in effective_scanlist:
ebuild_archs = set(kw.lstrip("~") for kw in keywords \
if not kw.startswith("-"))
- previous_keywords = slot_keywords.get(myaux["SLOT"])
+ previous_keywords = slot_keywords.get(pkg.slot)
if previous_keywords is None:
- slot_keywords[myaux["SLOT"]] = set()
- elif ebuild_archs and not live_ebuild:
+ slot_keywords[pkg.slot] = set()
+ elif ebuild_archs and "*" not in ebuild_archs and not live_ebuild:
dropped_keywords = previous_keywords.difference(ebuild_archs)
if dropped_keywords:
stats["KEYWORDS.dropped"] += 1
@@ -1793,7 +1925,7 @@ for x in effective_scanlist:
relative_path + ": %s" % \
" ".join(sorted(dropped_keywords)))
- slot_keywords[myaux["SLOT"]].update(ebuild_archs)
+ slot_keywords[pkg.slot].update(ebuild_archs)
# KEYWORDS="-*" is a stupid replacement for package.mask and screws general KEYWORDS semantics
if "-*" in keywords:
@@ -1805,7 +1937,7 @@ for x in effective_scanlist:
haskeyword = True
if not haskeyword:
stats["KEYWORDS.stupid"] += 1
- fails["KEYWORDS.stupid"].append(x+"/"+y+".ebuild")
+ fails["KEYWORDS.stupid"].append(x + "/" + y + ".ebuild")
"""
Ebuilds that inherit a "Live" eclass (darcs,subversion,git,cvs,etc..) should
@@ -1833,37 +1965,53 @@ for x in effective_scanlist:
arches = [[repoman_settings["ARCH"], repoman_settings["ARCH"],
repoman_settings["ACCEPT_KEYWORDS"].split()]]
else:
- arches=[]
- for keyword in myaux["KEYWORDS"].split():
- if (keyword[0]=="-"):
+ arches = set()
+ for keyword in keywords:
+ if keyword[0] == "-":
continue
- elif (keyword[0]=="~"):
- arches.append([keyword, keyword[1:], [keyword[1:], keyword]])
+ elif keyword[0] == "~":
+ arch = keyword[1:]
+ if arch == "*":
+ for expanded_arch in profiles:
+ if expanded_arch == "**":
+ continue
+ arches.add((keyword, expanded_arch,
+ (expanded_arch, "~" + expanded_arch)))
+ else:
+ arches.add((keyword, arch, (arch, keyword)))
else:
- arches.append([keyword, keyword, [keyword]])
+ if keyword == "*":
+ for expanded_arch in profiles:
+ if expanded_arch == "**":
+ continue
+ arches.add((keyword, expanded_arch,
+ (expanded_arch,)))
+ else:
+ arches.add((keyword, keyword, (keyword,)))
if not arches:
# Use an empty profile for checking dependencies of
# packages that have empty KEYWORDS.
- arches.append(['**', '**', ['**']])
+ arches.add(('**', '**', ('**',)))
unknown_pkgs = set()
baddepsyntax = False
badlicsyntax = False
badprovsyntax = False
- catpkg = catdir+"/"+y
+ catpkg = catdir + "/" + y
inherited_java_eclass = "java-pkg-2" in inherited or \
"java-pkg-opt-2" in inherited
inherited_wxwidgets_eclass = "wxwidgets" in inherited
operator_tokens = set(["||", "(", ")"])
type_list, badsyntax = [], []
- for mytype in ("DEPEND", "RDEPEND", "PDEPEND",
- "LICENSE", "PROPERTIES", "PROVIDE"):
+ for mytype in Package._dep_keys + ("LICENSE", "PROPERTIES", "PROVIDE"):
mydepstr = myaux[mytype]
+ buildtime = mytype in Package._buildtime_keys
+ runtime = mytype in Package._runtime_keys
token_class = None
- if mytype in ("DEPEND", "RDEPEND", "PDEPEND"):
- token_class=portage.dep.Atom
+ if mytype.endswith("DEPEND"):
+ token_class = portage.dep.Atom
try:
atoms = portage.dep.use_reduce(mydepstr, matchall=1, flat=True, \
@@ -1872,8 +2020,8 @@ for x in effective_scanlist:
atoms = None
badsyntax.append(str(e))
- if atoms and mytype in ("DEPEND", "RDEPEND", "PDEPEND"):
- if mytype in ("RDEPEND", "PDEPEND") and \
+ if atoms and mytype.endswith("DEPEND"):
+ if runtime and \
"test?" in mydepstr.split():
stats[mytype + '.suspect'] += 1
fails[mytype + '.suspect'].append(relative_path + \
@@ -1902,21 +2050,21 @@ for x in effective_scanlist:
": %s: consider using '%s' instead of '%s'" %
(mytype, suspect_virtual[atom.cp], atom))
- if mytype == "DEPEND" and \
+ if buildtime and \
not is_blocker and \
not inherited_java_eclass and \
atom.cp == "virtual/jdk":
stats['java.eclassesnotused'] += 1
fails['java.eclassesnotused'].append(relative_path)
- elif mytype == "DEPEND" and \
+ elif buildtime and \
not is_blocker and \
not inherited_wxwidgets_eclass and \
atom.cp == "x11-libs/wxGTK":
stats['wxwidgets.eclassnotused'] += 1
fails['wxwidgets.eclassnotused'].append(
- relative_path + ": DEPENDs on x11-libs/wxGTK"
- " without inheriting wxwidgets.eclass")
- elif mytype in ("PDEPEND", "RDEPEND"):
+ (relative_path + ": %ss on x11-libs/wxGTK"
+ " without inheriting wxwidgets.eclass") % mytype)
+ elif runtime:
if not is_blocker and \
atom.cp in suspect_rdepend:
stats[mytype + '.suspect'] += 1
@@ -1925,21 +2073,26 @@ for x in effective_scanlist:
if atom.operator == "~" and \
portage.versions.catpkgsplit(atom.cpv)[3] != "r0":
- stats[mytype + '.badtilde'] += 1
- fails[mytype + '.badtilde'].append(
+ qacat = 'dependency.badtilde'
+ stats[qacat] += 1
+ fails[qacat].append(
(relative_path + ": %s uses the ~ operator"
" with a non-zero revision:" + \
" '%s'") % (mytype, atom))
type_list.extend([mytype] * (len(badsyntax) - len(type_list)))
- for m,b in zip(type_list, badsyntax):
- stats[m+".syntax"] += 1
- fails[m+".syntax"].append(catpkg+".ebuild "+m+": "+b)
+ for m, b in zip(type_list, badsyntax):
+ if m.endswith("DEPEND"):
+ qacat = "dependency.syntax"
+ else:
+ qacat = m + ".syntax"
+ stats[qacat] += 1
+ fails[qacat].append("%s: %s: %s" % (relative_path, m, b))
badlicsyntax = len([z for z in type_list if z == "LICENSE"])
badprovsyntax = len([z for z in type_list if z == "PROVIDE"])
- baddepsyntax = len(type_list) != badlicsyntax + badprovsyntax
+ baddepsyntax = len(type_list) != badlicsyntax + badprovsyntax
badlicsyntax = badlicsyntax > 0
badprovsyntax = badprovsyntax > 0
@@ -1955,7 +2108,7 @@ for x in effective_scanlist:
myuse.append(flag_name)
# uselist checks - metadata
- for mypos in range(len(myuse)-1,-1,-1):
+ for mypos in range(len(myuse)-1, -1, -1):
if myuse[mypos] and (myuse[mypos] in muselist):
del myuse[mypos]
@@ -1968,8 +2121,17 @@ for x in effective_scanlist:
" '%s'") % (eapi, myflag))
for mypos in range(len(myuse)):
- stats["IUSE.invalid"]=stats["IUSE.invalid"]+1
- fails["IUSE.invalid"].append(x+"/"+y+".ebuild: %s" % myuse[mypos])
+ stats["IUSE.invalid"] += 1
+ fails["IUSE.invalid"].append(x + "/" + y + ".ebuild: %s" % myuse[mypos])
+
+ # Check for outdated RUBY targets
+ if "ruby-ng" in inherited or "ruby-fakegem" in inherited or "ruby" in inherited:
+ ruby_intersection = pkg.iuse.all.intersection(ruby_deprecated)
+ if ruby_intersection:
+ for myruby in ruby_intersection:
+ stats["IUSE.rubydeprecated"] += 1
+ fails["IUSE.rubydeprecated"].append(
+ (relative_path + ": Deprecated ruby target: %s") % myruby)
# license checks
if not badlicsyntax:
@@ -1982,10 +2144,13 @@ for x in effective_scanlist:
# Need to check for "||" manually as no portage
# function will remove it without removing values.
if lic not in liclist and lic != "||":
- stats["LICENSE.invalid"]=stats["LICENSE.invalid"]+1
- fails["LICENSE.invalid"].append(x+"/"+y+".ebuild: %s" % lic)
+ stats["LICENSE.invalid"] += 1
+ fails["LICENSE.invalid"].append(x + "/" + y + ".ebuild: %s" % lic)
+ elif lic in liclist_deprecated:
+ stats["LICENSE.deprecated"] += 1
+ fails["LICENSE.deprecated"].append("%s: %s" % (relative_path, lic))
- #keyword checks
+ # keyword checks
myuse = myaux["KEYWORDS"].split()
for mykey in myuse:
if mykey not in ("-*", "*", "~*"):
@@ -1996,17 +2161,17 @@ for x in effective_scanlist:
myskey = myskey[1:]
if myskey not in kwlist:
stats["KEYWORDS.invalid"] += 1
- fails["KEYWORDS.invalid"].append(x+"/"+y+".ebuild: %s" % mykey)
+ fails["KEYWORDS.invalid"].append(x + "/" + y + ".ebuild: %s" % mykey)
elif myskey not in profiles:
stats["KEYWORDS.invalid"] += 1
- fails["KEYWORDS.invalid"].append(x+"/"+y+".ebuild: %s (profile invalid)" % mykey)
+ fails["KEYWORDS.invalid"].append(x + "/" + y + ".ebuild: %s (profile invalid)" % mykey)
- #restrict checks
+ # restrict checks
myrestrict = None
try:
myrestrict = portage.dep.use_reduce(myaux["RESTRICT"], matchall=1, flat=True)
except portage.exception.InvalidDependString as e:
- stats["RESTRICT.syntax"] = stats["RESTRICT.syntax"] + 1
+ stats["RESTRICT.syntax"] += 1
fails["RESTRICT.syntax"].append(
"%s: RESTRICT: %s" % (relative_path, e))
del e
@@ -2016,8 +2181,8 @@ for x in effective_scanlist:
if mybadrestrict:
stats["RESTRICT.invalid"] += len(mybadrestrict)
for mybad in mybadrestrict:
- fails["RESTRICT.invalid"].append(x+"/"+y+".ebuild: %s" % mybad)
- #REQUIRED_USE check
+ fails["RESTRICT.invalid"].append(x + "/" + y + ".ebuild: %s" % mybad)
+ # REQUIRED_USE check
required_use = myaux["REQUIRED_USE"]
if required_use:
if not eapi_has_required_use(eapi):
@@ -2027,9 +2192,9 @@ for x in effective_scanlist:
" not supported with EAPI='%s'" % (eapi,))
try:
portage.dep.check_required_use(required_use, (),
- pkg.iuse.is_valid_flag)
+ pkg.iuse.is_valid_flag, eapi=eapi)
except portage.exception.InvalidDependString as e:
- stats["REQUIRED_USE.syntax"] = stats["REQUIRED_USE.syntax"] + 1
+ stats["REQUIRED_USE.syntax"] += 1
fails["REQUIRED_USE.syntax"].append(
"%s: REQUIRED_USE: %s" % (relative_path, e))
del e
@@ -2062,127 +2227,154 @@ for x in effective_scanlist:
# user is intent on forcing the commit anyway.
continue
- for keyword,arch,groups in arches:
-
+ relevant_profiles = []
+ for keyword, arch, groups in arches:
if arch not in profiles:
# A missing profile will create an error further down
# during the KEYWORDS verification.
continue
-
- for prof in profiles[arch]:
- if prof.status not in ("stable", "dev") or \
- prof.status == "dev" and not options.include_dev:
+ if include_arches is not None:
+ if arch not in include_arches:
continue
- dep_settings = arch_caches.get(prof.sub_path)
- if dep_settings is None:
- dep_settings = portage.config(
- config_profile_path=prof.abs_path,
- config_incrementals=repoman_incrementals,
- config_root=config_root,
- local_config=False,
- _unmatched_removal=options.unmatched_removal,
- env=env)
- dep_settings.categories = repoman_settings.categories
- if options.without_mask:
- dep_settings._mask_manager_obj = \
- copy.deepcopy(dep_settings._mask_manager)
- dep_settings._mask_manager._pmaskdict.clear()
- arch_caches[prof.sub_path] = dep_settings
-
- xmatch_cache_key = (prof.sub_path, tuple(groups))
- xcache = arch_xmatch_caches.get(xmatch_cache_key)
- if xcache is None:
- portdb.melt()
- portdb.freeze()
- xcache = portdb.xcache
- xcache.update(shared_xmatch_caches)
- arch_xmatch_caches[xmatch_cache_key] = xcache
-
- trees[root]["porttree"].settings = dep_settings
- portdb.settings = dep_settings
- portdb.xcache = xcache
- # for package.use.mask support inside dep_check
- dep_settings.setcpv(pkg)
- dep_settings["ACCEPT_KEYWORDS"] = " ".join(groups)
- # just in case, prevent config.reset() from nuking these.
- dep_settings.backup_changes("ACCEPT_KEYWORDS")
-
- if not baddepsyntax:
- ismasked = not ebuild_archs or \
- pkg.cpv not in portdb.xmatch("match-visible", pkg.cp)
- if ismasked:
- if not have_pmasked:
- have_pmasked = bool(dep_settings._getMaskAtom(
- pkg.cpv, pkg.metadata))
- if options.ignore_masked:
- continue
- #we are testing deps for a masked package; give it some lee-way
- suffix="masked"
- matchmode = "minimum-all"
- else:
- suffix=""
- matchmode = "minimum-visible"
-
- if not have_dev_keywords:
- have_dev_keywords = \
- bool(dev_keywords.intersection(keywords))
-
- if prof.status == "dev":
- suffix=suffix+"indev"
-
- for mytype,mypos in [["DEPEND",len(missingvars)],["RDEPEND",len(missingvars)+1],["PDEPEND",len(missingvars)+2]]:
-
- mykey=mytype+".bad"+suffix
- myvalue = myaux[mytype]
- if not myvalue:
- continue
-
- success, atoms = portage.dep_check(myvalue, portdb,
- dep_settings, use="all", mode=matchmode,
- trees=trees)
-
- if success:
- if atoms:
-
- # Don't bother with dependency.unknown for
- # cases in which *DEPEND.bad is triggered.
- for atom in atoms:
- # dep_check returns all blockers and they
- # aren't counted for *DEPEND.bad, so we
- # ignore them here.
- if not atom.blocker:
- unknown_pkgs.discard(
- (mytype, atom.unevaluated_atom))
-
- if not prof.sub_path:
- # old-style virtuals currently aren't
- # resolvable with empty profile, since
- # 'virtuals' mappings are unavailable
- # (it would be expensive to search
- # for PROVIDE in all ebuilds)
- atoms = [atom for atom in atoms if not \
- (atom.cp.startswith('virtual/') and \
- not portdb.cp_list(atom.cp))]
-
- #we have some unsolvable deps
- #remove ! deps, which always show up as unsatisfiable
- atoms = [str(atom.unevaluated_atom) \
- for atom in atoms if not atom.blocker]
-
- #if we emptied out our list, continue:
- if not atoms:
- continue
- stats[mykey]=stats[mykey]+1
- fails[mykey].append("%s: %s(%s) %s" % \
- (relative_path, keyword,
- prof, repr(atoms)))
- else:
- stats[mykey]=stats[mykey]+1
- fails[mykey].append("%s: %s(%s) %s" % \
- (relative_path, keyword,
+ relevant_profiles.extend((keyword, groups, prof)
+ for prof in profiles[arch])
+
+ def sort_key(item):
+ return item[2].sub_path
+
+ relevant_profiles.sort(key=sort_key)
+
+ for keyword, groups, prof in relevant_profiles:
+
+ if not (prof.status == "stable" or \
+ (prof.status == "dev" and options.include_dev) or \
+ (prof.status == "exp" and options.include_exp_profiles == 'y')):
+ continue
+
+ dep_settings = arch_caches.get(prof.sub_path)
+ if dep_settings is None:
+ dep_settings = portage.config(
+ config_profile_path=prof.abs_path,
+ config_incrementals=repoman_incrementals,
+ config_root=config_root,
+ local_config=False,
+ _unmatched_removal=options.unmatched_removal,
+ env=env, repositories=repoman_settings.repositories)
+ dep_settings.categories = repoman_settings.categories
+ if options.without_mask:
+ dep_settings._mask_manager_obj = \
+ copy.deepcopy(dep_settings._mask_manager)
+ dep_settings._mask_manager._pmaskdict.clear()
+ arch_caches[prof.sub_path] = dep_settings
+
+ xmatch_cache_key = (prof.sub_path, tuple(groups))
+ xcache = arch_xmatch_caches.get(xmatch_cache_key)
+ if xcache is None:
+ portdb.melt()
+ portdb.freeze()
+ xcache = portdb.xcache
+ xcache.update(shared_xmatch_caches)
+ arch_xmatch_caches[xmatch_cache_key] = xcache
+
+ trees[root]["porttree"].settings = dep_settings
+ portdb.settings = dep_settings
+ portdb.xcache = xcache
+
+ dep_settings["ACCEPT_KEYWORDS"] = " ".join(groups)
+ # just in case, prevent config.reset() from nuking these.
+ dep_settings.backup_changes("ACCEPT_KEYWORDS")
+
+ # This attribute is used in dbapi._match_use() to apply
+ # use.stable.{mask,force} settings based on the stable
+ # status of the parent package. This is required in order
+ # for USE deps of unstable packages to be resolved correctly,
+ # since otherwise use.stable.{mask,force} settings of
+ # dependencies may conflict (see bug #456342).
+ dep_settings._parent_stable = dep_settings._isStable(pkg)
+
+ # Handle package.use*.{force,mask) calculation, for use
+ # in dep_check.
+ dep_settings.useforce = dep_settings._use_manager.getUseForce(
+ pkg, stable=dep_settings._parent_stable)
+ dep_settings.usemask = dep_settings._use_manager.getUseMask(
+ pkg, stable=dep_settings._parent_stable)
+
+ if not baddepsyntax:
+ ismasked = not ebuild_archs or \
+ pkg.cpv not in portdb.xmatch("match-visible", pkg.cp)
+ if ismasked:
+ if not have_pmasked:
+ have_pmasked = bool(dep_settings._getMaskAtom(
+ pkg.cpv, pkg._metadata))
+ if options.ignore_masked:
+ continue
+ # we are testing deps for a masked package; give it some lee-way
+ suffix = "masked"
+ matchmode = "minimum-all"
+ else:
+ suffix = ""
+ matchmode = "minimum-visible"
+
+ if not have_dev_keywords:
+ have_dev_keywords = \
+ bool(dev_keywords.intersection(keywords))
+
+ if prof.status == "dev":
+ suffix = suffix + "indev"
+
+ for mytype in Package._dep_keys:
+
+ mykey = "dependency.bad" + suffix
+ myvalue = myaux[mytype]
+ if not myvalue:
+ continue
+
+ success, atoms = portage.dep_check(myvalue, portdb,
+ dep_settings, use="all", mode=matchmode,
+ trees=trees)
+
+ if success:
+ if atoms:
+
+ # Don't bother with dependency.unknown for
+ # cases in which *DEPEND.bad is triggered.
+ for atom in atoms:
+ # dep_check returns all blockers and they
+ # aren't counted for *DEPEND.bad, so we
+ # ignore them here.
+ if not atom.blocker:
+ unknown_pkgs.discard(
+ (mytype, atom.unevaluated_atom))
+
+ if not prof.sub_path:
+ # old-style virtuals currently aren't
+ # resolvable with empty profile, since
+ # 'virtuals' mappings are unavailable
+ # (it would be expensive to search
+ # for PROVIDE in all ebuilds)
+ atoms = [atom for atom in atoms if not \
+ (atom.cp.startswith('virtual/') and \
+ not portdb.cp_list(atom.cp))]
+
+ # we have some unsolvable deps
+ # remove ! deps, which always show up as unsatisfiable
+ atoms = [str(atom.unevaluated_atom) \
+ for atom in atoms if not atom.blocker]
+
+ # if we emptied out our list, continue:
+ if not atoms:
+ continue
+ stats[mykey] += 1
+ fails[mykey].append("%s: %s: %s(%s) %s" % \
+ (relative_path, mytype, keyword,
prof, repr(atoms)))
+ else:
+ stats[mykey] += 1
+ fails[mykey].append("%s: %s: %s(%s) %s" % \
+ (relative_path, mytype, keyword,
+ prof, repr(atoms)))
if not baddepsyntax and unknown_pkgs:
type_map = {}
@@ -2208,11 +2400,11 @@ if options.if_modified == "y" and len(effective_scanlist) < 1:
if options.mode == "manifest":
sys.exit(dofail)
-#dofail will be set to 1 if we have failed in at least one non-warning category
-dofail=0
-#dowarn will be set to 1 if we tripped any warnings
-dowarn=0
-#dofull will be set if we should print a "repoman full" informational message
+# dofail will be set to 1 if we have failed in at least one non-warning category
+dofail = 0
+# dowarn will be set to 1 if we tripped any warnings
+dowarn = 0
+# dofull will be set if we should print a "repoman full" informational message
dofull = options.mode != 'full'
for x in qacats:
@@ -2240,29 +2432,20 @@ console_writer.style_listener = style_file.new_styles
f = formatter.AbstractFormatter(console_writer)
-utilities.format_qa_output(f, stats, fails, dofull, dofail, options, qawarnings)
+format_outputs = {
+ 'column': utilities.format_qa_output_column,
+ 'default': utilities.format_qa_output
+}
+
+format_output = format_outputs.get(options.output_style,
+ format_outputs['default'])
+format_output(f, stats, fails, dofull, dofail, options, qawarnings)
style_file.flush()
del console_writer, f, style_file
qa_output = qa_output.getvalue()
qa_output = qa_output.splitlines(True)
-def grouplist(mylist,seperator="/"):
- """(list,seperator="/") -- Takes a list of elements; groups them into
- same initial element categories. Returns a dict of {base:[sublist]}
- From: ["blah/foo","spork/spatula","blah/weee/splat"]
- To: {"blah":["foo","weee/splat"], "spork":["spatula"]}"""
- mygroups={}
- for x in mylist:
- xs=x.split(seperator)
- if xs[0]==".":
- xs=xs[1:]
- if xs[0] not in mygroups:
- mygroups[xs[0]]=[seperator.join(xs[1:])]
- else:
- mygroups[xs[0]]+=[seperator.join(xs[1:])]
- return mygroups
-
suggest_ignore_masked = False
suggest_include_dev = False
@@ -2311,65 +2494,65 @@ else:
myunadded = []
if vcs == "cvs":
try:
- myvcstree=portage.cvstree.getentries("./",recursive=1)
- myunadded=portage.cvstree.findunadded(myvcstree,recursive=1,basedir="./")
+ myvcstree = portage.cvstree.getentries("./", recursive=1)
+ myunadded = portage.cvstree.findunadded(myvcstree, recursive=1, basedir="./")
except SystemExit as e:
raise # TODO propagate this
except:
err("Error retrieving CVS tree; exiting.")
if vcs == "svn":
try:
- with os.popen("svn status --no-ignore") as f:
+ with repoman_popen("svn status --no-ignore") as f:
svnstatus = f.readlines()
- myunadded = [ "./"+elem.rstrip().split()[1] for elem in svnstatus if elem.startswith("?") or elem.startswith("I") ]
+ myunadded = ["./" + elem.rstrip().split()[1] for elem in svnstatus if elem.startswith("?") or elem.startswith("I")]
except SystemExit as e:
raise # TODO propagate this
except:
err("Error retrieving SVN info; exiting.")
if vcs == "git":
# get list of files not under version control or missing
- myf = os.popen("git ls-files --others")
- myunadded = [ "./" + elem[:-1] for elem in myf ]
+ myf = repoman_popen("git ls-files --others")
+ myunadded = ["./" + elem[:-1] for elem in myf]
myf.close()
if vcs == "bzr":
try:
- with os.popen("bzr status -S .") as f:
+ with repoman_popen("bzr status -S .") as f:
bzrstatus = f.readlines()
- myunadded = [ "./"+elem.rstrip().split()[1].split('/')[-1:][0] for elem in bzrstatus if elem.startswith("?") or elem[0:2] == " D" ]
+ myunadded = ["./" + elem.rstrip().split()[1].split('/')[-1:][0] for elem in bzrstatus if elem.startswith("?") or elem[0:2] == " D"]
except SystemExit as e:
raise # TODO propagate this
except:
err("Error retrieving bzr info; exiting.")
if vcs == "hg":
- with os.popen("hg status --no-status --unknown .") as f:
+ with repoman_popen("hg status --no-status --unknown .") as f:
myunadded = f.readlines()
myunadded = ["./" + elem.rstrip() for elem in myunadded]
-
+
# Mercurial doesn't handle manually deleted files as removed from
# the repository, so the user need to remove them before commit,
# using "hg remove [FILES]"
- with os.popen("hg status --no-status --deleted .") as f:
+ with repoman_popen("hg status --no-status --deleted .") as f:
mydeleted = f.readlines()
mydeleted = ["./" + elem.rstrip() for elem in mydeleted]
- myautoadd=[]
+ myautoadd = []
if myunadded:
- for x in range(len(myunadded)-1,-1,-1):
- xs=myunadded[x].split("/")
- if xs[-1]=="files":
+ for x in range(len(myunadded)-1, -1, -1):
+ xs = myunadded[x].split("/")
+ if xs[-1] == "files":
print("!!! files dir is not added! Please correct this.")
sys.exit(-1)
- elif xs[-1]=="Manifest":
+ elif xs[-1] == "Manifest":
# It's a manifest... auto add
- myautoadd+=[myunadded[x]]
+ myautoadd += [myunadded[x]]
del myunadded[x]
if myunadded:
print(red("!!! The following files are in your local tree but are not added to the master"))
print(red("!!! tree. Please remove them from the local tree or add them to the master tree."))
for x in myunadded:
- print(" ",x)
+ print(" ", x)
print()
print()
sys.exit(1)
@@ -2378,7 +2561,7 @@ else:
print(red("!!! The following files are removed manually from your local tree but are not"))
print(red("!!! removed from the repository. Please remove them, using \"hg remove [FILES]\"."))
for x in mydeleted:
- print(" ",x)
+ print(" ", x)
print()
print()
sys.exit(1)
@@ -2387,60 +2570,59 @@ else:
mycvstree = cvstree.getentries("./", recursive=1)
mychanged = cvstree.findchanged(mycvstree, recursive=1, basedir="./")
mynew = cvstree.findnew(mycvstree, recursive=1, basedir="./")
- myremoved=portage.cvstree.findremoved(mycvstree,recursive=1,basedir="./")
+ myremoved = portage.cvstree.findremoved(mycvstree, recursive=1, basedir="./")
bin_blob_pattern = re.compile("^-kb$")
no_expansion = set(portage.cvstree.findoption(mycvstree, bin_blob_pattern,
recursive=1, basedir="./"))
-
if vcs == "svn":
- with os.popen("svn status") as f:
+ with repoman_popen("svn status") as f:
svnstatus = f.readlines()
- mychanged = [ "./" + elem.split()[-1:][0] for elem in svnstatus if (elem[:1] in "MR" or elem[1:2] in "M")]
- mynew = [ "./" + elem.split()[-1:][0] for elem in svnstatus if elem.startswith("A")]
- myremoved = [ "./" + elem.split()[-1:][0] for elem in svnstatus if elem.startswith("D")]
+ mychanged = ["./" + elem.split()[-1:][0] for elem in svnstatus if (elem[:1] in "MR" or elem[1:2] in "M")]
+ mynew = ["./" + elem.split()[-1:][0] for elem in svnstatus if elem.startswith("A")]
+ myremoved = ["./" + elem.split()[-1:][0] for elem in svnstatus if elem.startswith("D")]
# Subversion expands keywords specified in svn:keywords properties.
- with os.popen("svn propget -R svn:keywords") as f:
+ with repoman_popen("svn propget -R svn:keywords") as f:
props = f.readlines()
expansion = dict(("./" + prop.split(" - ")[0], prop.split(" - ")[1].split()) \
for prop in props if " - " in prop)
elif vcs == "git":
- with os.popen("git diff-index --name-only "
+ with repoman_popen("git diff-index --name-only "
"--relative --diff-filter=M HEAD") as f:
mychanged = f.readlines()
mychanged = ["./" + elem[:-1] for elem in mychanged]
- with os.popen("git diff-index --name-only "
+ with repoman_popen("git diff-index --name-only "
"--relative --diff-filter=A HEAD") as f:
mynew = f.readlines()
mynew = ["./" + elem[:-1] for elem in mynew]
- with os.popen("git diff-index --name-only "
+ with repoman_popen("git diff-index --name-only "
"--relative --diff-filter=D HEAD") as f:
myremoved = f.readlines()
myremoved = ["./" + elem[:-1] for elem in myremoved]
if vcs == "bzr":
- with os.popen("bzr status -S .") as f:
+ with repoman_popen("bzr status -S .") as f:
bzrstatus = f.readlines()
- mychanged = [ "./" + elem.split()[-1:][0].split('/')[-1:][0] for elem in bzrstatus if elem and elem[1:2] == "M" ]
- mynew = [ "./" + elem.split()[-1:][0].split('/')[-1:][0] for elem in bzrstatus if elem and ( elem[1:2] in "NK" or elem[0:1] == "R" ) ]
- myremoved = [ "./" + elem.split()[-1:][0].split('/')[-1:][0] for elem in bzrstatus if elem.startswith("-") ]
- myremoved = [ "./" + elem.split()[-3:-2][0].split('/')[-1:][0] for elem in bzrstatus if elem and ( elem[1:2] == "K" or elem[0:1] == "R" ) ]
+ mychanged = ["./" + elem.split()[-1:][0].split('/')[-1:][0] for elem in bzrstatus if elem and elem[1:2] == "M"]
+ mynew = ["./" + elem.split()[-1:][0].split('/')[-1:][0] for elem in bzrstatus if elem and (elem[1:2] in "NK" or elem[0:1] == "R")]
+ myremoved = ["./" + elem.split()[-1:][0].split('/')[-1:][0] for elem in bzrstatus if elem.startswith("-")]
+ myremoved = ["./" + elem.split()[-3:-2][0].split('/')[-1:][0] for elem in bzrstatus if elem and (elem[1:2] == "K" or elem[0:1] == "R")]
# Bazaar expands nothing.
if vcs == "hg":
- with os.popen("hg status --no-status --modified .") as f:
+ with repoman_popen("hg status --no-status --modified .") as f:
mychanged = f.readlines()
mychanged = ["./" + elem.rstrip() for elem in mychanged]
- with os.popen("hg status --no-status --added .") as f:
+ with repoman_popen("hg status --no-status --added .") as f:
mynew = f.readlines()
mynew = ["./" + elem.rstrip() for elem in mynew]
- with os.popen("hg status --no-status --removed .") as f:
+ with repoman_popen("hg status --no-status --removed .") as f:
myremoved = f.readlines()
myremoved = ["./" + elem.rstrip() for elem in myremoved]
@@ -2499,21 +2681,54 @@ else:
commitmessage = commitmessage.rstrip()
changelog_msg = commitmessage
portage_version = getattr(portage, "VERSION", None)
+ gpg_key = repoman_settings.get("PORTAGE_GPG_KEY", "")
+ dco_sob = repoman_settings.get("DCO_SIGNED_OFF_BY", "")
if portage_version is None:
sys.stderr.write("Failed to insert portage version in message!\n")
sys.stderr.flush()
portage_version = "Unknown"
- unameout = platform.system() + " "
- if platform.system() in ["Darwin", "SunOS"]:
- unameout += platform.processor()
- else:
- unameout += platform.machine()
- commitmessage += "\n\n(Portage version: %s/%s/%s" % \
- (portage_version, vcs, unameout)
+
+ report_options = []
if options.force:
- commitmessage += ", RepoMan options: --force"
- commitmessage += ")"
+ report_options.append("--force")
+ if options.ignore_arches:
+ report_options.append("--ignore-arches")
+ if include_arches is not None:
+ report_options.append("--include-arches=\"%s\"" %
+ " ".join(sorted(include_arches)))
+
+ if vcs == "git":
+ # Use new footer only for git (see bug #438364).
+ commit_footer = "\n\nPackage-Manager: portage-%s" % portage_version
+ if report_options:
+ commit_footer += "\nRepoMan-Options: " + " ".join(report_options)
+ if sign_manifests:
+ commit_footer += "\nManifest-Sign-Key: %s" % (gpg_key, )
+ if dco_sob:
+ commit_footer += "\nSigned-off-by: %s" % (dco_sob, )
+ else:
+ unameout = platform.system() + " "
+ if platform.system() in ["Darwin", "SunOS"]:
+ unameout += platform.processor()
+ else:
+ unameout += platform.machine()
+ commit_footer = "\n\n"
+ if dco_sob:
+ commit_footer += "Signed-off-by: %s\n" % (dco_sob, )
+ commit_footer += "(Portage version: %s/%s/%s" % \
+ (portage_version, vcs, unameout)
+ if report_options:
+ commit_footer += ", RepoMan options: " + " ".join(report_options)
+ if sign_manifests:
+ commit_footer += ", signed Manifest commit with key %s" % \
+ (gpg_key, )
+ else:
+ commit_footer += ", unsigned Manifest commit"
+ commit_footer += ")"
+
+ commitmessage += commit_footer
+ broken_changelog_manifests = []
if options.echangelog in ('y', 'force'):
logging.info("checking for unmodified ChangeLog files")
committer_name = utilities.get_committer_name(env=repoman_settings)
@@ -2569,6 +2784,8 @@ else:
# regenerate Manifest for modified ChangeLog (bug #420735)
repoman_settings["O"] = checkdir
digestgen(mysettings=repoman_settings, myportdb=portdb)
+ else:
+ broken_changelog_manifests.append(x)
if myautoadd:
print(">>> Auto-Adding missing Manifest/ChangeLog file(s)...")
@@ -2578,15 +2795,17 @@ else:
portage.writemsg_stdout("(%s)\n" % " ".join(add_cmd),
noiselevel=-1)
else:
- if not (sys.hexversion >= 0x3000000 and sys.hexversion < 0x3020000):
- # Python 3.1 produces the following TypeError if raw bytes are
- # passed to subprocess.call():
- # File "/usr/lib/python3.1/subprocess.py", line 646, in __init__
- # errread, errwrite)
- # File "/usr/lib/python3.1/subprocess.py", line 1157, in _execute_child
- # raise child_exception
- # TypeError: expected an object with the buffer interface
- add_cmd = [_unicode_encode(arg) for arg in add_cmd]
+
+ if sys.hexversion < 0x3020000 and sys.hexversion >= 0x3000000 and \
+ not os.path.isabs(add_cmd[0]):
+ # Python 3.1 _execvp throws TypeError for non-absolute executable
+ # path passed as bytes (see http://bugs.python.org/issue8513).
+ fullname = find_binary(add_cmd[0])
+ if fullname is None:
+ raise portage.exception.CommandNotFound(add_cmd[0])
+ add_cmd[0] = fullname
+
+ add_cmd = [_unicode_encode(arg) for arg in add_cmd]
retcode = subprocess.call(add_cmd)
if retcode != os.EX_OK:
logging.error(
@@ -2631,7 +2850,7 @@ else:
elif vcs == "svn":
if myfile not in expansion:
continue
-
+
# Subversion keywords are case-insensitive in svn:keywords properties, but case-sensitive in contents of files.
enabled_keywords = []
for k in expansion[myfile]:
@@ -2641,7 +2860,8 @@ else:
headerstring = "'\$(%s).*\$'" % "|".join(enabled_keywords)
- myout = subprocess_getstatusoutput("egrep -q "+headerstring+" "+myfile)
+ myout = repoman_getstatusoutput("egrep -q " + headerstring + " " +
+ portage._shell_quote(myfile))
if myout[0] == 0:
myheaders.append(myfile)
@@ -2688,7 +2908,7 @@ else:
if options.pretend:
print("(%s)" % (" ".join(commit_cmd),))
else:
- retval = spawn(commit_cmd, env=os.environ)
+ retval = spawn(commit_cmd, env=commit_env)
if retval != os.EX_OK:
writemsg_level(("!!! Exiting on %s (shell) " + \
"error code: %s\n") % (vcs, retval),
@@ -2729,14 +2949,38 @@ else:
gpgvars[k] = v
gpgcmd = portage.util.varexpand(gpgcmd, mydict=gpgvars)
if options.pretend:
- print("("+gpgcmd+")")
+ print("(" + gpgcmd + ")")
else:
- rValue = os.system(gpgcmd)
+ # Encode unicode manually for bug #310789.
+ gpgcmd = portage.util.shlex_split(gpgcmd)
+
+ if sys.hexversion < 0x3020000 and sys.hexversion >= 0x3000000 and \
+ not os.path.isabs(gpgcmd[0]):
+ # Python 3.1 _execvp throws TypeError for non-absolute executable
+ # path passed as bytes (see http://bugs.python.org/issue8513).
+ fullname = find_binary(gpgcmd[0])
+ if fullname is None:
+ raise portage.exception.CommandNotFound(gpgcmd[0])
+ gpgcmd[0] = fullname
+
+ gpgcmd = [_unicode_encode(arg,
+ encoding=_encodings['fs'], errors='strict') for arg in gpgcmd]
+ rValue = subprocess.call(gpgcmd)
if rValue == os.EX_OK:
- os.rename(filename+".asc", filename)
+ os.rename(filename + ".asc", filename)
else:
raise portage.exception.PortageException("!!! gpg exited with '" + str(rValue) + "' status")
+ def need_signature(filename):
+ try:
+ with open(_unicode_encode(filename,
+ encoding=_encodings['fs'], errors='strict'), 'rb') as f:
+ return b"BEGIN PGP SIGNED MESSAGE" not in f.readline()
+ except IOError as e:
+ if e.errno in (errno.ENOENT, errno.ESTALE):
+ return False
+ raise
+
# When files are removed and re-added, the cvs server will put /Attic/
# inside the $Header path. This code detects the problem and corrects it
# so that the Manifest will generate correctly. See bug #169500.
@@ -2771,6 +3015,11 @@ else:
repoman_settings["O"] = os.path.join(repodir, x)
digestgen(mysettings=repoman_settings, myportdb=portdb)
+ elif broken_changelog_manifests:
+ for x in broken_changelog_manifests:
+ repoman_settings["O"] = os.path.join(repodir, x)
+ digestgen(mysettings=repoman_settings, myportdb=portdb)
+
signed = False
if sign_manifests:
signed = True
@@ -2779,7 +3028,7 @@ else:
chain(myupdates, myremoved, mymanifests))):
repoman_settings["O"] = os.path.join(repodir, x)
manifest_path = os.path.join(repoman_settings["O"], "Manifest")
- if not os.path.exists(manifest_path):
+ if not need_signature(manifest_path):
continue
gpgsign(manifest_path)
except portage.exception.PortageException as e:
@@ -2809,7 +3058,6 @@ else:
sys.exit(retval)
if True:
-
myfiles = mymanifests[:]
# If there are no header (SVN/CVS keywords) changes in
# the files, this Manifest commit must include the
@@ -2821,14 +3069,7 @@ else:
fd, commitmessagefile = tempfile.mkstemp(".repoman.msg")
mymsg = os.fdopen(fd, "wb")
- # strip the closing parenthesis
- mymsg.write(_unicode_encode(commitmessage[:-1]))
- if signed:
- mymsg.write(_unicode_encode(
- ", signed Manifest commit with key %s)" % \
- repoman_settings["PORTAGE_GPG_KEY"]))
- else:
- mymsg.write(b", unsigned Manifest commit)")
+ mymsg.write(_unicode_encode(commitmessage))
mymsg.close()
commit_cmd = []
@@ -2851,9 +3092,8 @@ else:
if options.pretend:
print("(%s)" % (" ".join(commit_cmd),))
else:
- retval = spawn(commit_cmd, env=os.environ)
+ retval = spawn(commit_cmd, env=commit_env)
if retval != os.EX_OK:
-
if repo_config.sign_commit and vcs == 'git' and \
not git_supports_gpg_sign():
# Inform user that newer git is needed (bug #403323).
@@ -2877,4 +3117,3 @@ else:
print("repoman was too scared by not seeing any familiar version control file that he forgot to commit anything")
print(green("RepoMan sez:"), "\"If everyone were like you, I'd be out of business!\"\n")
sys.exit(0)
-
diff --git a/bin/save-ebuild-env.sh b/bin/save-ebuild-env.sh
index 47a2acae5..98cff839e 100644
--- a/bin/save-ebuild-env.sh
+++ b/bin/save-ebuild-env.sh
@@ -1,8 +1,8 @@
#!/bin/bash
-# Copyright 1999-2011 Gentoo Foundation
+# Copyright 1999-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-# @FUNCTION: save_ebuild_env
+# @FUNCTION: __save_ebuild_env
# @DESCRIPTION:
# echo the current environment to stdout, filtering out redundant info.
#
@@ -10,11 +10,12 @@
# be excluded from the output. These function are not needed for installation
# or removal of the packages, and can therefore be safely excluded.
#
-save_ebuild_env() {
+__save_ebuild_env() {
(
if has --exclude-init-phases $* ; then
unset S _E_DOCDESTTREE_ _E_EXEDESTTREE_ \
- PORTAGE_DOCOMPRESS PORTAGE_DOCOMPRESS_SKIP
+ PORTAGE_DOCOMPRESS_SIZE_LIMIT PORTAGE_DOCOMPRESS \
+ PORTAGE_DOCOMPRESS_SKIP
if [[ -n $PYTHONPATH &&
${PYTHONPATH%%:*} -ef $PORTAGE_PYM_PATH ]] ; then
if [[ $PYTHONPATH == *:* ]] ; then
@@ -42,35 +43,51 @@ save_ebuild_env() {
for x in pkg_setup pkg_nofetch src_unpack src_prepare src_configure \
src_compile src_test src_install pkg_preinst pkg_postinst \
pkg_prerm pkg_postrm ; do
- unset -f default_$x _eapi{0,1,2,3,4}_$x
+ unset -f default_$x __eapi{0,1,2,3,4}_$x
done
unset x
- unset -f assert assert_sigpipe_ok dump_trace die diefunc \
- quiet_mode vecho elog_base eqawarn elog \
- esyslog einfo einfon ewarn eerror ebegin _eend eend KV_major \
- KV_minor KV_micro KV_to_int get_KV unset_colors set_colors has \
- has_phase_defined_up_to \
- hasv hasq qa_source qa_call \
- addread addwrite adddeny addpredict _sb_append_var \
+ unset -f assert __assert_sigpipe_ok \
+ __dump_trace die \
+ __quiet_mode __vecho __elog_base eqawarn elog \
+ einfo einfon ewarn eerror ebegin __eend eend KV_major \
+ KV_minor KV_micro KV_to_int get_KV __1 __1 has \
+ __has_phase_defined_up_to \
+ hasv hasq __qa_source __qa_call \
+ addread addwrite adddeny addpredict __sb_append_var \
use usev useq has_version portageq \
best_version use_with use_enable register_die_hook \
- keepdir unpack strip_duplicate_slashes econf einstall \
- dyn_setup dyn_unpack dyn_clean into insinto exeinto docinto \
+ unpack __strip_duplicate_slashes econf einstall \
+ __dyn_setup __dyn_unpack __dyn_clean \
+ into insinto exeinto docinto \
insopts diropts exeopts libopts docompress \
- abort_handler abort_prepare abort_configure abort_compile \
- abort_test abort_install dyn_prepare dyn_configure \
- dyn_compile dyn_test dyn_install \
- dyn_preinst dyn_pretend dyn_help debug-print debug-print-function \
- debug-print-section helpers_die inherit EXPORT_FUNCTIONS \
- nonfatal register_success_hook remove_path_entry \
- save_ebuild_env filter_readonly_variables preprocess_ebuild_env \
- set_unless_changed unset_unless_changed source_all_bashrcs \
- ebuild_main ebuild_phase ebuild_phase_with_hooks \
- _ebuild_arg_to_phase _ebuild_phase_funcs default \
- _hasg _hasgq _unpack_tar \
+ __abort_handler __abort_prepare __abort_configure __abort_compile \
+ __abort_test __abort_install __dyn_prepare __dyn_configure \
+ __dyn_compile __dyn_test __dyn_install \
+ __dyn_pretend __dyn_help \
+ debug-print debug-print-function \
+ debug-print-section __helpers_die inherit EXPORT_FUNCTIONS \
+ nonfatal register_success_hook \
+ __hasg __hasgq \
+ __save_ebuild_env __set_colors __filter_readonly_variables \
+ __preprocess_ebuild_env \
+ __repo_attr __source_all_bashrcs \
+ __ebuild_main __ebuild_phase __ebuild_phase_with_hooks \
+ __ebuild_arg_to_phase __ebuild_phase_funcs default \
+ __unpack_tar __unset_colors \
${QA_INTERCEPTORS}
+ ___eapi_has_usex && unset -f usex
+ ___eapi_has_master_repositories && unset -f master_repositories
+ ___eapi_has_repository_path && unset -f repository_path
+ ___eapi_has_available_eclasses && unset -f available_eclasses
+ ___eapi_has_eclass_path && unset -f eclass_path
+ ___eapi_has_license_path && unset -f license_path
+ ___eapi_has_package_manager_build_user && unset -f package_manager_build_user
+ ___eapi_has_package_manager_build_group && unset -f package_manager_build_group
+
+ unset -f $(compgen -A function ___eapi_)
+
# portage config variables and variables set directly by portage
unset ACCEPT_LICENSE BAD BRACKET BUILD_PREFIX COLS \
DISTCC_DIR DISTDIR DOC_SYMLINKS_DIR \
diff --git a/bin/xattr-helper.py b/bin/xattr-helper.py
new file mode 100755
index 000000000..ea83a5e7c
--- /dev/null
+++ b/bin/xattr-helper.py
@@ -0,0 +1,190 @@
+#!/usr/bin/python -b
+# Copyright 2012-2014 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+"""Dump and restore extended attributes.
+
+We use formats like that used by getfattr --dump. This is meant for shell
+helpers to save/restore. If you're looking for a python/portage API, see
+portage.util.movefile._copyxattr instead.
+
+https://en.wikipedia.org/wiki/Extended_file_attributes
+"""
+
+import array
+import os
+import re
+import sys
+
+from portage.util._argparse import ArgumentParser
+
+if hasattr(os, "getxattr"):
+
+ class xattr(object):
+ get = os.getxattr
+ set = os.setxattr
+ list = os.listxattr
+
+else:
+ import xattr
+
+
+_UNQUOTE_RE = re.compile(br'\\[0-7]{3}')
+_FS_ENCODING = sys.getfilesystemencoding()
+
+
+if sys.hexversion < 0x3000000:
+
+ def octal_quote_byte(b):
+ return b'\\%03o' % ord(b)
+
+ def unicode_encode(s):
+ if isinstance(s, unicode):
+ s = s.encode(_FS_ENCODING)
+ return s
+else:
+
+ def octal_quote_byte(b):
+ return ('\\%03o' % ord(b)).encode('ascii')
+
+ def unicode_encode(s):
+ if isinstance(s, str):
+ s = s.encode(_FS_ENCODING)
+ return s
+
+
+def quote(s, quote_chars):
+ """Convert all |quote_chars| in |s| to escape sequences
+
+ This is normally used to escape any embedded quotation marks.
+ """
+ quote_re = re.compile(b'[' + quote_chars + b']')
+ result = []
+ pos = 0
+ s_len = len(s)
+
+ while pos < s_len:
+ m = quote_re.search(s, pos=pos)
+ if m is None:
+ result.append(s[pos:])
+ pos = s_len
+ else:
+ start = m.start()
+ result.append(s[pos:start])
+ result.append(octal_quote_byte(s[start:start+1]))
+ pos = start + 1
+
+ return b''.join(result)
+
+
+def unquote(s):
+ """Process all escape sequences in |s|"""
+ result = []
+ pos = 0
+ s_len = len(s)
+
+ while pos < s_len:
+ m = _UNQUOTE_RE.search(s, pos=pos)
+ if m is None:
+ result.append(s[pos:])
+ pos = s_len
+ else:
+ start = m.start()
+ result.append(s[pos:start])
+ pos = start + 4
+ a = array.array('B')
+ a.append(int(s[start + 1:pos], 8))
+ try:
+ # Python >= 3.2
+ result.append(a.tobytes())
+ except AttributeError:
+ result.append(a.tostring())
+
+ return b''.join(result)
+
+
+def dump_xattrs(pathnames, file_out):
+ """Dump the xattr data for |pathnames| to |file_out|"""
+ # NOTE: Always quote backslashes, in order to ensure that they are
+ # not interpreted as quotes when they are processed by unquote.
+ quote_chars = b'\n\r\\\\'
+
+ for pathname in pathnames:
+ attrs = xattr.list(pathname)
+ if not attrs:
+ continue
+
+ file_out.write(b'# file: %s\n' % quote(pathname, quote_chars))
+ for attr in attrs:
+ attr = unicode_encode(attr)
+ value = xattr.get(pathname, attr)
+ file_out.write(b'%s="%s"\n' % (
+ quote(attr, b'=' + quote_chars),
+ quote(value, b'\0"' + quote_chars)))
+
+
+def restore_xattrs(file_in):
+ """Read |file_in| and restore xattrs content from it
+
+ This expects textual data in the format written by dump_xattrs.
+ """
+ pathname = None
+ for i, line in enumerate(file_in):
+ if line.startswith(b'# file: '):
+ pathname = unquote(line.rstrip(b'\n')[8:])
+ else:
+ parts = line.split(b'=', 1)
+ if len(parts) == 2:
+ if pathname is None:
+ raise ValueError('line %d: missing pathname' % (i + 1,))
+ attr = unquote(parts[0])
+ # strip trailing newline and quotes
+ value = unquote(parts[1].rstrip(b'\n')[1:-1])
+ xattr.set(pathname, attr, value)
+ elif line.strip():
+ raise ValueError('line %d: malformed entry' % (i + 1,))
+
+
+def main(argv):
+
+ parser = ArgumentParser(description=__doc__)
+ parser.add_argument('paths', nargs='*', default=[])
+
+ actions = parser.add_argument_group('Actions')
+ actions.add_argument('--dump',
+ action='store_true',
+ help='Dump the values of all extended '
+ 'attributes associated with null-separated'
+ ' paths read from stdin.')
+ actions.add_argument('--restore',
+ action='store_true',
+ help='Restore extended attributes using'
+ ' a dump read from stdin.')
+
+ options = parser.parse_args(argv)
+
+ if sys.hexversion >= 0x3000000:
+ file_in = sys.stdin.buffer.raw
+ else:
+ file_in = sys.stdin
+ if not options.paths:
+ options.paths += [x for x in file_in.read().split(b'\0') if x]
+
+ if options.dump:
+ if sys.hexversion >= 0x3000000:
+ file_out = sys.stdout.buffer
+ else:
+ file_out = sys.stdout
+ dump_xattrs(options.paths, file_out)
+
+ elif options.restore:
+ restore_xattrs(file_in)
+
+ else:
+ parser.error('missing action!')
+
+ return os.EX_OK
+
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv[1:]))
diff --git a/bin/xpak-helper.py b/bin/xpak-helper.py
index ef74920db..c4391cde7 100755
--- a/bin/xpak-helper.py
+++ b/bin/xpak-helper.py
@@ -1,11 +1,12 @@
-#!/usr/bin/python
-# Copyright 2009-2011 Gentoo Foundation
+#!/usr/bin/python -b
+# Copyright 2009-2014 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
-import optparse
import sys
import portage
+portage._internal_caller = True
from portage import os
+from portage.util._argparse import ArgumentParser
def command_recompose(args):
@@ -45,8 +46,8 @@ def main(argv):
usage = "usage: %s COMMAND [args]" % \
os.path.basename(argv[0])
- parser = optparse.OptionParser(description=description, usage=usage)
- options, args = parser.parse_args(argv[1:])
+ parser = ArgumentParser(description=description, usage=usage)
+ options, args = parser.parse_known_args(argv[1:])
if not args:
parser.error("missing command argument")
diff --git a/cnf/dispatch-conf.conf b/cnf/dispatch-conf.conf
index 7eea44c8e..125b7cc1f 100644
--- a/cnf/dispatch-conf.conf
+++ b/cnf/dispatch-conf.conf
@@ -6,6 +6,7 @@
archive-dir=${EPREFIX}/etc/config-archive
# Use rcs for storing files in the archive directory?
+# NOTE: You should install dev-vcs/rcs before enabling this option.
# WARNING: When configured to use rcs, read and execute permissions of
# archived files may be inherited from the first check in of a working
# file, as documented in the ci(1) man page. This means that even if
diff --git a/cnf/make.conf b/cnf/make.conf.example
index ad2a5b775..6603b42c8 100644
--- a/cnf/make.conf
+++ b/cnf/make.conf.example
@@ -1,4 +1,4 @@
-# Copyright 1999-2011 Gentoo Foundation
+# Copyright 1999-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# Contains local system settings for Portage system
@@ -78,6 +78,18 @@
#
#ACCEPT_KEYWORDS="~arch"
+# ACCEPT_LICENSE is used to mask packages based on licensing restrictions.
+# It may contain both license and group names, where group names are
+# prefixed with the '@' symbol. License groups are defined in the
+# license_groups file (see portage(5) man page). In addition to license
+# and group names, the * and -* wildcard tokens are also supported.
+#
+# Accept any license except those in the EULA license group (default).
+#ACCEPT_LICENSE="* -@EULA"
+#
+# Only accept licenses in the FREE license group (i.e. Free Software).
+#ACCEPT_LICENSE="-* @FREE"
+
# Portage Directories
# ===================
#
@@ -92,7 +104,7 @@
#
# PORTDIR is the location of the portage tree. This is the repository
# for all profile information as well as all ebuilds. If you change
-# this, you must update your /etc/make.profile symlink accordingly.
+# this, you must update your /etc/portage/make.profile symlink accordingly.
# ***Warning***
# Data stored inside PORTDIR is in peril of being overwritten or deleted by
# the emerge --sync command. The default value of PORTAGE_RSYNC_OPTS
@@ -289,8 +301,7 @@
# logging related variables:
# PORTAGE_ELOG_CLASSES: selects messages to be logged, possible values are:
# info, warn, error, log, qa, *
-# Warning: commenting this will disable elog
-PORTAGE_ELOG_CLASSES="log warn error"
+#PORTAGE_ELOG_CLASSES="log warn error"
# PORTAGE_ELOG_SYSTEM: selects the module(s) to process the log messages. Modules
# included in portage are (empty means logging is disabled):
@@ -312,7 +323,7 @@ PORTAGE_ELOG_CLASSES="log warn error"
# separated list of loglevels to override PORTAGE_ELOG_CLASSES
# for this module (e.g.
# PORTAGE_ELOG_SYSTEM="mail:warn,error syslog:* save")
-#PORTAGE_ELOG_SYSTEM="save_summary echo"
+#PORTAGE_ELOG_SYSTEM="save_summary:log,warn,error,qa echo"
# PORTAGE_ELOG_COMMAND: only used with the "custom" logging module. Specifies a command
# to process log messages. Two variables are expanded:
diff --git a/cnf/make.conf.alpha.diff b/cnf/make.conf.example.alpha.diff
index f0a4e3852..5306999d0 100644
--- a/cnf/make.conf.alpha.diff
+++ b/cnf/make.conf.example.alpha.diff
@@ -1,6 +1,6 @@
---- make.conf 2006-03-19 18:40:11.000000000 +0100
-+++ make.conf.alpha 2006-03-19 18:26:21.000000000 +0100
-@@ -23,6 +23,17 @@
+--- make.conf.example
++++ make.conf.example
+@@ -22,6 +22,17 @@
# Example:
#USE="X gtk gnome -alsa"
@@ -18,9 +18,9 @@
# Host and optimization settings
# ==============================
#
-@@ -33,10 +44,18 @@
- # package (and in some cases the libraries it uses) at default optimizations
- # before reporting errors to developers.
+@@ -39,10 +50,18 @@
+ # -frecord-gcc-switches, since otherwise the check could result in false
+ # positive results.
#
-# Please refer to the GCC manual for a list of possible values.
+# -mcpu=<cpu-type> means optimize code for the particular type of CPU. In
@@ -39,12 +39,12 @@
# If you set a CFLAGS above, then this line will set your default C++ flags to
# the same settings.
#CXXFLAGS="${CFLAGS}"
-@@ -61,7 +80,7 @@
+@@ -76,7 +95,7 @@
# DO NOT PUT ANYTHING BUT YOUR SPECIFIC ~ARCHITECTURE IN THE LIST.
# IF YOU ARE UNSURE OF YOUR ARCH, OR THE IMPLICATIONS, DO NOT MODIFY THIS.
#
-#ACCEPT_KEYWORDS="~arch"
+#ACCEPT_KEYWORDS="~alpha"
- # Portage Directories
- # ===================
+ # ACCEPT_LICENSE is used to mask packages based on licensing restrictions.
+ # It may contain both license and group names, where group names are
diff --git a/cnf/make.conf.amd64-fbsd.diff b/cnf/make.conf.example.amd64-fbsd.diff
index aa07d0657..1277b6dba 100644
--- a/cnf/make.conf.amd64-fbsd.diff
+++ b/cnf/make.conf.example.amd64-fbsd.diff
@@ -1,6 +1,6 @@
---- make.conf 2006-03-19 18:40:11.000000000 +0100
-+++ make.conf.amd64-fbsd 2006-03-19 18:26:21.000000000 +0100
-@@ -23,6 +23,11 @@
+--- make.conf.example
++++ make.conf.example
+@@ -22,6 +22,11 @@
# Example:
#USE="X gtk gnome -alsa"
@@ -12,9 +12,9 @@
# Host and optimization settings
# ==============================
#
-@@ -33,10 +38,35 @@
- # package (and in some cases the libraries it uses) at default optimizations
- # before reporting errors to developers.
+@@ -39,10 +44,35 @@
+ # -frecord-gcc-switches, since otherwise the check could result in false
+ # positive results.
#
-# Please refer to the GCC manual for a list of possible values.
+# -mcpu=<cpu-type> means optimize code for the particular type of CPU without
@@ -50,12 +50,12 @@
# If you set a CFLAGS above, then this line will set your default C++ flags to
# the same settings.
#CXXFLAGS="${CFLAGS}"
-@@ -61,7 +91,7 @@
+@@ -76,7 +106,7 @@
# DO NOT PUT ANYTHING BUT YOUR SPECIFIC ~ARCHITECTURE IN THE LIST.
# IF YOU ARE UNSURE OF YOUR ARCH, OR THE IMPLICATIONS, DO NOT MODIFY THIS.
#
-#ACCEPT_KEYWORDS="~arch"
+#ACCEPT_KEYWORDS="~amd64-fbsd"
- # Portage Directories
- # ===================
+ # ACCEPT_LICENSE is used to mask packages based on licensing restrictions.
+ # It may contain both license and group names, where group names are
diff --git a/cnf/make.conf.amd64.diff b/cnf/make.conf.example.amd64.diff
index b4a93fe2a..dfa4b426f 100644
--- a/cnf/make.conf.amd64.diff
+++ b/cnf/make.conf.example.amd64.diff
@@ -1,6 +1,6 @@
---- make.conf 2006-03-19 18:40:11.000000000 +0100
-+++ make.conf.amd64 2006-03-19 18:26:21.000000000 +0100
-@@ -23,6 +23,11 @@
+--- make.conf.example
++++ make.conf.example
+@@ -22,6 +22,11 @@
# Example:
#USE="X gtk gnome -alsa"
@@ -12,9 +12,9 @@
# Host and optimization settings
# ==============================
#
-@@ -33,10 +38,35 @@
- # package (and in some cases the libraries it uses) at default optimizations
- # before reporting errors to developers.
+@@ -39,10 +44,35 @@
+ # -frecord-gcc-switches, since otherwise the check could result in false
+ # positive results.
#
-# Please refer to the GCC manual for a list of possible values.
+# -mcpu=<cpu-type> means optimize code for the particular type of CPU without
@@ -50,12 +50,12 @@
# If you set a CFLAGS above, then this line will set your default C++ flags to
# the same settings.
#CXXFLAGS="${CFLAGS}"
-@@ -61,7 +91,7 @@
+@@ -76,7 +106,7 @@
# DO NOT PUT ANYTHING BUT YOUR SPECIFIC ~ARCHITECTURE IN THE LIST.
# IF YOU ARE UNSURE OF YOUR ARCH, OR THE IMPLICATIONS, DO NOT MODIFY THIS.
#
-#ACCEPT_KEYWORDS="~arch"
+#ACCEPT_KEYWORDS="~amd64"
- # Portage Directories
- # ===================
+ # ACCEPT_LICENSE is used to mask packages based on licensing restrictions.
+ # It may contain both license and group names, where group names are
diff --git a/cnf/make.conf.arm.diff b/cnf/make.conf.example.arm.diff
index e6924ad50..bb9356339 100644
--- a/cnf/make.conf.arm.diff
+++ b/cnf/make.conf.example.arm.diff
@@ -1,6 +1,6 @@
---- make.conf 2006-03-19 18:40:11.000000000 +0100
-+++ make.conf.arm 2006-03-19 18:26:21.000000000 +0100
-@@ -23,6 +23,19 @@
+--- make.conf.example
++++ make.conf.example
+@@ -22,6 +22,19 @@
# Example:
#USE="X gtk gnome -alsa"
@@ -20,9 +20,9 @@
# Host and optimization settings
# ==============================
#
-@@ -33,10 +46,22 @@
- # package (and in some cases the libraries it uses) at default optimizations
- # before reporting errors to developers.
+@@ -39,10 +52,22 @@
+ # -frecord-gcc-switches, since otherwise the check could result in false
+ # positive results.
#
-# Please refer to the GCC manual for a list of possible values.
-#
diff --git a/cnf/make.conf.hppa.diff b/cnf/make.conf.example.hppa.diff
index a1fa5ef7b..2d17b3794 100644
--- a/cnf/make.conf.hppa.diff
+++ b/cnf/make.conf.example.hppa.diff
@@ -1,6 +1,6 @@
---- make.conf 2006-03-19 18:40:11.000000000 +0100
-+++ make.conf.hppa 2006-03-24 18:36:24.000000000 +0100
-@@ -23,6 +23,18 @@
+--- make.conf.example
++++ make.conf.example
+@@ -22,6 +22,18 @@
# Example:
#USE="X gtk gnome -alsa"
@@ -19,9 +19,9 @@
# Host and optimization settings
# ==============================
#
-@@ -33,14 +45,38 @@
- # package (and in some cases the libraries it uses) at default optimizations
- # before reporting errors to developers.
+@@ -39,14 +51,38 @@
+ # -frecord-gcc-switches, since otherwise the check could result in false
+ # positive results.
#
-# Please refer to the GCC manual for a list of possible values.
+# -march=<cpu-type> means to take full advantage of the ABI and instructions
@@ -35,10 +35,9 @@
+#
+# Architectures types supported in gcc-3.2 and higher: 1.0, 1.1 and 2.0
+# Note that 64bit userspace is not yet implemented.
- #
--#CFLAGS="-O2 -pipe"
++#
+# Decent examples:
- #
++#
+#
+# Use this one if you have a hppa1.1
+#CFLAGS="-march=1.1 -O2 -pipe -mschedule=7100LC"
@@ -47,8 +46,9 @@
+# Note that -march=2.0 was unstable on some stations.
+# -march=1.0 will create problems too.
+#CFLAGS="-O2 -pipe -mschedule=8000"
-+#
-+#
+ #
+-#CFLAGS="-O2 -pipe"
+ #
# If you set a CFLAGS above, then this line will set your default C++ flags to
# the same settings.
#CXXFLAGS="${CFLAGS}"
@@ -60,12 +60,12 @@
# If you set a CFLAGS above, then this line will set your default FORTRAN 77
# flags to the same settings.
#FFLAGS="${CFLAGS}"
-@@ -61,7 +97,7 @@
+@@ -76,7 +112,7 @@
# DO NOT PUT ANYTHING BUT YOUR SPECIFIC ~ARCHITECTURE IN THE LIST.
# IF YOU ARE UNSURE OF YOUR ARCH, OR THE IMPLICATIONS, DO NOT MODIFY THIS.
#
-#ACCEPT_KEYWORDS="~arch"
+#ACCEPT_KEYWORDS="~hppa"
- # Portage Directories
- # ===================
+ # ACCEPT_LICENSE is used to mask packages based on licensing restrictions.
+ # It may contain both license and group names, where group names are
diff --git a/cnf/make.conf.ia64.diff b/cnf/make.conf.example.ia64.diff
index 3b144d78f..68a0cb01c 100644
--- a/cnf/make.conf.ia64.diff
+++ b/cnf/make.conf.example.ia64.diff
@@ -1,5 +1,5 @@
---- make.conf
-+++ make.conf.ia64
+--- make.conf.example
++++ make.conf.example
@@ -22,6 +22,13 @@
# Example:
#USE="X gtk gnome -alsa"
@@ -14,12 +14,12 @@
# Host and optimization settings
# ==============================
#
-@@ -75,7 +82,7 @@
+@@ -76,7 +83,7 @@
# DO NOT PUT ANYTHING BUT YOUR SPECIFIC ~ARCHITECTURE IN THE LIST.
# IF YOU ARE UNSURE OF YOUR ARCH, OR THE IMPLICATIONS, DO NOT MODIFY THIS.
#
-#ACCEPT_KEYWORDS="~arch"
+#ACCEPT_KEYWORDS="~ia64"
- # Portage Directories
- # ===================
+ # ACCEPT_LICENSE is used to mask packages based on licensing restrictions.
+ # It may contain both license and group names, where group names are
diff --git a/cnf/make.conf.m68k.diff b/cnf/make.conf.example.m68k.diff
index ac3d0748f..f96746142 100644
--- a/cnf/make.conf.m68k.diff
+++ b/cnf/make.conf.example.m68k.diff
@@ -1,6 +1,6 @@
---- make.conf
-+++ make.conf.m68k
-@@ -23,6 +23,13 @@
+--- make.conf.example
++++ make.conf.example
+@@ -22,6 +22,13 @@
# Example:
#USE="X gtk gnome -alsa"
@@ -14,7 +14,7 @@
# Host and optimization settings
# ==============================
#
-@@ -35,7 +42,7 @@
+@@ -41,7 +48,7 @@
#
# Please refer to the GCC manual for a list of possible values.
#
@@ -23,12 +23,12 @@
#
# If you set a CFLAGS above, then this line will set your default C++ flags to
# the same settings.
-@@ -61,7 +68,7 @@
+@@ -76,7 +83,7 @@
# DO NOT PUT ANYTHING BUT YOUR SPECIFIC ~ARCHITECTURE IN THE LIST.
# IF YOU ARE UNSURE OF YOUR ARCH, OR THE IMPLICATIONS, DO NOT MODIFY THIS.
#
-#ACCEPT_KEYWORDS="~arch"
+#ACCEPT_KEYWORDS="~m68k"
- # Portage Directories
- # ===================
+ # ACCEPT_LICENSE is used to mask packages based on licensing restrictions.
+ # It may contain both license and group names, where group names are
diff --git a/cnf/make.conf.mips.diff b/cnf/make.conf.example.mips.diff
index 1ee10ec7b..7d3d83de5 100644
--- a/cnf/make.conf.mips.diff
+++ b/cnf/make.conf.example.mips.diff
@@ -1,6 +1,6 @@
---- make.conf 2006-03-19 18:40:11.000000000 +0100
-+++ make.conf.mips 2006-03-19 18:26:21.000000000 +0100
-@@ -23,6 +23,13 @@
+--- make.conf.example
++++ make.conf.example
+@@ -22,6 +22,13 @@
# Example:
#USE="X gtk gnome -alsa"
@@ -14,9 +14,9 @@
# Host and optimization settings
# ==============================
#
-@@ -33,10 +40,15 @@
- # package (and in some cases the libraries it uses) at default optimizations
- # before reporting errors to developers.
+@@ -39,10 +46,15 @@
+ # -frecord-gcc-switches, since otherwise the check could result in false
+ # positive results.
#
-# Please refer to the GCC manual for a list of possible values.
+# -mcpu=<cpu-type> for MIPS systems selects the type of processor you want
@@ -32,12 +32,12 @@
# If you set a CFLAGS above, then this line will set your default C++ flags to
# the same settings.
#CXXFLAGS="${CFLAGS}"
-@@ -61,7 +73,7 @@
+@@ -76,7 +88,7 @@
# DO NOT PUT ANYTHING BUT YOUR SPECIFIC ~ARCHITECTURE IN THE LIST.
# IF YOU ARE UNSURE OF YOUR ARCH, OR THE IMPLICATIONS, DO NOT MODIFY THIS.
#
-#ACCEPT_KEYWORDS="~arch"
+#ACCEPT_KEYWORDS="~mips"
- # Portage Directories
- # ===================
+ # ACCEPT_LICENSE is used to mask packages based on licensing restrictions.
+ # It may contain both license and group names, where group names are
diff --git a/cnf/make.conf.ppc.diff b/cnf/make.conf.example.ppc.diff
index 76a97d3c2..b34de8e66 100644
--- a/cnf/make.conf.ppc.diff
+++ b/cnf/make.conf.example.ppc.diff
@@ -1,6 +1,6 @@
---- make.conf 2006-03-19 18:40:11.000000000 +0100
-+++ make.conf.ppc 2006-03-19 18:26:21.000000000 +0100
-@@ -23,6 +23,13 @@
+--- make.conf.example
++++ make.conf.example
+@@ -22,6 +22,13 @@
# Example:
#USE="X gtk gnome -alsa"
@@ -14,9 +14,9 @@
# Host and optimization settings
# ==============================
#
-@@ -33,10 +40,56 @@
- # package (and in some cases the libraries it uses) at default optimizations
- # before reporting errors to developers.
+@@ -39,10 +46,56 @@
+ # -frecord-gcc-switches, since otherwise the check could result in false
+ # positive results.
#
-# Please refer to the GCC manual for a list of possible values.
+# -mcpu=<cpu-type> for PowerPC systems selects the type of processor you want
@@ -44,13 +44,13 @@
+#
+# Long term testing has shown that -O3 opts can be unreliable on G4's but work
+# on G3 series processors or earlier.
-+#
-+# The following is the suggested CFLAGS for a generic G4 cpu
-+#
-+#CFLAGS="-O2 -pipe -mcpu=G4 -maltivec -mabi=altivec -fno-strict-aliasing"
#
-#CFLAGS="-O2 -pipe"
++# The following is the suggested CFLAGS for a generic G4 cpu
#
++#CFLAGS="-O2 -pipe -mcpu=G4 -maltivec -mabi=altivec -fno-strict-aliasing"
++#
++#
+# All non G4 PPC boxen should choose this next option. It will work fine for
+# all G3 and pre machines. (note it will not hurt pre G3 machines either to
+# use this mcpu option as it is the default for gcc 3.2.x anyway)
@@ -73,7 +73,7 @@
# If you set a CFLAGS above, then this line will set your default C++ flags to
# the same settings.
#CXXFLAGS="${CFLAGS}"
-@@ -61,7 +114,10 @@
+@@ -76,7 +129,10 @@
# DO NOT PUT ANYTHING BUT YOUR SPECIFIC ~ARCHITECTURE IN THE LIST.
# IF YOU ARE UNSURE OF YOUR ARCH, OR THE IMPLICATIONS, DO NOT MODIFY THIS.
#
@@ -83,5 +83,5 @@
+#
+#ACCEPT_KEYWORDS="~ppc"
- # Portage Directories
- # ===================
+ # ACCEPT_LICENSE is used to mask packages based on licensing restrictions.
+ # It may contain both license and group names, where group names are
diff --git a/cnf/make.conf.ppc64.diff b/cnf/make.conf.example.ppc64.diff
index 2aaec01f0..961508e8f 100644
--- a/cnf/make.conf.ppc64.diff
+++ b/cnf/make.conf.example.ppc64.diff
@@ -1,6 +1,6 @@
---- make.conf 2006-03-19 18:40:11.000000000 +0100
-+++ make.conf.ppc64 2006-03-19 18:26:21.000000000 +0100
-@@ -23,6 +23,13 @@
+--- make.conf.example
++++ make.conf.example
+@@ -22,6 +22,13 @@
# Example:
#USE="X gtk gnome -alsa"
@@ -14,9 +14,9 @@
# Host and optimization settings
# ==============================
#
-@@ -33,9 +40,38 @@
- # package (and in some cases the libraries it uses) at default optimizations
- # before reporting errors to developers.
+@@ -39,9 +46,38 @@
+ # -frecord-gcc-switches, since otherwise the check could result in false
+ # positive results.
#
-# Please refer to the GCC manual for a list of possible values.
+# -mtune=<cpu-type> for PowerPC64 systems instructs the gcc compiler that
@@ -33,15 +33,15 @@
+# 970 (aka G5), and power5.
+#
+# RS64 processors should specify power3.
-+#
+ #
+-#CFLAGS="-O2 -pipe"
+# Additional options of interest:
+#
+# -maltivec enables optional altivec support and should be used
+# only for 970 processors. It also requires that you have
+# the alitvec option compiled into your kernel to take full advantage of this
+# feature. Note: you should also include -mabi=altivec flag if using this option.
- #
--#CFLAGS="-O2 -pipe"
++#
+# -O3 for the most part seems ok but should be used with caution as
+# for instance app-editors/vim has problems if it is used. -O2 is a
+# good selection.
@@ -55,7 +55,7 @@
#
# If you set a CFLAGS above, then this line will set your default C++ flags to
# the same settings.
-@@ -61,7 +97,10 @@
+@@ -76,7 +112,10 @@
# DO NOT PUT ANYTHING BUT YOUR SPECIFIC ~ARCHITECTURE IN THE LIST.
# IF YOU ARE UNSURE OF YOUR ARCH, OR THE IMPLICATIONS, DO NOT MODIFY THIS.
#
@@ -65,5 +65,5 @@
+#
+#ACCEPT_KEYWORDS="ppc64"
- # Portage Directories
- # ===================
+ # ACCEPT_LICENSE is used to mask packages based on licensing restrictions.
+ # It may contain both license and group names, where group names are
diff --git a/cnf/make.conf.s390.diff b/cnf/make.conf.example.s390.diff
index 2acb085ba..c78076236 100644
--- a/cnf/make.conf.s390.diff
+++ b/cnf/make.conf.example.s390.diff
@@ -1,5 +1,5 @@
---- make.conf
-+++ make.conf.s390
+--- make.conf.example
++++ make.conf.example
@@ -22,6 +22,13 @@
# Example:
#USE="X gtk gnome -alsa"
@@ -14,12 +14,12 @@
# Host and optimization settings
# ==============================
#
-@@ -75,7 +82,7 @@
+@@ -76,7 +83,7 @@
# DO NOT PUT ANYTHING BUT YOUR SPECIFIC ~ARCHITECTURE IN THE LIST.
# IF YOU ARE UNSURE OF YOUR ARCH, OR THE IMPLICATIONS, DO NOT MODIFY THIS.
#
-#ACCEPT_KEYWORDS="~arch"
+#ACCEPT_KEYWORDS="~s390"
- # Portage Directories
- # ===================
+ # ACCEPT_LICENSE is used to mask packages based on licensing restrictions.
+ # It may contain both license and group names, where group names are
diff --git a/cnf/make.conf.sh.diff b/cnf/make.conf.example.sh.diff
index f2784e613..9699a708b 100644
--- a/cnf/make.conf.sh.diff
+++ b/cnf/make.conf.example.sh.diff
@@ -1,6 +1,6 @@
---- make.conf 2006-03-19 18:40:11.000000000 +0100
-+++ make.conf.sh 2006-03-19 18:26:21.000000000 +0100
-@@ -23,6 +23,19 @@
+--- make.conf.example
++++ make.conf.example
+@@ -22,6 +22,19 @@
# Example:
#USE="X gtk gnome -alsa"
@@ -20,20 +20,19 @@
# Host and optimization settings
# ==============================
#
-@@ -33,10 +46,15 @@
- # package (and in some cases the libraries it uses) at default optimizations
- # before reporting errors to developers.
+@@ -39,10 +52,15 @@
+ # -frecord-gcc-switches, since otherwise the check could result in false
+ # positive results.
#
-# Please refer to the GCC manual for a list of possible values.
--#
--#CFLAGS="-O2 -pipe"
+# -m# optimize code for the particular type of CPU. The number should match
+# your CHOST so if you are using "sh4-unknown-linux-gnu", you should have
+# -m4 below.
#
+-#CFLAGS="-O2 -pipe"
+# For a full listing of supported CPU models, please refer to the GCC website:
+# http://gcc.gnu.org/onlinedocs/gcc-3.3/gcc/SH-Options.html
-+#
+ #
+#CFLAGS="-m4 -O2 -pipe"
+
# If you set a CFLAGS above, then this line will set your default C++ flags to
diff --git a/cnf/make.conf.sparc-fbsd.diff b/cnf/make.conf.example.sparc-fbsd.diff
index f3d3bca8d..25e6f46c2 100644
--- a/cnf/make.conf.sparc-fbsd.diff
+++ b/cnf/make.conf.example.sparc-fbsd.diff
@@ -1,6 +1,6 @@
---- make.conf 2006-10-16 17:06:32 +0100
-+++ make.conf.sparc-fbsd 2006-10-16 17:09:22 +0100
-@@ -23,6 +23,13 @@
+--- make.conf.example
++++ make.conf.example
+@@ -22,6 +22,13 @@
# Example:
#USE="X gtk gnome -alsa"
@@ -14,12 +14,12 @@
# Host and optimization settings
# ==============================
#
-@@ -61,7 +68,7 @@
+@@ -76,7 +83,7 @@
# DO NOT PUT ANYTHING BUT YOUR SPECIFIC ~ARCHITECTURE IN THE LIST.
# IF YOU ARE UNSURE OF YOUR ARCH, OR THE IMPLICATIONS, DO NOT MODIFY THIS.
#
-#ACCEPT_KEYWORDS="~arch"
+ACCEPT_KEYWORDS="~sparc-fbsd"
- # Portage Directories
- # ===================
+ # ACCEPT_LICENSE is used to mask packages based on licensing restrictions.
+ # It may contain both license and group names, where group names are
diff --git a/cnf/make.conf.sparc.diff b/cnf/make.conf.example.sparc.diff
index e016a0b1e..c68a95aa9 100644
--- a/cnf/make.conf.sparc.diff
+++ b/cnf/make.conf.example.sparc.diff
@@ -1,6 +1,6 @@
---- make.conf 2006-03-19 18:40:11.000000000 +0100
-+++ make.conf.sparc 2006-03-19 18:26:21.000000000 +0100
-@@ -23,6 +23,15 @@
+--- make.conf.example
++++ make.conf.example
+@@ -22,6 +22,15 @@
# Example:
#USE="X gtk gnome -alsa"
@@ -16,9 +16,9 @@
# Host and optimization settings
# ==============================
#
-@@ -33,10 +42,34 @@
- # package (and in some cases the libraries it uses) at default optimizations
- # before reporting errors to developers.
+@@ -39,10 +48,34 @@
+ # -frecord-gcc-switches, since otherwise the check could result in false
+ # positive results.
#
-# Please refer to the GCC manual for a list of possible values.
-#
@@ -55,12 +55,12 @@
# If you set a CFLAGS above, then this line will set your default C++ flags to
# the same settings.
#CXXFLAGS="${CFLAGS}"
-@@ -61,7 +94,7 @@
+@@ -76,7 +109,7 @@
# DO NOT PUT ANYTHING BUT YOUR SPECIFIC ~ARCHITECTURE IN THE LIST.
# IF YOU ARE UNSURE OF YOUR ARCH, OR THE IMPLICATIONS, DO NOT MODIFY THIS.
#
-#ACCEPT_KEYWORDS="~arch"
+#ACCEPT_KEYWORDS="~sparc"
- # Portage Directories
- # ===================
+ # ACCEPT_LICENSE is used to mask packages based on licensing restrictions.
+ # It may contain both license and group names, where group names are
diff --git a/cnf/make.conf.x86-fbsd.diff b/cnf/make.conf.example.x86-fbsd.diff
index 9fec4f177..d5e02feb0 100644
--- a/cnf/make.conf.x86-fbsd.diff
+++ b/cnf/make.conf.example.x86-fbsd.diff
@@ -1,6 +1,6 @@
---- make.conf 2006-03-19 18:40:11.000000000 +0100
-+++ make.conf.x86-fbsd 2006-03-19 18:26:21.000000000 +0100
-@@ -23,6 +23,16 @@
+--- make.conf.example
++++ make.conf.example
+@@ -22,6 +22,16 @@
# Example:
#USE="X gtk gnome -alsa"
@@ -17,9 +17,9 @@
# Host and optimization settings
# ==============================
#
-@@ -33,10 +43,34 @@
- # package (and in some cases the libraries it uses) at default optimizations
- # before reporting errors to developers.
+@@ -39,10 +49,34 @@
+ # -frecord-gcc-switches, since otherwise the check could result in false
+ # positive results.
#
-# Please refer to the GCC manual for a list of possible values.
+# -mtune=<cpu-type> means optimize code for the particular type of CPU without
@@ -54,12 +54,12 @@
# If you set a CFLAGS above, then this line will set your default C++ flags to
# the same settings.
#CXXFLAGS="${CFLAGS}"
-@@ -61,7 +95,7 @@
+@@ -76,7 +110,7 @@
# DO NOT PUT ANYTHING BUT YOUR SPECIFIC ~ARCHITECTURE IN THE LIST.
# IF YOU ARE UNSURE OF YOUR ARCH, OR THE IMPLICATIONS, DO NOT MODIFY THIS.
#
-#ACCEPT_KEYWORDS="~arch"
+ACCEPT_KEYWORDS="~x86-fbsd"
- # Portage Directories
- # ===================
+ # ACCEPT_LICENSE is used to mask packages based on licensing restrictions.
+ # It may contain both license and group names, where group names are
diff --git a/cnf/make.conf.x86.diff b/cnf/make.conf.example.x86.diff
index f90845111..3247126d7 100644
--- a/cnf/make.conf.x86.diff
+++ b/cnf/make.conf.example.x86.diff
@@ -1,6 +1,6 @@
---- make.conf 2007-01-10 03:22:07.410548112 +0100
-+++ make.conf.x86 2007-01-10 03:22:13.206910362 +0100
-@@ -23,6 +23,15 @@
+--- make.conf.example
++++ make.conf.example
+@@ -22,6 +22,15 @@
# Example:
#USE="X gtk gnome -alsa"
@@ -16,9 +16,9 @@
# Host and optimization settings
# ==============================
#
-@@ -33,10 +42,65 @@
- # package (and in some cases the libraries it uses) at default optimizations
- # before reporting errors to developers.
+@@ -39,10 +48,65 @@
+ # -frecord-gcc-switches, since otherwise the check could result in false
+ # positive results.
#
-# Please refer to the GCC manual for a list of possible values.
-#
@@ -85,12 +85,12 @@
# If you set a CFLAGS above, then this line will set your default C++ flags to
# the same settings.
#CXXFLAGS="${CFLAGS}"
-@@ -61,7 +125,7 @@
+@@ -76,7 +140,7 @@
# DO NOT PUT ANYTHING BUT YOUR SPECIFIC ~ARCHITECTURE IN THE LIST.
# IF YOU ARE UNSURE OF YOUR ARCH, OR THE IMPLICATIONS, DO NOT MODIFY THIS.
#
-#ACCEPT_KEYWORDS="~arch"
+#ACCEPT_KEYWORDS="~x86"
- # Portage Directories
- # ===================
+ # ACCEPT_LICENSE is used to mask packages based on licensing restrictions.
+ # It may contain both license and group names, where group names are
diff --git a/cnf/make.globals b/cnf/make.globals
index ada91f8f0..013c5560e 100644
--- a/cnf/make.globals
+++ b/cnf/make.globals
@@ -1,4 +1,4 @@
-# Copyright 1999-2011 Gentoo Foundation
+# Copyright 1999-2013 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# System-wide defaults for the Portage system
@@ -19,24 +19,21 @@ LDFLAGS=""
FFLAGS=""
FCFLAGS=""
-# Default rsync mirror
-SYNC="rsync://rsync.gentoo.org/gentoo-portage"
-
# Default distfiles mirrors. This rotation has multiple hosts and is reliable.
# Approved by the mirror-admin team.
GENTOO_MIRRORS="http://distfiles.gentoo.org"
ACCEPT_LICENSE="* -@EULA"
ACCEPT_PROPERTIES="*"
+ACCEPT_RESTRICT="*"
-# Repository Paths
-PORTDIR=/usr/portage
-DISTDIR=${PORTDIR}/distfiles
-PKGDIR=${PORTDIR}/packages
-RPMDIR=${PORTDIR}/rpm
+# Miscellaneous paths
+DISTDIR="/usr/portage/distfiles"
+PKGDIR="/usr/portage/packages"
+RPMDIR="/usr/portage/rpm"
# Temporary build directory
-PORTAGE_TMPDIR=/var/tmp
+PORTAGE_TMPDIR="/var/tmp"
# Fetching command (3 tries, passive ftp for firewall compatibility)
FETCHCOMMAND="wget -t 3 -T 60 --passive-ftp -O \"\${DISTDIR}/\${FILE}\" \"\${URI}\""
@@ -45,17 +42,19 @@ RESUMECOMMAND="wget -c -t 3 -T 60 --passive-ftp -O \"\${DISTDIR}/\${FILE}\" \"\$
FETCHCOMMAND_RSYNC="rsync -avP \"\${URI}\" \"\${DISTDIR}/\${FILE}\""
RESUMECOMMAND_RSYNC="rsync -avP \"\${URI}\" \"\${DISTDIR}/\${FILE}\""
-FETCHCOMMAND_SSH="bash -c \"x=\\\${2#ssh://} ; host=\\\${x%%/*} ; port=\\\${host##*:} ; host=\\\${host%:*} ; [[ \\\${host} = \\\${port} ]] && port=22 ; exec rsync --rsh=\\\"ssh -p\\\${port}\\\" -avP \\\"\\\${host}:/\\\${x#*/}\\\" \\\"\\\$1\\\"\" rsync \"\${DISTDIR}/\${FILE}\" \"\${URI}\""
+# NOTE: rsync will evaluate quotes embedded inside PORTAGE_SSH_OPTS
+FETCHCOMMAND_SSH="bash -c \"x=\\\${2#ssh://} ; host=\\\${x%%/*} ; port=\\\${host##*:} ; host=\\\${host%:*} ; [[ \\\${host} = \\\${port} ]] && port=22 ; exec rsync --rsh=\\\"ssh -p\\\${port} \\\${3}\\\" -avP \\\"\\\${host}:/\\\${x#*/}\\\" \\\"\\\$1\\\"\" rsync \"\${DISTDIR}/\${FILE}\" \"\${URI}\" \"\${PORTAGE_SSH_OPTS}\""
RESUMECOMMAND_SSH=${FETCHCOMMAND_SSH}
-FETCHCOMMAND_SFTP="bash -c \"x=\\\${2#sftp://} ; host=\\\${x%%/*} ; port=\\\${host##*:} ; host=\\\${host%:*} ; [[ \\\${host} = \\\${port} ]] && port=22 ; exec sftp -P \\\${port} \\\"\\\${host}:/\\\${x#*/}\\\" \\\"\\\$1\\\"\" sftp \"\${DISTDIR}/\${FILE}\" \"\${URI}\""
+# NOTE: bash eval is used to evaluate quotes embedded inside PORTAGE_SSH_OPTS
+FETCHCOMMAND_SFTP="bash -c \"x=\\\${2#sftp://} ; host=\\\${x%%/*} ; port=\\\${host##*:} ; host=\\\${host%:*} ; [[ \\\${host} = \\\${port} ]] && port=22 ; eval \\\"declare -a ssh_opts=(\\\${3})\\\" ; exec sftp -P \\\${port} \\\"\\\${ssh_opts[@]}\\\" \\\"\\\${host}:/\\\${x#*/}\\\" \\\"\\\$1\\\"\" sftp \"\${DISTDIR}/\${FILE}\" \"\${URI}\" \"\${PORTAGE_SSH_OPTS}\""
# Default user options
FEATURES="assume-digests binpkg-logs
config-protect-if-modified distlocks ebuild-locks
- fixlafiles news parallel-fetch parse-eapi-ebuild-head protect-owned
+ fixlafiles merge-sync news parallel-fetch preserve-libs protect-owned
sandbox sfperms strict unknown-features-warn unmerge-logs
- unmerge-orphans userfetch"
+ unmerge-orphans userfetch userpriv usersandbox usersync"
# Ignore file collisions in /lib/modules since files inside this directory
# are never unmerged, and therefore collisions must be ignored in order for
@@ -63,16 +62,9 @@ FEATURES="assume-digests binpkg-logs
# Ignore file collisions for unowned *.pyo and *.pyc files, this helps during
# transition from compiling python modules in live file system to compiling
# them in src_install() function.
-COLLISION_IGNORE="/lib/modules/* *.py[co]"
+COLLISION_IGNORE="/lib/modules/* *.py[co] *\$py.class"
UNINSTALL_IGNORE="/lib/modules/*"
-# Enable preserve-libs for testing with portage versions that support it.
-# This setting is commented out for portage versions that don't support it.
-FEATURES="${FEATURES} preserve-libs"
-
-# Default chunksize for binhost comms
-PORTAGE_BINHOST_CHUNKSIZE="3000"
-
# By default wait 5 secs before cleaning a package
CLEAN_DELAY="5"
@@ -100,7 +92,7 @@ PORTAGE_RSYNC_RETRIES="-1"
# Number of seconds rsync will wait before timing out.
#RSYNC_TIMEOUT="180"
-PORTAGE_RSYNC_OPTS="--recursive --links --safe-links --perms --times --compress --force --whole-file --delete --stats --human-readable --timeout=180 --exclude=/distfiles --exclude=/local --exclude=/packages"
+PORTAGE_RSYNC_OPTS="--recursive --links --safe-links --perms --times --omit-dir-times --compress --force --whole-file --delete --stats --human-readable --timeout=180 --exclude=/distfiles --exclude=/local --exclude=/packages"
# The number of days after the last `emerge --sync` that a warning
# message should be produced.
@@ -121,7 +113,7 @@ PORTAGE_WORKDIR_MODE="0700"
# Some defaults for elog
PORTAGE_ELOG_CLASSES="log warn error"
-PORTAGE_ELOG_SYSTEM="save_summary echo"
+PORTAGE_ELOG_SYSTEM="save_summary:log,warn,error,qa echo"
PORTAGE_ELOG_MAILURI="root"
PORTAGE_ELOG_MAILSUBJECT="[portage] ebuild log for \${PACKAGE} on \${HOST}"
@@ -130,6 +122,10 @@ PORTAGE_ELOG_MAILFROM="portage@localhost"
# Signing command used by repoman
PORTAGE_GPG_SIGNING_COMMAND="gpg --sign --digest-algo SHA256 --clearsign --yes --default-key \"\${PORTAGE_GPG_KEY}\" --homedir \"\${PORTAGE_GPG_DIR}\" \"\${FILE}\""
+# Security labels are special, see bug #461868.
+# system.nfs4_acl attributes are irrelevant, see bug #475496.
+PORTAGE_XATTR_EXCLUDE="security.* system.nfs4_acl"
+
# *****************************
# ** DO NOT EDIT THIS FILE **
# ***************************************************
diff --git a/cnf/metadata.dtd b/cnf/metadata.dtd
index d97642a72..ff2649cad 100644
--- a/cnf/metadata.dtd
+++ b/cnf/metadata.dtd
@@ -5,7 +5,7 @@
<!ATTLIST catmetadata pkgname CDATA "">
<!-- Metadata for a package -->
-<!ELEMENT pkgmetadata ( (herd|maintainer|longdescription|use|upstream)* )>
+<!ELEMENT pkgmetadata ( (herd|maintainer|natural-name|longdescription|use|upstream)* )>
<!ATTLIST pkgmetadata pkgname CDATA "">
<!-- One tag for each herd this package is assigned to. -->
@@ -14,6 +14,9 @@
<!-- One tag for each maintainer of a package, multiple allowed-->
<!ELEMENT maintainer ( email, (description| name)* )>
+ <!-- Natural name for package, example: LibreOffice (for app-office/libreoffice) -->
+ <!ELEMENT natural-name (#PCDATA) >
+
<!-- A long description of the package in freetext-->
<!ELEMENT longdescription (#PCDATA|pkg|cat)* >
@@ -61,7 +64,7 @@
<!ELEMENT bugs-to (#PCDATA)>
<!-- specify a type of package identification tracker -->
<!ELEMENT remote-id (#PCDATA)>
- <!ATTLIST remote-id type (freshmeat|sourceforge|sourceforge-jp|cpan|vim|google-code|ctan|pypi|rubyforge|cran) #REQUIRED>
+ <!ATTLIST remote-id type (bitbucket|cpan|cpan-module|cpe|cran|ctan|freecode|freshmeat|github|gitorious|google-code|launchpad|pear|pecl|pypi|rubyforge|rubygems|sourceforge|sourceforge-jp|vim) #REQUIRED>
<!-- category/package information for cross-linking in descriptions
and useflag descriptions -->
diff --git a/cnf/repos.conf b/cnf/repos.conf
new file mode 100644
index 000000000..8c657daae
--- /dev/null
+++ b/cnf/repos.conf
@@ -0,0 +1,7 @@
+[DEFAULT]
+main-repo = gentoo
+
+[gentoo]
+location = /usr/portage
+sync-type = rsync
+sync-uri = rsync://rsync.gentoo.org/gentoo-portage
diff --git a/cnf/sets/portage.conf b/cnf/sets/portage.conf
index c5c787bb5..b73afb19f 100644
--- a/cnf/sets/portage.conf
+++ b/cnf/sets/portage.conf
@@ -51,7 +51,7 @@ class = portage.sets.libs.PreservedLibraryConsumerSet
[live-rebuild]
class = portage.sets.dbapi.VariableSet
variable = INHERITED
-includes = bzr cvs darcs git git-2 mercurial subversion tla
+includes = bzr cvs darcs git git-2 git-r3 mercurial subversion tla
# Installed packages that own files inside /lib/modules.
[module-rebuild]
diff --git a/doc/config/sets.docbook b/doc/config/sets.docbook
index f7eea7766..8f7441250 100644
--- a/doc/config/sets.docbook
+++ b/doc/config/sets.docbook
@@ -17,9 +17,8 @@
<varname>system</varname> or <varname>security</varname>.
<!-- TODO: Add reference to currently non-existing documentation about
set usage and default sets -->
- After that it will read repository specific configurations from
- <envar>PORTDIR</envar> and <envar>PORTDIR_OVERLAY</envar> that might
- include definitions of sets included in the repository.
+ After that it will read configurations located in repositories
+ configured in <filename>repos.conf</filename>.
Finally a system-specific set configuration may reside in
<filename>/etc/portage</filename> to either define additional sets or
alter the default and repository sets.
diff --git a/doc/package/ebuild.docbook b/doc/package/ebuild.docbook
index ba146ca99..c3b6caca3 100644
--- a/doc/package/ebuild.docbook
+++ b/doc/package/ebuild.docbook
@@ -11,5 +11,8 @@
&package_ebuild_eapi_4;
&package_ebuild_eapi_4_python;
&package_ebuild_eapi_4_slot_abi;
+&package_ebuild_eapi_5;
+&package_ebuild_eapi_5_progress;
+&package_ebuild_eapi_5_hdepend;
</section>
</chapter>
diff --git a/doc/package/ebuild/eapi/4-python.docbook b/doc/package/ebuild/eapi/4-python.docbook
index ec5fd83c4..a61ac0503 100644
--- a/doc/package/ebuild/eapi/4-python.docbook
+++ b/doc/package/ebuild/eapi/4-python.docbook
@@ -19,7 +19,6 @@
<listitem><para>docompress</para></listitem>
<listitem><para>exeopts</para></listitem>
<listitem><para>insopts</para></listitem>
- <listitem><para>keepdir</para></listitem>
<listitem><para>libopts</para></listitem>
<listitem><para>use</para></listitem>
<listitem><para>use_enable</para></listitem>
@@ -97,7 +96,7 @@
<section id='package-ebuild-eapi-4-python-repo-level-config'>
<title>Extended Repository-Level Configuration</title>
<para>
- Repository-level configuration in ${repository}/profiles is supported for the following files:
+ Repository-level configuration in ${repository_path}/profiles is supported for the following files:
<itemizedlist>
<listitem><para>make.defaults</para></listitem>
<listitem><para>package.use</para></listitem>
@@ -107,8 +106,11 @@
<listitem><para>use.mask</para></listitem>
</itemizedlist>
</para>
+ </section>
+ <section id='package-ebuild-eapi-4-python-directories'>
+ <title>Directories Allowed for Profile-Level and Repository-Level Configuration</title>
<para>
- By default, the following files in ${repository}/profiles can be also directories:
+ The following files can be directories:
<itemizedlist>
<listitem><para>package.mask</para></listitem>
<listitem><para>package.use</para></listitem>
@@ -119,4 +121,40 @@
</itemizedlist>
</para>
</section>
+ <section id='package-ebuild-eapi-4-python-use-aliases'>
+ <title>USE Flag Aliases</title>
+ <para>
+ USE flag aliases are supported to allow to satisfy dependencies of packages from other repositories, which require differently named USE flags. USE flag aliases are defined in ${repository_path}/profiles/use.aliases and ${repository_path}/profiles/package.use.aliases files.
+ </para>
+ <table><title>use.aliases Example</title>
+ <tgroup cols='1' align='left'>
+ <tbody>
+ <row>
+ <entry>real_flag1 alias1 alias2</entry>
+ </row>
+ <row>
+ <entry>real_flag2 alias3 alias4</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ <table><title>package.use.aliases Example</title>
+ <tgroup cols='1' align='left'>
+ <tbody>
+ <row>
+ <entry>category/package1 real_flag1 alias1 alias2</entry>
+ </row>
+ <row>
+ <entry>category/package1 real_flag2 alias3 alias4</entry>
+ </row>
+ <row>
+ <entry>=category/package2-1* real_flag3 alias5 alias6</entry>
+ </row>
+ <row>
+ <entry>=category/package2-2* real_flag4 alias5 alias6</entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </section>
</section>
diff --git a/doc/package/ebuild/eapi/4-slot-abi.docbook b/doc/package/ebuild/eapi/4-slot-abi.docbook
index 696d0bf74..08e2cef75 100644
--- a/doc/package/ebuild/eapi/4-slot-abi.docbook
+++ b/doc/package/ebuild/eapi/4-slot-abi.docbook
@@ -28,12 +28,12 @@ Refer to the
</para>
</section>
<section id='package-ebuild-eapi-4-slot-abi-metadata-dependency-atom-slot-abi-equal-operator'>
-<title>Dependency Atom SLOT/ABI := Operator</title>
+<title>Dependency Atom slot/sub-slot := Operator</title>
<para>
-Dependency atom syntax now supports SLOT/ABI := operators which allow the
-specific SLOT/ABI that a package is built against to be recorded, so that it's
+Dependency atom syntax now supports slot/sub-slot := operators which allow the
+specific slot/sub-slot that a package is built against to be recorded, so that it's
possible to automatically determine when a package needs to be rebuilt due to
-having a dependency upgraded to a different SLOT/ABI.
+having a dependency upgraded to a different slot/sub-slot.
</para>
<para>
For example, if a package is built
@@ -50,13 +50,13 @@ not contain a sub-slot part, the sub-slot is considered to be implicitly equal
to "4.8".
</para>
<para>
-When dependencies are rewritten as described above, the SLOT/ABI recorded in
+When dependencies are rewritten as described above, the slot/sub-slot recorded in
the atom is always equal to that of the highest matched version that is
installed at build time.
</para>
</section>
<section id='package-ebuild-eapi-4-slot-abi-metadata-dependency-atom-slot-abi-asterisk-operator'>
-<title>Dependency Atom SLOT/ABI :* Operator</title>
+<title>Dependency Atom slot/sub-slot :* Operator</title>
<para>
The new :* operator is used to express dependencies that can change versions
at runtime without requiring reverse dependencies to be rebuilt. For example,
diff --git a/doc/package/ebuild/eapi/5-hdepend.docbook b/doc/package/ebuild/eapi/5-hdepend.docbook
new file mode 100644
index 000000000..0f568bcdd
--- /dev/null
+++ b/doc/package/ebuild/eapi/5-hdepend.docbook
@@ -0,0 +1,32 @@
+<section id='package-ebuild-eapi-5-hdepend'>
+<title>EAPI 5-hdepend</title>
+<section id='package-ebuild-eapi-5-hdepend-metadata'>
+<title>Metadata</title>
+<section id='package-ebuild-eapi-5-hdepend-metadata-dependencies'>
+<title>Dependencies</title>
+<section id='package-ebuild-eapi-5-hdepend-metadata-dependencies-hdepend'>
+<title>HDEPEND</title>
+<para>
+The HDEPEND variable is used to represent build-time host dependencies. For
+build-time target dependencies, use DEPEND (if the host is the target then both
+HDEPEND and DEPEND will be installed on it). For EAPIs that support HDEPEND,
+the emerge --root-deps option will have no effect, since it is not needed
+when build-time dependencies are correctly specified with HDEPEND and DEPEND.
+If ebuilds using EAPIs which <emphasis>do not</emphasis> support HDEPEND are
+built in the same emerge run as those using EAPIs which <emphasis>do</emphasis>
+support HDEPEND, the emerge --root-deps option will only apply to the former.
+</para>
+</section>
+<section id='package-ebuild-eapi-5-hdepend-metadata-dependencies-targetroot'></