pisi-1.1 -> trunk ...
Since most of the development went on the branch and trunk did not see significant commits for so long...
This commit is contained in:
@@ -1,189 +0,0 @@
|
|||||||
|
|
||||||
Here we take notes of the strange stuff, so we can refactor them after
|
|
||||||
Pardus 2007 release.
|
|
||||||
|
|
||||||
|
|
||||||
==> Python 2.5 support
|
|
||||||
* We should use python2.5
|
|
||||||
|
|
||||||
==> Locale support
|
|
||||||
* bindtextdomain and textdomain calls are not necessary, because
|
|
||||||
gettext.translation() dont use them.
|
|
||||||
|
|
||||||
* setlocale call is probably necessary for some stuff, but not for
|
|
||||||
message translation, it seems gettext.translation() api looks for
|
|
||||||
environment LC_ALL, LC_MESSAGES anyway.
|
|
||||||
|
|
||||||
* pygettext.py shouldn't be needed at all. Plain xgettext works with
|
|
||||||
python source.
|
|
||||||
|
|
||||||
|
|
||||||
==> Utility functions
|
|
||||||
* sha1_file and sha1_data functions has some
|
|
||||||
exception confusion. These two functions should be a lot simpler.
|
|
||||||
|
|
||||||
* get_file_hashes is overly complex and contains strange code like:
|
|
||||||
for r, d, f in os.walk(parent, topdown=False): pass
|
|
||||||
|
|
||||||
* To estimate required disk size for the packages more accurately we can
|
|
||||||
calculate package size + (nr of files * inode size of fs).
|
|
||||||
|
|
||||||
* Why in a world like this there exists *parse_package* util functions? These must be all methods of package class
|
|
||||||
|
|
||||||
* Remove all unneeded util functions, most of them belongs its classes
|
|
||||||
|
|
||||||
==> code readability
|
|
||||||
* Public functions should contain doc strings.
|
|
||||||
|
|
||||||
* Python builtins like file, list, etc should be avoided in variable names.
|
|
||||||
There is even a file.py module!
|
|
||||||
|
|
||||||
* a,b,c,d,f,r,_i,A,B,C,G are equally bad.
|
|
||||||
|
|
||||||
* some import'ed modules are not used inside the importer modules, cleanup needed.
|
|
||||||
|
|
||||||
* Would be very good if we can avoid "from x import y" form, it makes it
|
|
||||||
harder to reload modules.
|
|
||||||
|
|
||||||
* Convert all String Concatenation into "%s" % string form which is much faster, readable and correct
|
|
||||||
|
|
||||||
==> exceptions
|
|
||||||
* Current model is bad. Exception names should tell what is the error type. Instead
|
|
||||||
we have one Error exception in every module. If I call pisi.api.install("lala"),
|
|
||||||
I should get pisi.api.PackageNotFound or pisi.install.PackageNotFound or something
|
|
||||||
like that. For every kind of error, you get pisi.api.Error now, and only way to find
|
|
||||||
out exact error is try to parse error string (which is localized).
|
|
||||||
|
|
||||||
* class Exception(Exception) is evil.
|
|
||||||
|
|
||||||
* There shouldn't be a bare Except: clause in pisi modules.
|
|
||||||
|
|
||||||
|
|
||||||
==> database
|
|
||||||
* We should have a DB performance test suite to find important points to make faster,
|
|
||||||
if we cannot measure, we cannot improve.
|
|
||||||
|
|
||||||
* [FIXED] We should use "2" as pickle protocol. currently we use old binary pickle protocol "1". New
|
|
||||||
protocol generally produces more compact pickled objects (dbshelve.py)
|
|
||||||
|
|
||||||
* History, and Summary-Description objects should be kept in seperate db files. This way
|
|
||||||
we can have faster searches and probably faster access to packages and better memory footprint
|
|
||||||
|
|
||||||
* For big objects with many member objects (Package, from pisi.metadata) we might investigate
|
|
||||||
writing our own simple serialization routines for some objects like Conflicts or additionalfiles.
|
|
||||||
|
|
||||||
* context singleton is a mess. Maybe we should consider another approach to access common db objects
|
|
||||||
|
|
||||||
* ComponentDB should not hold lists of Packages that belongs to it. A new index for components to package DB
|
|
||||||
should be enough.
|
|
||||||
|
|
||||||
* Current implementation of repository system is suboptimal. We add every package to a Dictionary as value
|
|
||||||
and repository name as key and add that dictionary to db. For example if I am adding package foo to
|
|
||||||
packages db, I am actually adding, a Dictionary with ["repotype", foo] to db.
|
|
||||||
This is cheap, bloated and slow. We must have different repository databases for packages.
|
|
||||||
|
|
||||||
* We should really consider using a simple and fast relational database (sqlite) for database operations. Here
|
|
||||||
is the rationale and some issues.
|
|
||||||
- Current implementation uses berkeleydb as a storage of dictionaries, with keys and Pickled Python objects.
|
|
||||||
This approach simplifies coding requirements but leads to some problems.
|
|
||||||
1. Some operations cannot be done effectively. Searching can only be done by iterating all objects and searching
|
|
||||||
one by one. component, reverse dependencies etc are holding lists of package names that are updated on every
|
|
||||||
package operation, Multiple repository problem is
|
|
||||||
|
|
||||||
2.Performance: although fast, pickling and unpickling whole objects is still a time consuming process.
|
|
||||||
Pickled Objects contains object metadata and are larger then the data they hold, so reading, writing pickled
|
|
||||||
Objects to db is slower than reading and writing only necessary fields. large objects (Order of kilobytes)
|
|
||||||
causes berkeleydb data buckets to overflow and caches works less efficently.
|
|
||||||
|
|
||||||
4.Disk usage: Using pickled objects requires more memory and disk space. Total size of a current pisi database
|
|
||||||
is over 100Mb, if we modify files.bdb to only hold filenames and packages, size is still around 50MB.
|
|
||||||
|
|
||||||
Rational Databases offers number of advantages and disadvantages:
|
|
||||||
|
|
||||||
Advantages:
|
|
||||||
+ Relational databases offers much more flexible operations on stored data. Searching, grouping, sorting
|
|
||||||
can be done by database engine efficently.
|
|
||||||
+ There will be only a single database file and much smaller database size compared to berkeleydb files
|
|
||||||
holding pickled python objects.
|
|
||||||
+ Since database no longer holds pickled python objects, it is possible to read and modify the database
|
|
||||||
by other programs written in different languages (Java, C++ etc.)
|
|
||||||
+ SQL lite is generally very fast, probably beating "Berkeleydb with pickled objects" by the order of 4-5 on
|
|
||||||
queries.
|
|
||||||
|
|
||||||
Disadvantages
|
|
||||||
- Using a relational database will require more coding when adding and retrieving contents of objects.
|
|
||||||
- Introducing SQL language makes code more complex and harder to maintain.
|
|
||||||
- Designing a good schema, identifying required indexes etc. takes time
|
|
||||||
- Some developers are superstitious about sql and relational databases ;)
|
|
||||||
|
|
||||||
==> class attributes
|
|
||||||
* In some classes there are some attributes assigned but never
|
|
||||||
used. (see remove_unused_attributes.patch)
|
|
||||||
|
|
||||||
* PiSi uses heavy classes and creates thousands of instances of them
|
|
||||||
(Package, Metadata, Dependency, ...). These classes should define
|
|
||||||
__slots__ to reduce the heap used.
|
|
||||||
|
|
||||||
|
|
||||||
==> actionsAPI
|
|
||||||
* Get rid of ugly exception model
|
|
||||||
* Refactor/clean the code
|
|
||||||
* Add strict checks to models
|
|
||||||
* Maybe? Get rid of functional logic, switch to OO one
|
|
||||||
* ActionsAPI still needs an updated API document
|
|
||||||
|
|
||||||
|
|
||||||
==> PiSi API
|
|
||||||
* Write a real one
|
|
||||||
|
|
||||||
|
|
||||||
==> Function parameters
|
|
||||||
* Check function parameters and see if some parameters (especially the
|
|
||||||
ones named tmpDir/tmp_dir/target_dir) are redundant now. See
|
|
||||||
http://liste.uludag.org.tr/uludag-commits/2007-February/010070.html
|
|
||||||
|
|
||||||
* conflict.py
|
|
||||||
conflicts method takes a pkg_name parameter but doesn't use it at all
|
|
||||||
|
|
||||||
|
|
||||||
==> Fixes (that need API breakage)
|
|
||||||
* http://liste.uludag.org.tr/uludag-commits/2007-February/010117.html
|
|
||||||
|
|
||||||
==> Logging
|
|
||||||
|
|
||||||
* Improve logging with all needed update/downgrade/install/remove information so one can easily find the history of packages,
|
|
||||||
currently PiSi wrotes everyting into logs which is not usefull. Also this information can be used for rollback and reporting.
|
|
||||||
|
|
||||||
==> operations.py and atomicoperations.py
|
|
||||||
|
|
||||||
* These modules have gone so big and become untraceable... divide all operations to their related modules
|
|
||||||
under a pisi.operations module...
|
|
||||||
|
|
||||||
==> function code lengths
|
|
||||||
|
|
||||||
* we have some functions that goes pages long... divide all of them to small digestable chunks..
|
|
||||||
avoid writing functions longer than your editor's screen.
|
|
||||||
|
|
||||||
==> assertions
|
|
||||||
|
|
||||||
* Lots of assertions used in the code with no following descriptive string information.
|
|
||||||
|
|
||||||
==> repo order
|
|
||||||
|
|
||||||
* When trying to install a package or looking for a dependency for a package the first found package
|
|
||||||
in "repo order" is used. This design decision is not very good. When a new repo that has the latest
|
|
||||||
version of any package is added and if it is the last repo in order, pisi can not upgrade to this
|
|
||||||
package.
|
|
||||||
|
|
||||||
We can remove this order thing and in this situation we can use the latest version of the package.
|
|
||||||
This should also lead to some other problems but between these two not very good solutions this
|
|
||||||
seems to be the better one.
|
|
||||||
|
|
||||||
==> autoxml
|
|
||||||
|
|
||||||
* When setting a Long type attribute or tag of an autoxml class, value must be Long type. Otherwise,
|
|
||||||
autoxml.write() fails in x86_64
|
|
||||||
|
|
||||||
==> COMAR
|
|
||||||
|
|
||||||
* pisi-cli should use comar.
|
|
||||||
@@ -1,96 +0,0 @@
|
|||||||
Possible API Migrations
|
|
||||||
=======================
|
|
||||||
|
|
||||||
Pisi does not have an api. All the projects use its internal modules to do their
|
|
||||||
jobs. This file holds a list of these usages for api migration.
|
|
||||||
|
|
||||||
PiSi
|
|
||||||
====
|
|
||||||
|
|
||||||
Pisi itself also should not use internal db modules. It can also use this abstracted
|
|
||||||
api layer from the needed places.
|
|
||||||
|
|
||||||
* packagedb.remove_repo
|
|
||||||
* sourcedb.remove_repo
|
|
||||||
* packagedb.which_repo
|
|
||||||
* repodb.get_repo
|
|
||||||
* packagedb.get_package
|
|
||||||
* installdb.is_installed
|
|
||||||
* packagedb.get_rev_deps
|
|
||||||
* installdb.get_version
|
|
||||||
* packagedb.has_package
|
|
||||||
* packagedb.add_package
|
|
||||||
* componentdb.add_package
|
|
||||||
* filesdb.has_file
|
|
||||||
* filesdb.get_file
|
|
||||||
* installdb.get_info
|
|
||||||
* installdb.files
|
|
||||||
* installdb.pkg_dir
|
|
||||||
* installdb.install
|
|
||||||
* filesdb.add_files
|
|
||||||
* componentdb.add_spec
|
|
||||||
* sourcedb.add_spec
|
|
||||||
* componentdb.get_union_comp
|
|
||||||
* componentdb.remove_spec
|
|
||||||
* installdb.get_version
|
|
||||||
* componentdb.remove_repo
|
|
||||||
* componentdb.remove_package
|
|
||||||
* componentdb.update_component
|
|
||||||
* componentdb.add_package
|
|
||||||
* installdb.remove
|
|
||||||
* filesdb.remove_files
|
|
||||||
* sourcedb.pkgtosrc
|
|
||||||
* sourcedb.get_spec
|
|
||||||
* sourcedb.get_source
|
|
||||||
* sourcedb.get_spec_repo
|
|
||||||
* repodb.get_repo
|
|
||||||
* componentdb.has_component
|
|
||||||
* componentdb.get_component
|
|
||||||
* installdb.is_installed
|
|
||||||
* packagedb.list_packages
|
|
||||||
* installdb.list_installed
|
|
||||||
* componentdb.get_union_packages
|
|
||||||
* componentdb.list_components
|
|
||||||
* repodb.list
|
|
||||||
* sourcedb.list
|
|
||||||
* installdb.list_pending
|
|
||||||
* filesdb.match_files
|
|
||||||
|
|
||||||
Package Manager
|
|
||||||
===============
|
|
||||||
|
|
||||||
Package Manager should not use internal db modules of pisi. It should only use pisi
|
|
||||||
api.
|
|
||||||
|
|
||||||
* repodb.get_repo
|
|
||||||
* packagedb.get_package
|
|
||||||
|
|
||||||
pisi.itemsbyrepo.installed or pisi.itemsbyrepo.repos should not be used by package manager.
|
|
||||||
Instead api should have functions like api.get_installed_packages, api.get_repo_packages and
|
|
||||||
get_all_packages/get_packages.
|
|
||||||
|
|
||||||
* componentdb.list_components
|
|
||||||
* repodb.list
|
|
||||||
* componentdb.get_union_comp
|
|
||||||
* componentdb.get_union_packages
|
|
||||||
|
|
||||||
Yali
|
|
||||||
====
|
|
||||||
|
|
||||||
Yali should not use internal db modules of pisi. It should only use pisi api.
|
|
||||||
|
|
||||||
* api.add_repo
|
|
||||||
* api.update_repo
|
|
||||||
* api.remove_repo
|
|
||||||
* api.install
|
|
||||||
* packagedb.list_packages
|
|
||||||
* installdb.list_pending
|
|
||||||
* api.configure_pending
|
|
||||||
* packagedb.get_package
|
|
||||||
|
|
||||||
Buildfarm
|
|
||||||
=========
|
|
||||||
|
|
||||||
Buildfarm should not use internal db modules of pisi. It should only use pisi api.
|
|
||||||
|
|
||||||
* api.create_delta_package
|
|
||||||
+1
-12
@@ -22,20 +22,11 @@ import pisi.context as ctx
|
|||||||
import pisi.cli.pisicli as pisicli
|
import pisi.cli.pisicli as pisicli
|
||||||
|
|
||||||
import gettext
|
import gettext
|
||||||
gettext.bindtextdomain('pisi', "/usr/share/locale")
|
|
||||||
gettext.textdomain('pisi')
|
|
||||||
__trans = gettext.translation('pisi', fallback=True)
|
__trans = gettext.translation('pisi', fallback=True)
|
||||||
_ = __trans.ugettext
|
_ = __trans.ugettext
|
||||||
|
|
||||||
def sig_handler(sig, frame):
|
|
||||||
if sig == signal.SIGTERM:
|
|
||||||
exit()
|
|
||||||
|
|
||||||
def exit():
|
def exit():
|
||||||
try:
|
pisi.api.finalize()
|
||||||
pisi.api.finalize()
|
|
||||||
except KeyboardInterrupt: # raised pending interrupt
|
|
||||||
pass
|
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
def handle_exception(exception, value, tb):
|
def handle_exception(exception, value, tb):
|
||||||
@@ -82,8 +73,6 @@ if __name__ == "__main__":
|
|||||||
|
|
||||||
sys.excepthook = handle_exception
|
sys.excepthook = handle_exception
|
||||||
|
|
||||||
signal.signal(signal.SIGTERM, sig_handler)
|
|
||||||
|
|
||||||
locale.setlocale(locale.LC_ALL, '')
|
locale.setlocale(locale.LC_ALL, '')
|
||||||
cli = pisicli.PisiCLI()
|
cli = pisicli.PisiCLI()
|
||||||
cli.run_command()
|
cli.run_command()
|
||||||
|
|||||||
+2
-10
@@ -78,7 +78,6 @@
|
|||||||
RuntimeDependencies |
|
RuntimeDependencies |
|
||||||
Files |
|
Files |
|
||||||
Conflicts |
|
Conflicts |
|
||||||
Replaces |
|
|
||||||
AdditionalFiles |
|
AdditionalFiles |
|
||||||
Provides
|
Provides
|
||||||
)*>
|
)*>
|
||||||
@@ -91,14 +90,6 @@
|
|||||||
<!-- we have a problem here, this Package tag only contains a package name
|
<!-- we have a problem here, this Package tag only contains a package name
|
||||||
while dtd treats this as another Package section, who said dtd doesnt
|
while dtd treats this as another Package section, who said dtd doesnt
|
||||||
suck anyway -->
|
suck anyway -->
|
||||||
<!ATTLIST Package versionFrom CDATA #IMPLIED>
|
|
||||||
<!ATTLIST Package versionTo CDATA #IMPLIED>
|
|
||||||
<!ATTLIST Package version CDATA #IMPLIED>
|
|
||||||
<!ATTLIST Package releaseFrom CDATA #IMPLIED>
|
|
||||||
<!ATTLIST Package releaseTo CDATA #IMPLIED>
|
|
||||||
<!ATTLIST Package release CDATA #IMPLIED>
|
|
||||||
|
|
||||||
<!ELEMENT Replaces (Package)+>
|
|
||||||
|
|
||||||
<!ELEMENT AdditionalFiles (AdditionalFile+)>
|
<!ELEMENT AdditionalFiles (AdditionalFile+)>
|
||||||
<!ELEMENT AdditionalFile (#PCDATA)>
|
<!ELEMENT AdditionalFile (#PCDATA)>
|
||||||
@@ -124,7 +115,8 @@ suck anyway -->
|
|||||||
|
|
||||||
<!ELEMENT Update (#PCDATA | Date | Version | Comment | Name | Email)*>
|
<!ELEMENT Update (#PCDATA | Date | Version | Comment | Name | Email)*>
|
||||||
<!ATTLIST Update release CDATA #REQUIRED>
|
<!ATTLIST Update release CDATA #REQUIRED>
|
||||||
<!ATTLIST Update type (security|bug) #IMPLIED>
|
<!-- FIXME: valid types must be used instead of CDATA -->
|
||||||
|
<!ATTLIST Update type CDATA #IMPLIED>
|
||||||
|
|
||||||
<!ELEMENT Date (#PCDATA)>
|
<!ELEMENT Date (#PCDATA)>
|
||||||
<!ELEMENT Version (#PCDATA)>
|
<!ELEMENT Version (#PCDATA)>
|
||||||
|
|||||||
-502
@@ -1,502 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!-- RELAX NG schema file for PISI pspec.xml files -->
|
|
||||||
<!-- http://www.pardus.org.tr/projeler/pisi/ -->
|
|
||||||
|
|
||||||
<grammar xmlns="http://relaxng.org/ns/structure/1.0">
|
|
||||||
|
|
||||||
<!-- Start Document -->
|
|
||||||
<start>
|
|
||||||
<ref name="PISI"/>
|
|
||||||
</start>
|
|
||||||
|
|
||||||
<!-- PISI Section -->
|
|
||||||
<define name="PISI">
|
|
||||||
<element name="PISI">
|
|
||||||
<ref name="Source"/>
|
|
||||||
<oneOrMore>
|
|
||||||
<ref name="Package"/>
|
|
||||||
</oneOrMore>
|
|
||||||
<ref name="History"/>
|
|
||||||
</element>
|
|
||||||
</define>
|
|
||||||
|
|
||||||
<!-- Source Section -->
|
|
||||||
<define name="Source">
|
|
||||||
<element name="Source">
|
|
||||||
<ref name="Name"/>
|
|
||||||
<ref name="Homepage"/>
|
|
||||||
<ref name="Packager"/>
|
|
||||||
<oneOrMore>
|
|
||||||
<ref name="License"/>
|
|
||||||
</oneOrMore>
|
|
||||||
<optional>
|
|
||||||
<ref name="Icon"/>
|
|
||||||
</optional>
|
|
||||||
<zeroOrMore>
|
|
||||||
<ref name="IsA"/>
|
|
||||||
</zeroOrMore>
|
|
||||||
<optional>
|
|
||||||
<ref name="PartOf"/>
|
|
||||||
</optional>
|
|
||||||
<oneOrMore>
|
|
||||||
<ref name="Summary"/>
|
|
||||||
</oneOrMore>
|
|
||||||
<zeroOrMore>
|
|
||||||
<!-- FIXME: should be oneOrMore -->
|
|
||||||
<ref name="Description"/>
|
|
||||||
</zeroOrMore>
|
|
||||||
<ref name="Archive"/>
|
|
||||||
<optional>
|
|
||||||
<ref name="BuildDependencies"/>
|
|
||||||
</optional>
|
|
||||||
<optional>
|
|
||||||
<ref name="Patches"/>
|
|
||||||
</optional>
|
|
||||||
</element>
|
|
||||||
</define>
|
|
||||||
|
|
||||||
<!-- Package Section -->
|
|
||||||
<define name="Package">
|
|
||||||
<element name="Package">
|
|
||||||
<ref name="Name"/>
|
|
||||||
<optional>
|
|
||||||
<ref name="License"/>
|
|
||||||
</optional>
|
|
||||||
<zeroOrMore>
|
|
||||||
<ref name="IsA"/>
|
|
||||||
</zeroOrMore>
|
|
||||||
<optional>
|
|
||||||
<ref name="PartOf"/>
|
|
||||||
</optional>
|
|
||||||
<zeroOrMore>
|
|
||||||
<ref name="Summary"/>
|
|
||||||
</zeroOrMore>
|
|
||||||
<zeroOrMore>
|
|
||||||
<ref name="Description"/>
|
|
||||||
</zeroOrMore>
|
|
||||||
<optional>
|
|
||||||
<ref name="RuntimeDependencies"/>
|
|
||||||
</optional>
|
|
||||||
<optional>
|
|
||||||
<ref name="Conflicts"/>
|
|
||||||
</optional>
|
|
||||||
<optional>
|
|
||||||
<ref name="Replaces"/>
|
|
||||||
</optional>
|
|
||||||
<ref name="Files"/>
|
|
||||||
<optional>
|
|
||||||
<ref name="AdditionalFiles"/>
|
|
||||||
</optional>
|
|
||||||
<optional>
|
|
||||||
<ref name="Provides"/>
|
|
||||||
</optional>
|
|
||||||
</element>
|
|
||||||
</define>
|
|
||||||
|
|
||||||
<!-- History Section -->
|
|
||||||
<define name="History">
|
|
||||||
<element name="History">
|
|
||||||
<oneOrMore>
|
|
||||||
<ref name="Update"/>
|
|
||||||
</oneOrMore>
|
|
||||||
</element>
|
|
||||||
</define>
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Name -->
|
|
||||||
<define name="Name">
|
|
||||||
<element name="Name">
|
|
||||||
<data type="string" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
|
|
||||||
<param name="pattern">[0-9a-zA-Z\-_+]*</param>
|
|
||||||
<param name="maxLength">255</param>
|
|
||||||
</data>
|
|
||||||
</element>
|
|
||||||
</define>
|
|
||||||
|
|
||||||
<!-- Homepage -->
|
|
||||||
<define name="Homepage">
|
|
||||||
<element name="Homepage">
|
|
||||||
<text/>
|
|
||||||
</element>
|
|
||||||
</define>
|
|
||||||
|
|
||||||
<!-- Icon -->
|
|
||||||
<define name="Icon">
|
|
||||||
<element name="Icon">
|
|
||||||
<text/>
|
|
||||||
</element>
|
|
||||||
</define>
|
|
||||||
|
|
||||||
<!-- Packager -->
|
|
||||||
<define name="Packager">
|
|
||||||
<element name="Packager">
|
|
||||||
<ref name="Packager.Name"/>
|
|
||||||
<ref name="Email"/>
|
|
||||||
</element>
|
|
||||||
</define>
|
|
||||||
|
|
||||||
<!-- Packager.Name -->
|
|
||||||
<define name="Packager.Name">
|
|
||||||
<element name="Name">
|
|
||||||
<data type="string" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
|
|
||||||
<param name="maxLength">255</param>
|
|
||||||
</data>
|
|
||||||
</element>
|
|
||||||
</define>
|
|
||||||
|
|
||||||
<!-- Email -->
|
|
||||||
<define name="Email">
|
|
||||||
<element name="Email">
|
|
||||||
<text/>
|
|
||||||
</element>
|
|
||||||
</define>
|
|
||||||
|
|
||||||
<!-- License -->
|
|
||||||
<define name="License">
|
|
||||||
<element name="License">
|
|
||||||
<text/>
|
|
||||||
</element>
|
|
||||||
</define>
|
|
||||||
|
|
||||||
<!-- IsA -->
|
|
||||||
<define name="IsA">
|
|
||||||
<element name="IsA">
|
|
||||||
<choice>
|
|
||||||
<value>app</value>
|
|
||||||
<value>app:console</value>
|
|
||||||
<value>app:gui</value>
|
|
||||||
<value>app:web</value>
|
|
||||||
<value>library</value>
|
|
||||||
<value>service</value>
|
|
||||||
<value>data</value>
|
|
||||||
<value>data:doc</value>
|
|
||||||
<value>data:font</value>
|
|
||||||
<value>kernel</value>
|
|
||||||
<value>driver</value>
|
|
||||||
<value>locale</value>
|
|
||||||
<value>locale:tr</value>
|
|
||||||
<value>locale:en</value>
|
|
||||||
<value>locale:es</value>
|
|
||||||
<value>locale:nl</value>
|
|
||||||
<value>locale:fr</value>
|
|
||||||
<value>locale:de</value>
|
|
||||||
<value>locale:it</value>
|
|
||||||
</choice>
|
|
||||||
</element>
|
|
||||||
</define>
|
|
||||||
|
|
||||||
<!-- PartOf -->
|
|
||||||
<define name="PartOf">
|
|
||||||
<element name="PartOf">
|
|
||||||
<text/>
|
|
||||||
</element>
|
|
||||||
</define>
|
|
||||||
|
|
||||||
<!-- Summary -->
|
|
||||||
<define name="Summary">
|
|
||||||
<element name="Summary">
|
|
||||||
<ref name="attlist.Summary"/>
|
|
||||||
<text/>
|
|
||||||
</element>
|
|
||||||
</define>
|
|
||||||
<!-- attlist.Summary -->
|
|
||||||
<define name="attlist.Summary" combine="interleave">
|
|
||||||
<optional>
|
|
||||||
<attribute name="xml:lang"/>
|
|
||||||
</optional>
|
|
||||||
</define>
|
|
||||||
|
|
||||||
<!-- Description -->
|
|
||||||
<define name="Description">
|
|
||||||
<element name="Description">
|
|
||||||
<ref name="attlist.Description"/>
|
|
||||||
<text/>
|
|
||||||
</element>
|
|
||||||
</define>
|
|
||||||
<!-- attlist.Description -->
|
|
||||||
<define name="attlist.Description" combine="interleave">
|
|
||||||
<optional>
|
|
||||||
<attribute name="xml:lang"/>
|
|
||||||
</optional>
|
|
||||||
</define>
|
|
||||||
|
|
||||||
<!-- Archive -->
|
|
||||||
<define name="Archive">
|
|
||||||
<element name="Archive">
|
|
||||||
<ref name="attlist.Archive"/>
|
|
||||||
<text/>
|
|
||||||
</element>
|
|
||||||
</define>
|
|
||||||
<!-- attlist.Archive -->
|
|
||||||
<define name="attlist.Archive" combine="interleave">
|
|
||||||
<group>
|
|
||||||
<attribute name="sha1sum"/>
|
|
||||||
<attribute name="type">
|
|
||||||
<choice>
|
|
||||||
<value>targz</value>
|
|
||||||
<value>tarbz2</value>
|
|
||||||
<value>tarlzma</value>
|
|
||||||
<value>tar</value>
|
|
||||||
<value>zip</value>
|
|
||||||
<value>gzip</value>
|
|
||||||
<value>binary</value>
|
|
||||||
</choice>
|
|
||||||
</attribute>
|
|
||||||
</group>
|
|
||||||
</define>
|
|
||||||
|
|
||||||
<!-- BuildDependencies -->
|
|
||||||
<define name="BuildDependencies">
|
|
||||||
<element name="BuildDependencies">
|
|
||||||
<oneOrMore>
|
|
||||||
<ref name="Dependency"/>
|
|
||||||
</oneOrMore>
|
|
||||||
</element>
|
|
||||||
</define>
|
|
||||||
|
|
||||||
<!-- Dependency -->
|
|
||||||
<define name="Dependency">
|
|
||||||
<element name="Dependency">
|
|
||||||
<ref name="attlist.VersionReleaseToFrom"/>
|
|
||||||
<text/>
|
|
||||||
</element>
|
|
||||||
</define>
|
|
||||||
|
|
||||||
<!-- attlist.VersionReleaseToFrom -->
|
|
||||||
<define name="attlist.VersionReleaseToFrom">
|
|
||||||
<group>
|
|
||||||
<optional>
|
|
||||||
<attribute name="versionFrom"/>
|
|
||||||
</optional>
|
|
||||||
<optional>
|
|
||||||
<attribute name="versionTo"/>
|
|
||||||
</optional>
|
|
||||||
<optional>
|
|
||||||
<attribute name="version"/>
|
|
||||||
</optional>
|
|
||||||
<optional>
|
|
||||||
<attribute name="releaseFrom"/>
|
|
||||||
</optional>
|
|
||||||
<optional>
|
|
||||||
<attribute name="releaseTo"/>
|
|
||||||
</optional>
|
|
||||||
<optional>
|
|
||||||
<attribute name="release"/>
|
|
||||||
</optional>
|
|
||||||
</group>
|
|
||||||
</define>
|
|
||||||
|
|
||||||
<!-- Patches -->
|
|
||||||
<define name="Patches">
|
|
||||||
<element name="Patches">
|
|
||||||
<oneOrMore>
|
|
||||||
<ref name="Patch"/>
|
|
||||||
</oneOrMore>
|
|
||||||
</element>
|
|
||||||
</define>
|
|
||||||
|
|
||||||
<!-- Patch -->
|
|
||||||
<define name="Patch">
|
|
||||||
<element name="Patch">
|
|
||||||
<ref name="attlist.Patch"/>
|
|
||||||
<text/>
|
|
||||||
</element>
|
|
||||||
</define>
|
|
||||||
<!-- attlist.Patch -->
|
|
||||||
<define name="attlist.Patch" combine="interleave">
|
|
||||||
<group>
|
|
||||||
<optional>
|
|
||||||
<attribute name="compressionType"/>
|
|
||||||
</optional>
|
|
||||||
<optional>
|
|
||||||
<attribute name="level"/>
|
|
||||||
</optional>
|
|
||||||
<optional>
|
|
||||||
<attribute name="target"/>
|
|
||||||
</optional>
|
|
||||||
</group>
|
|
||||||
</define>
|
|
||||||
|
|
||||||
<!-- Provides -->
|
|
||||||
<define name="Provides">
|
|
||||||
<element name="Provides">
|
|
||||||
<oneOrMore>
|
|
||||||
<ref name="COMAR"/>
|
|
||||||
</oneOrMore>
|
|
||||||
</element>
|
|
||||||
</define>
|
|
||||||
|
|
||||||
<!-- COMAR -->
|
|
||||||
<define name="COMAR">
|
|
||||||
<element name="COMAR">
|
|
||||||
<ref name="attlist.COMAR"/>
|
|
||||||
<text/>
|
|
||||||
</element>
|
|
||||||
</define>
|
|
||||||
<!-- attlist.COMAR -->
|
|
||||||
<define name="attlist.COMAR">
|
|
||||||
<optional>
|
|
||||||
<attribute name="script"/>
|
|
||||||
</optional>
|
|
||||||
</define>
|
|
||||||
|
|
||||||
<!-- Conflicts -->
|
|
||||||
<define name="Conflicts">
|
|
||||||
<element name="Conflicts">
|
|
||||||
<oneOrMore>
|
|
||||||
<ref name="Conflicts.Package"/>
|
|
||||||
</oneOrMore>
|
|
||||||
</element>
|
|
||||||
</define>
|
|
||||||
|
|
||||||
<define name="Conflicts.Package">
|
|
||||||
<element name="Package">
|
|
||||||
<ref name="attlist.VersionReleaseToFrom"/>
|
|
||||||
<text />
|
|
||||||
</element>
|
|
||||||
</define>
|
|
||||||
|
|
||||||
<!-- Replaces -->
|
|
||||||
<define name="Replaces">
|
|
||||||
<element name="Replaces">
|
|
||||||
<oneOrMore>
|
|
||||||
<ref name="Replaces.Package"/>
|
|
||||||
</oneOrMore>
|
|
||||||
</element>
|
|
||||||
</define>
|
|
||||||
|
|
||||||
<define name="Replaces.Package">
|
|
||||||
<element name="Package">
|
|
||||||
<ref name="attlist.VersionReleaseToFrom"/>
|
|
||||||
<text />
|
|
||||||
</element>
|
|
||||||
</define>
|
|
||||||
|
|
||||||
<!-- AdditionalFiles -->
|
|
||||||
<define name="AdditionalFiles">
|
|
||||||
<element name="AdditionalFiles">
|
|
||||||
<oneOrMore>
|
|
||||||
<ref name="AdditionalFile"/>
|
|
||||||
</oneOrMore>
|
|
||||||
</element>
|
|
||||||
</define>
|
|
||||||
|
|
||||||
<!-- AdditionalFile -->
|
|
||||||
<define name="AdditionalFile">
|
|
||||||
<element name="AdditionalFile">
|
|
||||||
<ref name="attlist.AdditionalFile"/>
|
|
||||||
<text/>
|
|
||||||
</element>
|
|
||||||
</define>
|
|
||||||
<!-- attlist.AdditionalFile -->
|
|
||||||
<define name="attlist.AdditionalFile">
|
|
||||||
<attribute name="target"/>
|
|
||||||
<optional>
|
|
||||||
<attribute name="permission"/>
|
|
||||||
</optional>
|
|
||||||
<optional>
|
|
||||||
<attribute name="owner"/>
|
|
||||||
</optional>
|
|
||||||
</define>
|
|
||||||
|
|
||||||
<!-- RuntimeDependencies -->
|
|
||||||
<define name="RuntimeDependencies">
|
|
||||||
<element name="RuntimeDependencies">
|
|
||||||
<oneOrMore>
|
|
||||||
<ref name="Dependency"/>
|
|
||||||
</oneOrMore>
|
|
||||||
</element>
|
|
||||||
</define>
|
|
||||||
|
|
||||||
<!-- Files -->
|
|
||||||
<define name="Files">
|
|
||||||
<element name="Files">
|
|
||||||
<oneOrMore>
|
|
||||||
<ref name="Path"/>
|
|
||||||
</oneOrMore>
|
|
||||||
</element>
|
|
||||||
</define>
|
|
||||||
|
|
||||||
<!-- Path -->
|
|
||||||
<define name="Path">
|
|
||||||
<element name="Path">
|
|
||||||
<ref name="attlist.Path"/>
|
|
||||||
<text/>
|
|
||||||
</element>
|
|
||||||
</define>
|
|
||||||
<!-- attlist.Path -->
|
|
||||||
<define name="attlist.Path" combine="interleave">
|
|
||||||
<group>
|
|
||||||
<attribute name="fileType">
|
|
||||||
<choice>
|
|
||||||
<value>executable</value>
|
|
||||||
<value>library</value>
|
|
||||||
<value>data</value>
|
|
||||||
<value>config</value>
|
|
||||||
<value>doc</value>
|
|
||||||
<value>man</value>
|
|
||||||
<value>info</value>
|
|
||||||
<value>localedata</value>
|
|
||||||
<value>header</value>
|
|
||||||
</choice>
|
|
||||||
</attribute>
|
|
||||||
<optional>
|
|
||||||
<attribute name="permanent">
|
|
||||||
<choice>
|
|
||||||
<value>false</value>
|
|
||||||
<value>true</value>
|
|
||||||
</choice>
|
|
||||||
</attribute>
|
|
||||||
</optional>
|
|
||||||
</group>
|
|
||||||
</define>
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<!-- Update -->
|
|
||||||
<define name="Update">
|
|
||||||
<element name="Update">
|
|
||||||
<ref name="attlist.Update"/>
|
|
||||||
<ref name="Date"/>
|
|
||||||
<ref name="Version"/>
|
|
||||||
<ref name="Comment"/>
|
|
||||||
<ref name="Packager.Name"/>
|
|
||||||
<ref name="Email"/>
|
|
||||||
</element>
|
|
||||||
</define>
|
|
||||||
|
|
||||||
<!-- attlist.Update -->
|
|
||||||
<define name="attlist.Update" combine="interleave">
|
|
||||||
<attribute name="release"/>
|
|
||||||
<optional>
|
|
||||||
<attribute name="type">
|
|
||||||
<choice>
|
|
||||||
<value>security</value>
|
|
||||||
<value>bug</value>
|
|
||||||
</choice>
|
|
||||||
</attribute>
|
|
||||||
</optional>
|
|
||||||
</define>
|
|
||||||
|
|
||||||
<!-- Date -->
|
|
||||||
<define name="Date">
|
|
||||||
<element name="Date">
|
|
||||||
<data type="date" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"/>
|
|
||||||
</element>
|
|
||||||
</define>
|
|
||||||
|
|
||||||
<!-- Version -->
|
|
||||||
<define name="Version">
|
|
||||||
<element name="Version">
|
|
||||||
<text/>
|
|
||||||
</element>
|
|
||||||
</define>
|
|
||||||
|
|
||||||
<!-- Comment -->
|
|
||||||
<define name="Comment">
|
|
||||||
<element name="Comment">
|
|
||||||
<text/>
|
|
||||||
</element>
|
|
||||||
</define>
|
|
||||||
|
|
||||||
</grammar>
|
|
||||||
+2
-2
@@ -12,9 +12,9 @@
|
|||||||
|
|
||||||
# PiSi version
|
# PiSi version
|
||||||
|
|
||||||
__version__ = "1.1_20070305"
|
__version__ = "1.1.5"
|
||||||
|
|
||||||
__dbversion__ = "1.1_20070305"
|
__dbversion__ = "1.1.5"
|
||||||
__filesdbversion__ = "1.0.5" # yes, this is the real bottleneck
|
__filesdbversion__ = "1.0.5" # yes, this is the real bottleneck
|
||||||
|
|
||||||
__all__ = [ 'api', 'config', 'configfile', 'packagedb', 'installdb', 'search' ]
|
__all__ = [ 'api', 'config', 'configfile', 'packagedb', 'installdb', 'search' ]
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ def install(parameters = ''):
|
|||||||
|
|
||||||
for doc in DDOCS:
|
for doc in DDOCS:
|
||||||
if can_access_file(doc):
|
if can_access_file(doc):
|
||||||
pisitools.dodoc(doc)
|
dodoc(doc)
|
||||||
|
|
||||||
def run(parameters = ''):
|
def run(parameters = ''):
|
||||||
'''executes parameters with python'''
|
'''executes parameters with python'''
|
||||||
|
|||||||
+66
-112
@@ -21,19 +21,16 @@ __trans = gettext.translation('pisi', fallback=True)
|
|||||||
_ = __trans.ugettext
|
_ = __trans.ugettext
|
||||||
|
|
||||||
import pisi
|
import pisi
|
||||||
import pisi.db
|
|
||||||
import pisi.context as ctx
|
import pisi.context as ctx
|
||||||
import pisi.uri
|
import pisi.uri
|
||||||
import pisi.util
|
import pisi.util
|
||||||
import pisi.dependency as dependency
|
import pisi.dependency as dependency
|
||||||
import pisi.pgraph as pgraph
|
import pisi.pgraph as pgraph
|
||||||
import pisi.db.packagedb
|
import pisi.packagedb
|
||||||
import pisi.db.repodb
|
import pisi.repodb
|
||||||
import pisi.db.installdb
|
import pisi.installdb
|
||||||
import pisi.db.filesdb
|
import pisi.sourcedb
|
||||||
import pisi.db.componentdb
|
import pisi.lockeddbshelve as shelve
|
||||||
import pisi.db.sourcedb
|
|
||||||
import pisi.db.lockeddbshelve as shelve
|
|
||||||
import pisi.index
|
import pisi.index
|
||||||
import pisi.config
|
import pisi.config
|
||||||
import pisi.metadata
|
import pisi.metadata
|
||||||
@@ -108,12 +105,12 @@ def init(database = True, write = True,
|
|||||||
ctx.database = database
|
ctx.database = database
|
||||||
if database:
|
if database:
|
||||||
shelve.init_dbenv(write=write)
|
shelve.init_dbenv(write=write)
|
||||||
ctx.repodb = pisi.db.repodb.RepoDB()
|
ctx.repodb = pisi.repodb.init()
|
||||||
ctx.installdb = pisi.db.installdb.InstallDB()
|
ctx.installdb = pisi.installdb.init()
|
||||||
ctx.filesdb = pisi.db.filesdb.FilesDB()
|
ctx.filesdb = pisi.files.FilesDB()
|
||||||
ctx.componentdb = pisi.db.componentdb.ComponentDB()
|
ctx.componentdb = pisi.component.ComponentDB()
|
||||||
ctx.packagedb = pisi.db.packagedb.PackageDB()
|
ctx.packagedb = pisi.packagedb.init_db()
|
||||||
ctx.sourcedb = pisi.db.sourcedb.SourceDB()
|
ctx.sourcedb = pisi.sourcedb.init()
|
||||||
else:
|
else:
|
||||||
ctx.repodb = None
|
ctx.repodb = None
|
||||||
ctx.installdb = None
|
ctx.installdb = None
|
||||||
@@ -131,12 +128,9 @@ def finalize():
|
|||||||
if ctx.log:
|
if ctx.log:
|
||||||
ctx.loghandler.flush()
|
ctx.loghandler.flush()
|
||||||
ctx.log.removeHandler(ctx.loghandler)
|
ctx.log.removeHandler(ctx.loghandler)
|
||||||
if ctx.repodb != None:
|
|
||||||
ctx.repodb.close()
|
pisi.repodb.finalize()
|
||||||
ctx.repodb = None
|
pisi.installdb.finalize()
|
||||||
if ctx.installdb != None:
|
|
||||||
ctx.installdb.close()
|
|
||||||
ctx.installdb = None
|
|
||||||
if ctx.filesdb != None:
|
if ctx.filesdb != None:
|
||||||
ctx.filesdb.close()
|
ctx.filesdb.close()
|
||||||
ctx.filesdb = None
|
ctx.filesdb = None
|
||||||
@@ -144,10 +138,10 @@ def finalize():
|
|||||||
ctx.componentdb.close()
|
ctx.componentdb.close()
|
||||||
ctx.componentdb = None
|
ctx.componentdb = None
|
||||||
if ctx.packagedb:
|
if ctx.packagedb:
|
||||||
ctx.packagedb.close()
|
pisi.packagedb.finalize_db()
|
||||||
ctx.packagedb = None
|
ctx.packagedb = None
|
||||||
if ctx.sourcedb != None:
|
if ctx.sourcedb:
|
||||||
ctx.sourcedb.close()
|
pisi.sourcedb.finalize()
|
||||||
ctx.sourcedb = None
|
ctx.sourcedb = None
|
||||||
if ctx.dbenv:
|
if ctx.dbenv:
|
||||||
ctx.dbenv.close()
|
ctx.dbenv.close()
|
||||||
@@ -164,16 +158,18 @@ def list_installed():
|
|||||||
"""Return a set of installed package names."""
|
"""Return a set of installed package names."""
|
||||||
return set(ctx.installdb.list_installed())
|
return set(ctx.installdb.list_installed())
|
||||||
|
|
||||||
|
def list_replaces(repo = None):
|
||||||
|
"""Returns a dict of the replaced packages."""
|
||||||
|
return ctx.packagedb.get_replaces(repo = repo)
|
||||||
|
|
||||||
def list_available(repo = None):
|
def list_available(repo = None):
|
||||||
"""Return a set of available package names."""
|
"""Return a set of available package names."""
|
||||||
return set(ctx.packagedb.list_packages(repo = repo))
|
return set(ctx.packagedb.list_packages(repo = repo))
|
||||||
|
|
||||||
def list_upgradable():
|
def list_upgradable():
|
||||||
ignore_build = ctx.get_option('ignore_build_no')
|
return filter(pisi.operations.is_upgradable, ctx.installdb.list_installed()) + ctx.packagedb.get_replaces().keys()
|
||||||
|
|
||||||
return filter(pisi.operations.is_upgradable, ctx.installdb.list_installed())
|
def package_graph(A, repo = pisi.itembyrepodb.installed, ignore_installed = False):
|
||||||
|
|
||||||
def package_graph(A, repo = pisi.db.itembyrepodb.installed, ignore_installed = False):
|
|
||||||
"""Construct a package relations graph.
|
"""Construct a package relations graph.
|
||||||
|
|
||||||
Graph will contain all dependencies of packages A, if ignore_installed
|
Graph will contain all dependencies of packages A, if ignore_installed
|
||||||
@@ -197,7 +193,7 @@ def package_graph(A, repo = pisi.db.itembyrepodb.installed, ignore_installed = F
|
|||||||
while len(B) > 0:
|
while len(B) > 0:
|
||||||
Bp = set()
|
Bp = set()
|
||||||
for x in B:
|
for x in B:
|
||||||
pkg = get_repo_package(x, repo)
|
pkg = ctx.packagedb.get_package(x, repo)
|
||||||
#print pkg
|
#print pkg
|
||||||
for dep in pkg.runtimeDependencies():
|
for dep in pkg.runtimeDependencies():
|
||||||
if ignore_installed:
|
if ignore_installed:
|
||||||
@@ -236,24 +232,24 @@ def generate_base_upgrade(A):
|
|||||||
|
|
||||||
def generate_conflicts(A):
|
def generate_conflicts(A):
|
||||||
# returns the conflicting packages list of the to be installed packages.
|
# returns the conflicting packages list of the to be installed packages.
|
||||||
# @C: conflicting and must be removed packages list to proceed
|
# @conflicting_pkgs: conflicting and must be removed packages list to proceed
|
||||||
# @D: list of the conflicting packages _with each other_ in the to be installed list
|
# @conflicts_inorder: list of the conflicting packages _with each other_ in the to be installed list
|
||||||
# @E: dictionary that contains which package in the to be installed list conflicts
|
# @conflicting_pairs: dictionary that contains which package in the to be installed list conflicts
|
||||||
# with which packages
|
# with which packages
|
||||||
|
|
||||||
(C, D, E) = calculate_conflicts(A, ctx.packagedb)
|
(conflicting_pkgs, conflicts_inorder, conflicting_pairs) = pisi.conflict.calculate_conflicts(A, ctx.packagedb)
|
||||||
return (C, D, E)
|
return (conflicting_pkgs, conflicts_inorder, conflicting_pairs)
|
||||||
|
|
||||||
def generate_pending_order(A):
|
def generate_pending_order(A):
|
||||||
# returns pending package list in reverse topological order of dependency
|
# returns pending package list in reverse topological order of dependency
|
||||||
G_f = pgraph.PGraph(ctx.packagedb, pisi.db.itembyrepodb.installed) # construct G_f
|
G_f = pgraph.PGraph(ctx.packagedb, pisi.itembyrepodb.installed) # construct G_f
|
||||||
for x in A.keys():
|
for x in A.keys():
|
||||||
G_f.add_package(x)
|
G_f.add_package(x)
|
||||||
B = A
|
B = A
|
||||||
while len(B) > 0:
|
while len(B) > 0:
|
||||||
Bp = set()
|
Bp = set()
|
||||||
for x in B.keys():
|
for x in B.keys():
|
||||||
pkg = get_installed_package(x)
|
pkg = ctx.packagedb.get_package(x, pisi.itembyrepodb.installed)
|
||||||
for dep in pkg.runtimeDependencies():
|
for dep in pkg.runtimeDependencies():
|
||||||
if dep.package in G_f.vertices():
|
if dep.package in G_f.vertices():
|
||||||
G_f.add_dep(x, dep)
|
G_f.add_dep(x, dep)
|
||||||
@@ -321,10 +317,10 @@ def info_file(package_fn):
|
|||||||
def info_name(package_name, installed=False):
|
def info_name(package_name, installed=False):
|
||||||
"""Fetch package information for the given package."""
|
"""Fetch package information for the given package."""
|
||||||
if installed:
|
if installed:
|
||||||
package = get_installed_package(package_name)
|
package = ctx.packagedb.get_package(package_name, pisi.itembyrepodb.installed)
|
||||||
repo = None
|
repo = None
|
||||||
else:
|
else:
|
||||||
package, repo = ctx.packagedb.get_package_repo(package_name, pisi.db.itembyrepodb.repos)
|
package, repo = ctx.packagedb.get_package_repo(package_name, pisi.itembyrepodb.repos)
|
||||||
|
|
||||||
metadata = pisi.metadata.MetaData()
|
metadata = pisi.metadata.MetaData()
|
||||||
metadata.package = package
|
metadata.package = package
|
||||||
@@ -341,10 +337,10 @@ def info_name(package_name, installed=False):
|
|||||||
files = None
|
files = None
|
||||||
return metadata, files, repo
|
return metadata, files, repo
|
||||||
|
|
||||||
def search_package_terms(terms, repo = pisi.db.itembyrepodb.all):
|
def search_package_terms(terms, repo = pisi.itembyrepodb.all):
|
||||||
return search_in_packages(terms, ctx.packagedb.list_packages(repo), repo)
|
return search_in_packages(terms, ctx.packagedb.list_packages(repo), repo)
|
||||||
|
|
||||||
def search_in_packages(terms, packages, repo = pisi.db.itembyrepodb.all):
|
def search_in_packages(terms, packages, repo = pisi.itembyrepodb.all):
|
||||||
|
|
||||||
def search(package, term):
|
def search(package, term):
|
||||||
term = unicode(term).lower()
|
term = unicode(term).lower()
|
||||||
@@ -355,7 +351,7 @@ def search_in_packages(terms, packages, repo = pisi.db.itembyrepodb.all):
|
|||||||
|
|
||||||
found = []
|
found = []
|
||||||
for name in packages:
|
for name in packages:
|
||||||
pkg = get_repo_package(name, repo)
|
pkg = ctx.packagedb.get_package(name, repo)
|
||||||
if terms == filter(lambda x:search(pkg, x), terms):
|
if terms == filter(lambda x:search(pkg, x), terms):
|
||||||
found.append(name)
|
found.append(name)
|
||||||
|
|
||||||
@@ -364,14 +360,14 @@ def search_in_packages(terms, packages, repo = pisi.db.itembyrepodb.all):
|
|||||||
def check(package):
|
def check(package):
|
||||||
md, files = info(package, True)
|
md, files = info(package, True)
|
||||||
corrupt = []
|
corrupt = []
|
||||||
for file in files.list:
|
for f in files.list:
|
||||||
if file.hash and file.type != "config" \
|
if f.hash and f.type != "config" \
|
||||||
and not os.path.islink('/' + file.path):
|
and not os.path.islink('/' + f.path):
|
||||||
ctx.ui.info(_("Checking /%s ") % file.path, noln=True, verbose=True)
|
ctx.ui.info(_("Checking /%s ") % f.path, noln=True, verbose=True)
|
||||||
try:
|
try:
|
||||||
if file.hash != pisi.util.sha1_file('/' + file.path):
|
if f.hash != pisi.util.sha1_file('/' + f.path):
|
||||||
corrupt.append(file)
|
corrupt.append(f)
|
||||||
ctx.ui.error(_("\nCorrupt file: %s") % file)
|
ctx.ui.error(_("\nCorrupt file: %s") % f)
|
||||||
else:
|
else:
|
||||||
ctx.ui.info(_("OK"), verbose=True)
|
ctx.ui.info(_("OK"), verbose=True)
|
||||||
except pisi.util.FileError,e:
|
except pisi.util.FileError,e:
|
||||||
@@ -395,6 +391,23 @@ def index(dirs=None, output='pisi-index.xml', skip_sources=False, skip_signing=F
|
|||||||
index.write(output, sha1sum=True, compress=pisi.file.File.bz2, sign=pisi.file.File.detached)
|
index.write(output, sha1sum=True, compress=pisi.file.File.bz2, sign=pisi.file.File.detached)
|
||||||
ctx.ui.info(_('* Index file written'))
|
ctx.ui.info(_('* Index file written'))
|
||||||
|
|
||||||
|
def add_repo(name, indexuri, at = None):
|
||||||
|
if ctx.repodb.has_repo(name):
|
||||||
|
raise Error(_('Repo %s already present.') % name)
|
||||||
|
else:
|
||||||
|
repo = pisi.repodb.Repo(pisi.uri.URI(indexuri))
|
||||||
|
ctx.repodb.add_repo(name, repo, at = at)
|
||||||
|
ctx.ui.info(_('Repo %s added to system.') % name)
|
||||||
|
|
||||||
|
def remove_repo(name):
|
||||||
|
if ctx.repodb.has_repo(name):
|
||||||
|
ctx.repodb.remove_repo(name)
|
||||||
|
pisi.util.clean_dir(os.path.join(ctx.config.index_dir(), name))
|
||||||
|
ctx.ui.info(_('Repo %s removed from system.') % name)
|
||||||
|
else:
|
||||||
|
ctx.ui.error(_('Repository %s does not exist. Cannot remove.')
|
||||||
|
% name)
|
||||||
|
|
||||||
def list_repos():
|
def list_repos():
|
||||||
return ctx.repodb.list()
|
return ctx.repodb.list()
|
||||||
|
|
||||||
@@ -451,7 +464,7 @@ def rebuild_repo(repo):
|
|||||||
|
|
||||||
def rebuild_db(files=False):
|
def rebuild_db(files=False):
|
||||||
|
|
||||||
assert ctx.database == False
|
assert not ctx.database
|
||||||
|
|
||||||
# Bug 2596
|
# Bug 2596
|
||||||
# finds and cleans duplicate package directories under '/var/lib/pisi/package'
|
# finds and cleans duplicate package directories under '/var/lib/pisi/package'
|
||||||
@@ -502,13 +515,13 @@ def rebuild_db(files=False):
|
|||||||
percent = progress.update(processed),
|
percent = progress.update(processed),
|
||||||
info = _("Rebuilding package database"))
|
info = _("Rebuilding package database"))
|
||||||
|
|
||||||
def reload_indices(txn):
|
def reload_indices():
|
||||||
index_dir = ctx.config.index_dir()
|
index_dir = ctx.config.index_dir()
|
||||||
if os.path.exists(index_dir): # it may have been erased, or we may be upgrading from a previous version -- exa
|
if os.path.exists(index_dir): # it may have been erased, or we may be upgrading from a previous version -- exa
|
||||||
for repo in os.listdir(index_dir):
|
for repo in os.listdir(index_dir):
|
||||||
indexuri = pisi.util.join_path(ctx.config.lib_dir(), 'index', repo, 'uri')
|
indexuri = pisi.util.join_path(ctx.config.lib_dir(), 'index', repo, 'uri')
|
||||||
indexuri = open(indexuri, 'r').readline()
|
indexuri = open(indexuri, 'r').readline()
|
||||||
pisi.api.add_repository(repo, indexuri)
|
pisi.api.add_repo(repo, indexuri)
|
||||||
pisi.api.rebuild_repo(repo)
|
pisi.api.rebuild_repo(repo)
|
||||||
|
|
||||||
# check db schema versions
|
# check db schema versions
|
||||||
@@ -516,7 +529,7 @@ def rebuild_db(files=False):
|
|||||||
shelve.check_dbversion('filesdbversion', pisi.__filesdbversion__, write=False)
|
shelve.check_dbversion('filesdbversion', pisi.__filesdbversion__, write=False)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
raise
|
raise
|
||||||
except Exception, e: #FIXME: what exception could we catch here, replace with that.
|
except Exception: #FIXME: what exception could we catch here, replace with that.
|
||||||
files = True # exception means the files db version was wrong
|
files = True # exception means the files db version was wrong
|
||||||
shelve.init_dbenv(write=True, writeversion=True)
|
shelve.init_dbenv(write=True, writeversion=True)
|
||||||
destroy(files) # bye bye
|
destroy(files) # bye bye
|
||||||
@@ -532,68 +545,9 @@ def rebuild_db(files=False):
|
|||||||
clean_duplicates()
|
clean_duplicates()
|
||||||
txn = ctx.dbenv.txn_begin()
|
txn = ctx.dbenv.txn_begin()
|
||||||
reload_packages(files, txn)
|
reload_packages(files, txn)
|
||||||
reload_indices(txn)
|
reload_indices()
|
||||||
txn.commit()
|
txn.commit()
|
||||||
|
|
||||||
|
|
||||||
############################ Under Construction ##############################
|
|
||||||
|
|
||||||
### Package Database Operations ###
|
|
||||||
|
|
||||||
## Returns the package informations of the given repository
|
|
||||||
# @param name Name of the package
|
|
||||||
# @param repo Name of the repository
|
|
||||||
def get_repo_package(name, repo=pisi.db.itembyrepodb.repos):
|
|
||||||
# FIXME: * currently we return the first package in repo order
|
|
||||||
# * we should get rid of itembyrepodb enums
|
|
||||||
# * transparent transaction support
|
|
||||||
return ctx.packagedb.get_package(name, repo, txn=None)
|
|
||||||
|
|
||||||
## Returns the installed package information
|
|
||||||
# @param name Name of the package
|
|
||||||
def get_installed_package(name):
|
|
||||||
# FIXME: * we should get rid of itembyrepodb enums
|
|
||||||
# * transparent transaction support
|
|
||||||
return ctx.packagedb.get_package(name, pisi.db.itembyrepodb.installed, txn=None)
|
|
||||||
|
|
||||||
### Repo Database Operations ###
|
|
||||||
|
|
||||||
## Adds a new repository to the pisi database
|
|
||||||
# @param name Name of the repository
|
|
||||||
# @param uri Repository location
|
|
||||||
def add_repository(name, uri):
|
|
||||||
if ctx.repodb.has_repo(name):
|
|
||||||
raise Error(_('Repo %s already present.') % name)
|
|
||||||
else:
|
|
||||||
repo = pisi.db.repodb.Repo(pisi.uri.URI(uri))
|
|
||||||
ctx.repodb.add_repo(name, repo)
|
|
||||||
ctx.ui.info(_('Repo %s added to system.') % name)
|
|
||||||
|
|
||||||
## Removes an existing repository from the pisi database
|
|
||||||
# @param name Name of the repository
|
|
||||||
def remove_repository(name):
|
|
||||||
if ctx.repodb.has_repo(name):
|
|
||||||
ctx.repodb.remove_repo(name)
|
|
||||||
pisi.util.clean_dir(os.path.join(ctx.config.index_dir(), name))
|
|
||||||
ctx.ui.info(_('Repo %s removed from system.') % name)
|
|
||||||
else:
|
|
||||||
ctx.ui.error(_('Repository %s does not exist. Cannot remove.')
|
|
||||||
% name)
|
|
||||||
|
|
||||||
### Source Database Operations ###
|
|
||||||
|
|
||||||
### Component Database Operations ###
|
|
||||||
|
|
||||||
### Files Database Operations ###
|
|
||||||
|
|
||||||
### Delta Package Operations ###
|
|
||||||
|
|
||||||
## Creates a delta package from the given .pisi package paths.
|
|
||||||
# @param old_package Path of the older package
|
|
||||||
# @param new_package Path of the newer package
|
|
||||||
def create_delta_package(old_package, new_package):
|
|
||||||
pisi.delta.create_delta_package(old_package, new_package)
|
|
||||||
|
|
||||||
############# FIXME: this was a quick fix. ##############################
|
############# FIXME: this was a quick fix. ##############################
|
||||||
|
|
||||||
# api was importing other module's functions and providing them as api functions. This is wrong.
|
# api was importing other module's functions and providing them as api functions. This is wrong.
|
||||||
@@ -630,7 +584,7 @@ def upgrade_base(*args, **kw):
|
|||||||
return pisi.operations.upgrade_base(*args, **kw)
|
return pisi.operations.upgrade_base(*args, **kw)
|
||||||
|
|
||||||
def calculate_conflicts(*args, **kw):
|
def calculate_conflicts(*args, **kw):
|
||||||
return pisi.operations.calculate_conflicts(*args, **kw)
|
return pisi.conflict.calculate_conflicts(*args, **kw)
|
||||||
|
|
||||||
def reorder_base_packages(*args, **kw):
|
def reorder_base_packages(*args, **kw):
|
||||||
return pisi.operations.reorder_base_packages(*args, **kw)
|
return pisi.operations.reorder_base_packages(*args, **kw)
|
||||||
|
|||||||
+4
-3
@@ -43,11 +43,12 @@ class ArchiveBase(object):
|
|||||||
self.type = atype
|
self.type = atype
|
||||||
|
|
||||||
def unpack(self, target_dir, clean_dir = False):
|
def unpack(self, target_dir, clean_dir = False):
|
||||||
|
self.target_dir = target_dir
|
||||||
# first we check if we need to clean-up our working env.
|
# first we check if we need to clean-up our working env.
|
||||||
if os.path.exists(target_dir) and clean_dir:
|
if os.path.exists(self.target_dir) and clean_dir:
|
||||||
util.clean_dir(target_dir)
|
util.clean_dir(self.target_dir)
|
||||||
|
|
||||||
os.makedirs(target_dir)
|
os.makedirs(self.target_dir)
|
||||||
|
|
||||||
|
|
||||||
class ArchiveBinary(ArchiveBase):
|
class ArchiveBinary(ArchiveBase):
|
||||||
|
|||||||
+49
-38
@@ -15,15 +15,12 @@ import gettext
|
|||||||
__trans = gettext.translation('pisi', fallback=True)
|
__trans = gettext.translation('pisi', fallback=True)
|
||||||
_ = __trans.ugettext
|
_ = __trans.ugettext
|
||||||
|
|
||||||
import sys
|
|
||||||
import os
|
import os
|
||||||
import bsddb3.db as db
|
import bsddb3.db as db
|
||||||
import shutil
|
import shutil
|
||||||
|
|
||||||
import pisi
|
import pisi
|
||||||
import pisi.context as ctx
|
import pisi.context as ctx
|
||||||
import pisi.db.packagedb as packagedb
|
|
||||||
import pisi.dependency as dependency
|
|
||||||
import pisi.conflict
|
import pisi.conflict
|
||||||
import pisi.util as util
|
import pisi.util as util
|
||||||
import pisi.metadata
|
import pisi.metadata
|
||||||
@@ -32,6 +29,7 @@ import pisi.uri
|
|||||||
import pisi.ui
|
import pisi.ui
|
||||||
import pisi.version
|
import pisi.version
|
||||||
import pisi.delta
|
import pisi.delta
|
||||||
|
import pisi.packagedb
|
||||||
|
|
||||||
class Error(pisi.Error):
|
class Error(pisi.Error):
|
||||||
pass
|
pass
|
||||||
@@ -43,8 +41,12 @@ class NotfoundError(pisi.Error):
|
|||||||
|
|
||||||
class AtomicOperation(object):
|
class AtomicOperation(object):
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self, ignore_dep = None):
|
||||||
pass
|
#self.package = package
|
||||||
|
if ignore_dep==None:
|
||||||
|
self.ignore_dep = ctx.config.get_option('ignore_dependency')
|
||||||
|
else:
|
||||||
|
self.ignore_dep = ignore_dep
|
||||||
|
|
||||||
def run(self, package):
|
def run(self, package):
|
||||||
"perform an atomic package operation"
|
"perform an atomic package operation"
|
||||||
@@ -55,14 +57,14 @@ class Install(AtomicOperation):
|
|||||||
"Install class, provides install routines for pisi packages"
|
"Install class, provides install routines for pisi packages"
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_name(name):
|
def from_name(name, ignore_dep = None):
|
||||||
# download package and return an installer object
|
# download package and return an installer object
|
||||||
# find package in repository
|
# find package in repository
|
||||||
repo = ctx.packagedb.which_repo(name)
|
repo = ctx.packagedb.which_repo(name)
|
||||||
if repo:
|
if repo:
|
||||||
ctx.ui.info(_("Package %s found in repository %s") % (name, repo))
|
ctx.ui.info(_("Package %s found in repository %s") % (name, repo))
|
||||||
repo = ctx.repodb.get_repo(repo)
|
repo = ctx.repodb.get_repo(repo)
|
||||||
pkg = pisi.api.get_repo_package(name)
|
pkg = ctx.packagedb.get_package(name)
|
||||||
delta = None
|
delta = None
|
||||||
|
|
||||||
# Package is installed. This is an upgrade. Check delta.
|
# Package is installed. This is an upgrade. Check delta.
|
||||||
@@ -85,13 +87,13 @@ class Install(AtomicOperation):
|
|||||||
|
|
||||||
ctx.ui.info(_("Package URI: %s") % pkg_path, verbose=True)
|
ctx.ui.info(_("Package URI: %s") % pkg_path, verbose=True)
|
||||||
|
|
||||||
return Install(pkg_path)
|
return Install(pkg_path, ignore_dep)
|
||||||
else:
|
else:
|
||||||
raise Error(_("Package %s not found in any active repository.") % name)
|
raise Error(_("Package %s not found in any active repository.") % name)
|
||||||
|
|
||||||
def __init__(self, package_fname, ignore_file_conflicts = None):
|
def __init__(self, package_fname, ignore_dep = None, ignore_file_conflicts = None):
|
||||||
"initialize from a file name"
|
"initialize from a file name"
|
||||||
super(Install, self).__init__()
|
super(Install, self).__init__(ignore_dep)
|
||||||
if not ignore_file_conflicts:
|
if not ignore_file_conflicts:
|
||||||
ignore_file_conflicts = ctx.get_option('ignore_file_conflicts')
|
ignore_file_conflicts = ctx.get_option('ignore_file_conflicts')
|
||||||
self.ignore_file_conflicts = ignore_file_conflicts
|
self.ignore_file_conflicts = ignore_file_conflicts
|
||||||
@@ -145,7 +147,7 @@ class Install(AtomicOperation):
|
|||||||
# check comar
|
# check comar
|
||||||
if self.metadata.package.providesComar and ctx.comar:
|
if self.metadata.package.providesComar and ctx.comar:
|
||||||
import pisi.comariface as comariface
|
import pisi.comariface as comariface
|
||||||
com = comariface.get_comar()
|
comariface.get_comar()
|
||||||
|
|
||||||
def check_relations(self):
|
def check_relations(self):
|
||||||
# check dependencies
|
# check dependencies
|
||||||
@@ -157,15 +159,25 @@ class Install(AtomicOperation):
|
|||||||
# check if package is in database
|
# check if package is in database
|
||||||
# If it is not, put it into 3rd party packagedb
|
# If it is not, put it into 3rd party packagedb
|
||||||
if not ctx.packagedb.has_package(self.pkginfo.name):
|
if not ctx.packagedb.has_package(self.pkginfo.name):
|
||||||
ctx.packagedb.add_package(self.pkginfo, pisi.db.itembyrepodb.thirdparty)
|
ctx.packagedb.add_package(self.pkginfo, pisi.itembyrepodb.thirdparty)
|
||||||
|
|
||||||
|
# If it is explicitly specified that package conflicts with this package and also
|
||||||
|
# we passed check_conflicts tests in operations.py than this means a non-conflicting
|
||||||
|
# pkg is in "order" to be installed that has no file conflict problem with this package.
|
||||||
|
# PS: we need this because "order" generating code does not consider conflicts.
|
||||||
|
def really_conflicts(pkg):
|
||||||
|
if not self.pkginfo.conflicts:
|
||||||
|
return True
|
||||||
|
|
||||||
|
return not pkg in map(lambda x:x.package, self.pkginfo.conflicts)
|
||||||
|
|
||||||
# check file conflicts
|
# check file conflicts
|
||||||
file_conflicts = []
|
file_conflicts = []
|
||||||
for file in self.files.list:
|
for f in self.files.list:
|
||||||
if ctx.filesdb.has_file(file.path):
|
if ctx.filesdb.has_file(f.path):
|
||||||
pkg, existing_file = ctx.filesdb.get_file(file.path)
|
pkg, existing_file = ctx.filesdb.get_file(f.path)
|
||||||
dst = pisi.util.join_path(ctx.config.dest_dir(), file.path)
|
dst = pisi.util.join_path(ctx.config.dest_dir(), f.path)
|
||||||
if pkg != self.pkginfo.name and not os.path.isdir(dst):
|
if pkg != self.pkginfo.name and not os.path.isdir(dst) and really_conflicts(pkg):
|
||||||
file_conflicts.append( (pkg, existing_file) )
|
file_conflicts.append( (pkg, existing_file) )
|
||||||
if file_conflicts:
|
if file_conflicts:
|
||||||
file_conflicts_str = ""
|
file_conflicts_str = ""
|
||||||
@@ -187,6 +199,7 @@ class Install(AtomicOperation):
|
|||||||
if ctx.installdb.is_installed(pkg.name): # is this a reinstallation?
|
if ctx.installdb.is_installed(pkg.name): # is this a reinstallation?
|
||||||
|
|
||||||
#FIXME: consider REPOSITORY instead of DISTRIBUTION -- exa
|
#FIXME: consider REPOSITORY instead of DISTRIBUTION -- exa
|
||||||
|
#ipackage = ctx.packagedb.get_package(pkg.name, pisi.itembyrepodb.installed)
|
||||||
ipkg = ctx.installdb.get_info(pkg.name)
|
ipkg = ctx.installdb.get_info(pkg.name)
|
||||||
repomismatch = ipkg.distribution != pkg.distribution
|
repomismatch = ipkg.distribution != pkg.distribution
|
||||||
|
|
||||||
@@ -273,8 +286,8 @@ class Install(AtomicOperation):
|
|||||||
fpath = pisi.util.join_path(ctx.config.dest_dir(), config.path)
|
fpath = pisi.util.join_path(ctx.config.dest_dir(), config.path)
|
||||||
if os.path.exists(fpath) and not os.path.isdir(fpath):
|
if os.path.exists(fpath) and not os.path.isdir(fpath):
|
||||||
if os.path.islink(fpath):
|
if os.path.islink(fpath):
|
||||||
file = os.readlink(fpath)
|
f = os.readlink(fpath)
|
||||||
if os.path.exists(file) and pisi.util.sha1_data(file) != config.hash:
|
if os.path.exists(f) and pisi.util.sha1_data(f) != config.hash:
|
||||||
changed = True
|
changed = True
|
||||||
else:
|
else:
|
||||||
if pisi.util.sha1_file(fpath) != config.hash:
|
if pisi.util.sha1_file(fpath) != config.hash:
|
||||||
@@ -332,8 +345,8 @@ class Install(AtomicOperation):
|
|||||||
|
|
||||||
# remove left over files from the old package.
|
# remove left over files from the old package.
|
||||||
def clean_leftovers():
|
def clean_leftovers():
|
||||||
new = set(map(lambda x: str(x.path), self.files.list))
|
new = set(str(f.path) for f in self.files.list)
|
||||||
old = set(map(lambda x: str(x.path), self.old_files.list))
|
old = set(str(f.path) for f in self.old_files.list)
|
||||||
leftover = old - new
|
leftover = old - new
|
||||||
old_fileinfo = {}
|
old_fileinfo = {}
|
||||||
for fileinfo in self.old_files.list:
|
for fileinfo in self.old_files.list:
|
||||||
@@ -347,19 +360,19 @@ class Install(AtomicOperation):
|
|||||||
old = filter(lambda x: x.type == 'config', self.old_files.list)
|
old = filter(lambda x: x.type == 'config', self.old_files.list)
|
||||||
|
|
||||||
# get config path lists
|
# get config path lists
|
||||||
newconfig = set(map(lambda x: str(x.path), new))
|
newconfig = set(str(x.path) for x in new)
|
||||||
oldconfig = set(map(lambda x: str(x.path), old))
|
oldconfig = set(str(x.path) for x in old)
|
||||||
|
|
||||||
config_overlaps = newconfig & oldconfig
|
config_overlaps = newconfig & oldconfig
|
||||||
if config_overlaps:
|
if config_overlaps:
|
||||||
files = filter(lambda x: x.path in config_overlaps, old)
|
files = filter(lambda x: x.path in config_overlaps, old)
|
||||||
for file in files:
|
for f in files:
|
||||||
check_config_changed(file)
|
check_config_changed(f)
|
||||||
else:
|
else:
|
||||||
for file in self.files.list:
|
for f in self.files.list:
|
||||||
if file.type == 'config':
|
if f.type == 'config':
|
||||||
# there may be left over config files
|
# there may be left over config files
|
||||||
check_config_changed(file)
|
check_config_changed(f)
|
||||||
|
|
||||||
if self.package_fname.endswith(ctx.const.delta_package_suffix):
|
if self.package_fname.endswith(ctx.const.delta_package_suffix):
|
||||||
relocate_files()
|
relocate_files()
|
||||||
@@ -369,9 +382,6 @@ class Install(AtomicOperation):
|
|||||||
if config_changed:
|
if config_changed:
|
||||||
rename_configs()
|
rename_configs()
|
||||||
|
|
||||||
if self.package_fname.endswith(ctx.const.delta_package_suffix):
|
|
||||||
relocate_files()
|
|
||||||
|
|
||||||
if self.reinstall:
|
if self.reinstall:
|
||||||
clean_leftovers()
|
clean_leftovers()
|
||||||
|
|
||||||
@@ -414,7 +424,7 @@ class Install(AtomicOperation):
|
|||||||
ctx.filesdb.add_files(self.metadata.package.name, self.files, txn=txn)
|
ctx.filesdb.add_files(self.metadata.package.name, self.files, txn=txn)
|
||||||
|
|
||||||
# installed packages
|
# installed packages
|
||||||
ctx.packagedb.add_package(self.pkginfo, pisi.db.itembyrepodb.installed, txn=txn)
|
ctx.packagedb.add_package(self.pkginfo, pisi.itembyrepodb.installed, txn=txn)
|
||||||
|
|
||||||
|
|
||||||
def install_single(pkg, upgrade = False):
|
def install_single(pkg, upgrade = False):
|
||||||
@@ -440,10 +450,10 @@ def install_single_name(name, upgrade = False):
|
|||||||
|
|
||||||
class Remove(AtomicOperation):
|
class Remove(AtomicOperation):
|
||||||
|
|
||||||
def __init__(self, package_name):
|
def __init__(self, package_name, ignore_dep = None):
|
||||||
super(Remove, self).__init__()
|
super(Remove, self).__init__(ignore_dep)
|
||||||
self.package_name = package_name
|
self.package_name = package_name
|
||||||
self.package = pisi.api.get_installed_package(self.package_name)
|
self.package = ctx.packagedb.get_package(self.package_name, pisi.itembyrepodb.installed)
|
||||||
try:
|
try:
|
||||||
self.files = ctx.installdb.files(self.package_name)
|
self.files = ctx.installdb.files(self.package_name)
|
||||||
except pisi.Error, e:
|
except pisi.Error, e:
|
||||||
@@ -509,7 +519,7 @@ class Remove(AtomicOperation):
|
|||||||
try:
|
try:
|
||||||
if pisi.util.sha1_file(fpath) == fileinfo.hash:
|
if pisi.util.sha1_file(fpath) == fileinfo.hash:
|
||||||
os.unlink(fpath)
|
os.unlink(fpath)
|
||||||
except pisi.util.FileError, e:
|
except pisi.util.FileError:
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
if os.path.isfile(fpath) or os.path.islink(fpath):
|
if os.path.isfile(fpath) or os.path.islink(fpath):
|
||||||
@@ -541,7 +551,8 @@ class Remove(AtomicOperation):
|
|||||||
def remove_db(self, txn):
|
def remove_db(self, txn):
|
||||||
ctx.installdb.remove(self.package_name, txn)
|
ctx.installdb.remove(self.package_name, txn)
|
||||||
ctx.filesdb.remove_files(self.files, txn)
|
ctx.filesdb.remove_files(self.files, txn)
|
||||||
pisi.db.packagedb.remove_tracking_package(self.package_name, txn)
|
# FIXME: something goes wrong here, if we use ctx operations ends up with segmentation fault!
|
||||||
|
pisi.packagedb.remove_tracking_package(self.package_name, txn)
|
||||||
|
|
||||||
|
|
||||||
def remove_single(package_name):
|
def remove_single(package_name):
|
||||||
@@ -568,7 +579,7 @@ def virtual_install(metadata, files, txn):
|
|||||||
ctx.filesdb.add_files(metadata.package.name, files, txn=txn)
|
ctx.filesdb.add_files(metadata.package.name, files, txn=txn)
|
||||||
|
|
||||||
# installed packages
|
# installed packages
|
||||||
ctx.packagedb.add_package(metadata.package, pisi.db.itembyrepodb.installed, txn=txn)
|
ctx.packagedb.add_package(metadata.package, pisi.itembyrepodb.installed, txn=txn)
|
||||||
|
|
||||||
def resurrect_package(package_fn, write_files, txn = None):
|
def resurrect_package(package_fn, write_files, txn = None):
|
||||||
"""Resurrect the package from xml files"""
|
"""Resurrect the package from xml files"""
|
||||||
|
|||||||
+98
-72
@@ -13,7 +13,6 @@
|
|||||||
|
|
||||||
# python standard library
|
# python standard library
|
||||||
import os
|
import os
|
||||||
import sys
|
|
||||||
import glob
|
import glob
|
||||||
import copy
|
import copy
|
||||||
import stat
|
import stat
|
||||||
@@ -129,6 +128,8 @@ class Builder:
|
|||||||
else:
|
else:
|
||||||
self.specdir = os.path.dirname(self.specuri.get_uri())
|
self.specdir = os.path.dirname(self.specuri.get_uri())
|
||||||
|
|
||||||
|
self.read_translations(self.specdir)
|
||||||
|
|
||||||
self.sourceArchive = pisi.sourcearchive.SourceArchive(self.spec, self.pkg_work_dir())
|
self.sourceArchive = pisi.sourcearchive.SourceArchive(self.spec, self.pkg_work_dir())
|
||||||
|
|
||||||
self.set_environment_vars()
|
self.set_environment_vars()
|
||||||
@@ -142,9 +143,12 @@ class Builder:
|
|||||||
specuri = pisi.uri.URI(os.path.realpath(specuri.get_uri())) # FIXME: doesn't work for file://
|
specuri = pisi.uri.URI(os.path.realpath(specuri.get_uri())) # FIXME: doesn't work for file://
|
||||||
self.specuri = specuri
|
self.specuri = specuri
|
||||||
spec = pisi.specfile.SpecFile()
|
spec = pisi.specfile.SpecFile()
|
||||||
spec.read(specuri, ctx.config.tmp_dir())
|
spec.read(self.specuri, ctx.config.tmp_dir())
|
||||||
self.spec = spec
|
self.spec = spec
|
||||||
|
|
||||||
|
def read_translations(self, specdir):
|
||||||
|
self.spec.read_translations(pisi.util.join_path(specdir, ctx.const.translations_file))
|
||||||
|
|
||||||
# directory accessor functions
|
# directory accessor functions
|
||||||
|
|
||||||
# pkg_x_dir: per package directory for storing info type x
|
# pkg_x_dir: per package directory for storing info type x
|
||||||
@@ -237,6 +241,7 @@ class Builder:
|
|||||||
#self.location = os.path.dirname(self.url.uri)
|
#self.location = os.path.dirname(self.url.uri)
|
||||||
|
|
||||||
self.fetch_actionsfile()
|
self.fetch_actionsfile()
|
||||||
|
self.fetch_translationsfile()
|
||||||
self.fetch_patches()
|
self.fetch_patches()
|
||||||
self.fetch_comarfiles()
|
self.fetch_comarfiles()
|
||||||
self.fetch_additionalFiles()
|
self.fetch_additionalFiles()
|
||||||
@@ -247,6 +252,14 @@ class Builder:
|
|||||||
actionsuri = pisi.util.join_path(self.specdiruri, ctx.const.actions_file)
|
actionsuri = pisi.util.join_path(self.specdiruri, ctx.const.actions_file)
|
||||||
self.download(actionsuri, self.destdir)
|
self.download(actionsuri, self.destdir)
|
||||||
|
|
||||||
|
def fetch_translationsfile(self):
|
||||||
|
translationsuri = pisi.util.join_path(self.specdiruri, ctx.const.translations_file)
|
||||||
|
try:
|
||||||
|
self.download(translationsuri, self.destdir)
|
||||||
|
except pisi.fetcher.FetchError:
|
||||||
|
# translations.xml is not mandatory for PiSi
|
||||||
|
pass
|
||||||
|
|
||||||
def fetch_patches(self):
|
def fetch_patches(self):
|
||||||
spec = self.spec
|
spec = self.spec
|
||||||
for patch in spec.source.patches:
|
for patch in spec.source.patches:
|
||||||
@@ -402,6 +415,9 @@ class Builder:
|
|||||||
|
|
||||||
return pisi.util.join_path(self.pkg_work_dir(), workdir)
|
return pisi.util.join_path(self.pkg_work_dir(), workdir)
|
||||||
|
|
||||||
|
def log_sandbox_violation(self, operation, path, canonical_path):
|
||||||
|
ctx.ui.error(_("Sandbox violation: %s (%s -> %s)") % (operation, path, canonical_path))
|
||||||
|
|
||||||
def run_action_function(self, func, mandatory=False):
|
def run_action_function(self, func, mandatory=False):
|
||||||
"""Calls the corresponding function in actions.py.
|
"""Calls the corresponding function in actions.py.
|
||||||
|
|
||||||
@@ -412,12 +428,32 @@ class Builder:
|
|||||||
curDir = os.getcwd()
|
curDir = os.getcwd()
|
||||||
os.chdir(self.srcDir)
|
os.chdir(self.srcDir)
|
||||||
|
|
||||||
|
|
||||||
if func in self.actionLocals:
|
if func in self.actionLocals:
|
||||||
self.actionLocals[func]()
|
if ctx.get_option('ignore_sandbox'):
|
||||||
|
self.actionLocals[func]()
|
||||||
|
else:
|
||||||
|
import catbox
|
||||||
|
# stupid autoconf family needs /usr/lib/conftest* and /usr/lib/cf* for some conftest,
|
||||||
|
# http://sources.gentoo.org/viewcvs.py/portage/trunk/sandbox/files/sandbox/sandbox.c also permits these
|
||||||
|
valid_dirs = [self.pkg_dir(), "/tmp/", "/var/tmp/", "/dev/tty", "/dev/pts/", "/dev/pty", "/dev/null", "/dev/zero", "/dev/ptmx", "/proc/", "/usr/lib/conftest", "/usr/lib/cf"]
|
||||||
|
if ctx.config.values.build.buildhelper == "ccache":
|
||||||
|
valid_dirs.append("%s/.ccache" % os.environ["HOME"])
|
||||||
|
# every qt/KDE application check these
|
||||||
|
valid_dirs.append("%s/.qt/.qt_plugins_3.3rc.lock" % os.environ["HOME"])
|
||||||
|
valid_dirs.append("%s/.qt/qt_plugins_3.3rc.tmp" % os.environ["HOME"])
|
||||||
|
valid_dirs.append("%s/.qt/.qtrc.lock" % os.environ["HOME"])
|
||||||
|
valid_dirs.append("%s/.qt/.qt_designerrc.lock" % os.environ["HOME"])
|
||||||
|
valid_dirs.append("/usr/qt/3/etc/settings/.qt_plugins_3.3rc.lock")
|
||||||
|
valid_dirs.append("/usr/qt/3/etc/settings/qt_plugins_3.3rc.tmp")
|
||||||
|
valid_dirs.append("/usr/qt/3/etc/settings/qt_plugins_3.3rc")
|
||||||
|
ret = catbox.run(self.actionLocals[func], valid_dirs, logger=self.log_sandbox_violation)
|
||||||
|
if ret.code == 1:
|
||||||
|
raise RuntimeError
|
||||||
|
if ret.violations != []:
|
||||||
|
ctx.ui.error(_("Sandbox violations!"))
|
||||||
else:
|
else:
|
||||||
if mandatory:
|
if mandatory:
|
||||||
Error, _("unable to call function from actions: %s") %func
|
raise Error(_("unable to call function from actions: %s") % func)
|
||||||
|
|
||||||
os.chdir(curDir)
|
os.chdir(curDir)
|
||||||
return True
|
return True
|
||||||
@@ -496,6 +532,7 @@ class Builder:
|
|||||||
ctx.ui.action(_("* Applying patch: %s") % patch.filename)
|
ctx.ui.action(_("* Applying patch: %s") % patch.filename)
|
||||||
pisi.util.do_patch(self.srcDir, patchFile, level=patch.level)
|
pisi.util.do_patch(self.srcDir, patchFile, level=patch.level)
|
||||||
return True
|
return True
|
||||||
|
return True
|
||||||
|
|
||||||
def generate_static_package_object(self):
|
def generate_static_package_object(self):
|
||||||
ar_files = []
|
ar_files = []
|
||||||
@@ -560,7 +597,7 @@ class Builder:
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
pisi.util.strip_directory(install_dir)
|
pisi.util.strip_directory(install_dir)
|
||||||
|
|
||||||
def gen_metadata_xml(self, package, build_no=None):
|
def gen_metadata_xml(self, package):
|
||||||
"""Generate the metadata.xml file for build source.
|
"""Generate the metadata.xml file for build source.
|
||||||
|
|
||||||
metadata.xml is composed of the information from specfile plus
|
metadata.xml is composed of the information from specfile plus
|
||||||
@@ -634,7 +671,16 @@ class Builder:
|
|||||||
files.write(files_xml_path)
|
files.write(files_xml_path)
|
||||||
self.files = files
|
self.files = files
|
||||||
|
|
||||||
def find_old_package_info(self, package_name):
|
def calc_build_no(self, package_name):
|
||||||
|
"""Calculate build number"""
|
||||||
|
|
||||||
|
def metadata_changed(old_metadata, new_metadata):
|
||||||
|
for key in old_metadata.package.__dict__.keys():
|
||||||
|
if old_metadata.package.__dict__[key] != new_metadata.package.__dict__[key]:
|
||||||
|
if key != "build":
|
||||||
|
return True
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
# find previous build in packages dir
|
# find previous build in packages dir
|
||||||
found = []
|
found = []
|
||||||
@@ -654,87 +700,71 @@ class Builder:
|
|||||||
ctx.ui.warning('Package file %s may be corrupt. Skipping.' % old_package_fn)
|
ctx.ui.warning('Package file %s may be corrupt. Skipping.' % old_package_fn)
|
||||||
|
|
||||||
for root, dirs, files in os.walk(ctx.config.compiled_packages_dir()):
|
for root, dirs, files in os.walk(ctx.config.compiled_packages_dir()):
|
||||||
for file in files:
|
for f in files:
|
||||||
locate_old_package(pisi.util.join_path(root,file))
|
locate_old_package(pisi.util.join_path(root,f))
|
||||||
|
|
||||||
outdir=ctx.get_option('output_dir')
|
outdir=ctx.get_option('output_dir')
|
||||||
if not outdir:
|
if not outdir:
|
||||||
outdir = '.'
|
outdir = '.'
|
||||||
for file in [pisi.util.join_path(outdir,entry) for entry in os.listdir(outdir)]:
|
for f in [pisi.util.join_path(outdir,entry) for entry in os.listdir(outdir)]:
|
||||||
if os.path.isfile(file):
|
if os.path.isfile(f):
|
||||||
locate_old_package(file)
|
locate_old_package(f)
|
||||||
|
|
||||||
if found:
|
if not found:
|
||||||
|
return (1, None)
|
||||||
|
ctx.ui.warning(_('(no previous build found, setting build no to 1.)'))
|
||||||
|
else:
|
||||||
a = filter(lambda (x,y): y != None, found)
|
a = filter(lambda (x,y): y != None, found)
|
||||||
ctx.ui.debug(str(a))
|
ctx.ui.debug(str(a))
|
||||||
|
|
||||||
if a:
|
if a:
|
||||||
# sort in order of increasing build number
|
# sort in order of increasing build number
|
||||||
a.sort(lambda x,y : cmp(x[1],y[1]))
|
a.sort(lambda x,y : cmp(x[1],y[1]))
|
||||||
old_package_fn = a[-1][0] # get the last one
|
old_package_fn = a[-1][0] # get the last one
|
||||||
old_build = a[-1][1]
|
old_build = a[-1][1]
|
||||||
return (old_package_fn, old_build)
|
|
||||||
|
|
||||||
return None
|
# compare old files.xml with the new one..
|
||||||
|
old_pkg = pisi.package.Package(old_package_fn, 'r')
|
||||||
|
old_pkg.read(pisi.util.join_path(ctx.config.tmp_dir(), 'oldpkg'))
|
||||||
|
|
||||||
def calc_build_no(self, old_package_info):
|
changed = False
|
||||||
"""Calculate build number"""
|
fnew = self.files.list
|
||||||
|
fold = old_pkg.files.list
|
||||||
|
fold.sort(lambda x,y : cmp(x.path,y.path))
|
||||||
|
fnew.sort(lambda x,y : cmp(x.path,y.path))
|
||||||
|
|
||||||
def metadata_changed(old_metadata, new_metadata):
|
if len(fnew) != len(fold):
|
||||||
for key in old_metadata.package.__dict__.keys():
|
changed = True
|
||||||
if old_metadata.package.__dict__[key] != new_metadata.package.__dict__[key]:
|
else:
|
||||||
if key != "build":
|
for i in range(len(fold)):
|
||||||
return True
|
fo = fold.pop(0)
|
||||||
|
fn = fnew.pop(0)
|
||||||
return False
|
if fo.path != fn.path:
|
||||||
|
|
||||||
if not old_package_info:
|
|
||||||
return (1, None)
|
|
||||||
ctx.ui.warning(_('(no previous build no info found, setting build no to 1.)'))
|
|
||||||
else:
|
|
||||||
old_package_fn, old_build = old_package_info
|
|
||||||
|
|
||||||
# compare old files.xml with the new one..
|
|
||||||
old_pkg = pisi.package.Package(old_package_fn, 'r')
|
|
||||||
old_pkg.read(pisi.util.join_path(ctx.config.tmp_dir(), 'oldpkg'))
|
|
||||||
|
|
||||||
changed = False
|
|
||||||
fnew = self.files.list
|
|
||||||
fold = old_pkg.files.list
|
|
||||||
fold.sort(lambda x,y : cmp(x.path,y.path))
|
|
||||||
fnew.sort(lambda x,y : cmp(x.path,y.path))
|
|
||||||
|
|
||||||
if len(fnew) != len(fold):
|
|
||||||
changed = True
|
|
||||||
else:
|
|
||||||
for i in range(len(fold)):
|
|
||||||
fo = fold.pop(0)
|
|
||||||
fn = fnew.pop(0)
|
|
||||||
if fo.path != fn.path:
|
|
||||||
changed = True
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
if fo.hash != fn.hash:
|
|
||||||
changed = True
|
changed = True
|
||||||
break
|
break
|
||||||
|
else:
|
||||||
|
if fo.hash != fn.hash:
|
||||||
|
changed = True
|
||||||
|
break
|
||||||
|
|
||||||
if metadata_changed(old_pkg.metadata, self.metadata):
|
if metadata_changed(old_pkg.metadata, self.metadata):
|
||||||
changed = True
|
changed = True
|
||||||
|
|
||||||
self.old_packages.append(os.path.basename(old_package_fn))
|
self.old_packages.append(os.path.basename(old_package_fn))
|
||||||
|
else: # no old build had a build number
|
||||||
|
old_build = None
|
||||||
|
|
||||||
ctx.ui.debug('old build number: %s' % old_build)
|
ctx.ui.debug('old build number: %s' % old_build)
|
||||||
|
|
||||||
# set build number
|
# set build number
|
||||||
if old_build is None:
|
if old_build is None:
|
||||||
ctx.ui.warning(_('(old package lacks a build no, setting build no to 1.)'))
|
ctx.ui.warning(_('(old package lacks a build no, setting build no to 1.)'))
|
||||||
return (1, None)
|
return (1, None)
|
||||||
elif changed:
|
elif changed:
|
||||||
ctx.ui.info(_('There are changes, incrementing build no to %d') % (old_build + 1))
|
ctx.ui.info(_('There are changes, incrementing build no to %d') % (old_build + 1))
|
||||||
return (old_build + 1, old_build)
|
return (old_build + 1, old_build)
|
||||||
else:
|
else:
|
||||||
ctx.ui.info(_('There is no change from previous build %d') % old_build)
|
ctx.ui.info(_('There is no change from previous build %d') % old_build)
|
||||||
return (old_build, old_build)
|
return (old_build, old_build)
|
||||||
|
|
||||||
def build_packages(self):
|
def build_packages(self):
|
||||||
"""Build each package defined in PSPEC file. After this process there
|
"""Build each package defined in PSPEC file. After this process there
|
||||||
@@ -814,16 +844,12 @@ class Builder:
|
|||||||
ctx.ui.info(_("Generating %s,") % ctx.const.metadata_xml)
|
ctx.ui.info(_("Generating %s,") % ctx.const.metadata_xml)
|
||||||
self.gen_metadata_xml(package)
|
self.gen_metadata_xml(package)
|
||||||
|
|
||||||
# find the latest build info if any with build no.
|
|
||||||
# old_package_info = (old_package_file_name, old_build_no)
|
|
||||||
old_package_info = self.find_old_package_info(package.name)
|
|
||||||
|
|
||||||
# build number
|
# build number
|
||||||
if ctx.config.options.ignore_build_no or not ctx.config.values.build.buildno:
|
if ctx.config.options.ignore_build_no or not ctx.config.values.build.buildno:
|
||||||
build_no = old_build_no = None
|
build_no = old_build_no = None
|
||||||
ctx.ui.warning(_('Build number is not available. For repo builds you must enable buildno in pisi.conf.'))
|
ctx.ui.warning(_('Build number is not available. For repo builds you must enable buildno in pisi.conf.'))
|
||||||
else:
|
else:
|
||||||
build_no, old_build_no = self.calc_build_no(old_package_info)
|
build_no, old_build_no = self.calc_build_no(package.name)
|
||||||
|
|
||||||
self.metadata.package.build = build_no
|
self.metadata.package.build = build_no
|
||||||
self.metadata.write(pisi.util.join_path(self.pkg_dir(), ctx.const.metadata_xml))
|
self.metadata.write(pisi.util.join_path(self.pkg_dir(), ctx.const.metadata_xml))
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ class CLI(pisi.ui.UI):
|
|||||||
opt = int(s)
|
opt = int(s)
|
||||||
if 1 <= opt and opt <= len(opts):
|
if 1 <= opt and opt <= len(opts):
|
||||||
return opts(opt-1)
|
return opts(opt-1)
|
||||||
except (Exception,e):
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def confirm(self, msg):
|
def confirm(self, msg):
|
||||||
|
|||||||
+37
-37
@@ -99,9 +99,9 @@ class Command(object):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def commands_string():
|
def commands_string():
|
||||||
s = ''
|
s = ''
|
||||||
list = [x.name[0] for x in Command.cmd]
|
l = [x.name[0] for x in Command.cmd]
|
||||||
list.sort()
|
l.sort()
|
||||||
for name in list:
|
for name in l:
|
||||||
commandcls = Command.cmd_dict[name]
|
commandcls = Command.cmd_dict[name]
|
||||||
trans = gettext.translation('pisi', fallback=True)
|
trans = gettext.translation('pisi', fallback=True)
|
||||||
summary = trans.ugettext(commandcls.__doc__).split('\n')[0]
|
summary = trans.ugettext(commandcls.__doc__).split('\n')[0]
|
||||||
@@ -173,12 +173,12 @@ class Command(object):
|
|||||||
|
|
||||||
# make destdir absolute
|
# make destdir absolute
|
||||||
if self.options.destdir:
|
if self.options.destdir:
|
||||||
dir = str(self.options.destdir)
|
d = str(self.options.destdir)
|
||||||
import os.path
|
import os.path
|
||||||
if not os.path.exists(dir):
|
if not os.path.exists(d):
|
||||||
pisi.cli.printu(_('Destination directory %s does not exist. Creating directory.\n') % dir)
|
pisi.cli.printu(_('Destination directory %s does not exist. Creating directory.\n') % d)
|
||||||
os.makedirs(dir)
|
os.makedirs(d)
|
||||||
self.options.destdir = os.path.realpath(dir)
|
self.options.destdir = os.path.realpath(d)
|
||||||
|
|
||||||
def check_auth_info(self):
|
def check_auth_info(self):
|
||||||
username = self.options.username
|
username = self.options.username
|
||||||
@@ -374,7 +374,7 @@ the package in graphviz format to 'pgraph.dot'.
|
|||||||
repo = ctx.get_option('repository')
|
repo = ctx.get_option('repository')
|
||||||
ctx.ui.info(_('Plotting packages in repository %s') % repo)
|
ctx.ui.info(_('Plotting packages in repository %s') % repo)
|
||||||
else:
|
else:
|
||||||
repo = pisi.db.itembyrepodb.repos
|
repo = pisi.itembyrepodb.repos
|
||||||
if self.args:
|
if self.args:
|
||||||
a = self.args
|
a = self.args
|
||||||
else:
|
else:
|
||||||
@@ -387,7 +387,7 @@ the package in graphviz format to 'pgraph.dot'.
|
|||||||
# if A is empty, then graph all packages
|
# if A is empty, then graph all packages
|
||||||
ctx.ui.info(_('Plotting a graph of relations among all installed packages'))
|
ctx.ui.info(_('Plotting a graph of relations among all installed packages'))
|
||||||
a = ctx.installdb.list_installed()
|
a = ctx.installdb.list_installed()
|
||||||
repo = pisi.db.itembyrepodb.installed
|
repo = pisi.itembyrepodb.installed
|
||||||
g = pisi.api.package_graph(a, repo = repo,
|
g = pisi.api.package_graph(a, repo = repo,
|
||||||
ignore_installed = ctx.get_option('ignore_installed'))
|
ignore_installed = ctx.get_option('ignore_installed'))
|
||||||
g.write_graphviz(file(ctx.get_option('output'), 'w'))
|
g.write_graphviz(file(ctx.get_option('output'), 'w'))
|
||||||
@@ -451,8 +451,10 @@ to be downloaded from a repository containing sources.
|
|||||||
default=False, help=_("Do not install build dependencies, fail if a build dependency is present"))
|
default=False, help=_("Do not install build dependencies, fail if a build dependency is present"))
|
||||||
group.add_option("-F", "--package-format", action="store", default='1.1',
|
group.add_option("-F", "--package-format", action="store", default='1.1',
|
||||||
help=_("PiSi binary package formats: '1.0', '1.1' (default)"))
|
help=_("PiSi binary package formats: '1.0', '1.1' (default)"))
|
||||||
group.add_option("--use-quilt", action="store_true",
|
group.add_option("--use-quilt", action="store_true", default=False,
|
||||||
default=False, help=_("Use quilt patch management system instead of GNU patch"))
|
help=_("Use quilt patch management system instead of GNU patch"))
|
||||||
|
group.add_option("--ignore-sandbox", action="store_true", default=False,
|
||||||
|
help=_("Do not constrain build process inside the build folder"))
|
||||||
|
|
||||||
def add_steps_options(self):
|
def add_steps_options(self):
|
||||||
group = OptionGroup(self.parser, _("build steps"))
|
group = OptionGroup(self.parser, _("build steps"))
|
||||||
@@ -530,7 +532,7 @@ and creates a delta pisi package with the changed files between two releases.
|
|||||||
|
|
||||||
self.init(database=False, write=False)
|
self.init(database=False, write=False)
|
||||||
|
|
||||||
if len(self.args) is not 2:
|
if len(self.args) != 2:
|
||||||
self.help()
|
self.help()
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -730,9 +732,9 @@ expanded to package names.
|
|||||||
import os
|
import os
|
||||||
|
|
||||||
patterns = []
|
patterns = []
|
||||||
file = ctx.get_option('exclude_from')
|
f = ctx.get_option('exclude_from')
|
||||||
if os.path.exists(file):
|
if os.path.exists(f):
|
||||||
for line in open(file, "r").readlines():
|
for line in open(f, "r").readlines():
|
||||||
if not line.startswith('#') and not line == '\n':
|
if not line.startswith('#') and not line == '\n':
|
||||||
patterns.append(line.strip())
|
patterns.append(line.strip())
|
||||||
if patterns:
|
if patterns:
|
||||||
@@ -752,8 +754,8 @@ expanded to package names.
|
|||||||
|
|
||||||
if not match:
|
if not match:
|
||||||
# match pattern in component names
|
# match pattern in component names
|
||||||
for cmp in fnmatch.filter(ctx.componentdb.list_components(), pattern):
|
for compare in fnmatch.filter(ctx.componentdb.list_components(), pattern):
|
||||||
packages = packages - set(ctx.componentdb.get_union_packages(cmp, walk=True))
|
packages = packages - set(ctx.componentdb.get_union_packages(compare, walk=True))
|
||||||
|
|
||||||
return list(packages)
|
return list(packages)
|
||||||
|
|
||||||
@@ -951,7 +953,7 @@ Usage: info <package1> <package2> ... <packagen>
|
|||||||
ctx.ui.info(_('[inst] '), noln=True)
|
ctx.ui.info(_('[inst] '), noln=True)
|
||||||
else:
|
else:
|
||||||
ctx.ui.info(_('Installed package:'))
|
ctx.ui.info(_('Installed package:'))
|
||||||
self.print_pkginfo(metadata, files,pisi.db.itembyrepodb.installed)
|
self.print_pkginfo(metadata, files,pisi.itembyrepodb.installed)
|
||||||
|
|
||||||
if ctx.packagedb.has_package(arg):
|
if ctx.packagedb.has_package(arg):
|
||||||
metadata, files, repo = pisi.api.info_name(arg, False)
|
metadata, files, repo = pisi.api.info_name(arg, False)
|
||||||
@@ -959,7 +961,7 @@ Usage: info <package1> <package2> ... <packagen>
|
|||||||
ctx.ui.info(_('[repo] '), noln=True)
|
ctx.ui.info(_('[repo] '), noln=True)
|
||||||
else:
|
else:
|
||||||
ctx.ui.info(_('Package found in %s repository:') % repo)
|
ctx.ui.info(_('Package found in %s repository:') % repo)
|
||||||
self.print_pkginfo(metadata, files, pisi.db.itembyrepodb.repos)
|
self.print_pkginfo(metadata, files, pisi.itembyrepodb.repos)
|
||||||
|
|
||||||
if not ctx.packagedb.has_package(arg):
|
if not ctx.packagedb.has_package(arg):
|
||||||
ctx.ui.info(_("%s is not found in repositories") % arg)
|
ctx.ui.info(_("%s is not found in repositories") % arg)
|
||||||
@@ -968,8 +970,6 @@ Usage: info <package1> <package2> ... <packagen>
|
|||||||
ctx.ui.info(_("%s is not installed") % arg)
|
ctx.ui.info(_("%s is not installed") % arg)
|
||||||
|
|
||||||
def print_pkginfo(self, metadata, files, repo = None):
|
def print_pkginfo(self, metadata, files, repo = None):
|
||||||
import os.path
|
|
||||||
|
|
||||||
if ctx.get_option('short'):
|
if ctx.get_option('short'):
|
||||||
pkg = metadata.package
|
pkg = metadata.package
|
||||||
ctx.ui.info('%15s - %s' % (pkg.name, unicode(pkg.summary)))
|
ctx.ui.info('%15s - %s' % (pkg.name, unicode(pkg.summary)))
|
||||||
@@ -1017,7 +1017,7 @@ If no packages are given, checks all installed packages.
|
|||||||
def options(self):
|
def options(self):
|
||||||
group = OptionGroup(self.parser, _("check options"))
|
group = OptionGroup(self.parser, _("check options"))
|
||||||
group.add_option("-c", "--component", action="store",
|
group.add_option("-c", "--component", action="store",
|
||||||
default=None, help=_("Check installed packages under given component"))
|
default=None, help=_("Check installed packages under given component"))
|
||||||
self.parser.add_option_group(group)
|
self.parser.add_option_group(group)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
@@ -1146,7 +1146,7 @@ Usage: list-installed
|
|||||||
ctx.ui.info(_('Package Name |St| Version| Rel.| Build| Distro| Date'))
|
ctx.ui.info(_('Package Name |St| Version| Rel.| Build| Distro| Date'))
|
||||||
print '========================================================================'
|
print '========================================================================'
|
||||||
for pkg in installed:
|
for pkg in installed:
|
||||||
package = pisi.api.get_installed_package(pkg)
|
package = ctx.packagedb.get_package(pkg, pisi.itembyrepodb.installed)
|
||||||
inst_info = ctx.installdb.get_info(pkg)
|
inst_info = ctx.installdb.get_info(pkg)
|
||||||
if self.options.long:
|
if self.options.long:
|
||||||
ctx.ui.info(unicode(package))
|
ctx.ui.info(unicode(package))
|
||||||
@@ -1273,7 +1273,7 @@ NB: We support only local files (e.g., /a/b/c) and http:// URIs at the moment
|
|||||||
else:
|
else:
|
||||||
name = 'pardus-2007'
|
name = 'pardus-2007'
|
||||||
indexuri = 'http://paketler.pardus.org.tr/pardus-2007/pisi-index.xml.bz2'
|
indexuri = 'http://paketler.pardus.org.tr/pardus-2007/pisi-index.xml.bz2'
|
||||||
pisi.api.add_repository(name, indexuri, ctx.get_option('at'))
|
pisi.api.add_repo(name, indexuri, ctx.get_option('at'))
|
||||||
if ctx.ui.confirm(_('Update PiSi database for repository %s?') % name):
|
if ctx.ui.confirm(_('Update PiSi database for repository %s?') % name):
|
||||||
try:
|
try:
|
||||||
pisi.api.update_repo(name)
|
pisi.api.update_repo(name)
|
||||||
@@ -1383,13 +1383,13 @@ all repositories.
|
|||||||
|
|
||||||
component = ctx.get_option('component')
|
component = ctx.get_option('component')
|
||||||
if component:
|
if component:
|
||||||
list = ctx.componentdb.get_packages(component, walk=True, repo=repo)
|
l = ctx.componentdb.get_packages(component, walk=True, repo=repo)
|
||||||
else:
|
else:
|
||||||
list = ctx.packagedb.list_packages(repo)
|
l = ctx.packagedb.list_packages(repo)
|
||||||
installed_list = ctx.installdb.list_installed()
|
installed_list = ctx.installdb.list_installed()
|
||||||
list.sort()
|
l.sort()
|
||||||
for p in list:
|
for p in l:
|
||||||
package = pisi.api.get_repo_package(p)
|
package = ctx.packagedb.get_package(p)
|
||||||
if self.options.long:
|
if self.options.long:
|
||||||
ctx.ui.info(unicode(package))
|
ctx.ui.info(unicode(package))
|
||||||
else:
|
else:
|
||||||
@@ -1426,9 +1426,9 @@ repositories.
|
|||||||
|
|
||||||
self.init(database = True, write = False)
|
self.init(database = True, write = False)
|
||||||
|
|
||||||
list = ctx.componentdb.list_components()
|
l = ctx.componentdb.list_components()
|
||||||
list.sort()
|
l.sort()
|
||||||
for p in list:
|
for p in l:
|
||||||
component = ctx.componentdb.get_component(p)
|
component = ctx.componentdb.get_component(p)
|
||||||
if self.options.long:
|
if self.options.long:
|
||||||
ctx.ui.info(unicode(component))
|
ctx.ui.info(unicode(component))
|
||||||
@@ -1465,9 +1465,9 @@ Gives a brief list of sources published in the repositories.
|
|||||||
|
|
||||||
self.init(database = True, write = False)
|
self.init(database = True, write = False)
|
||||||
|
|
||||||
list = ctx.sourcedb.list()
|
l = ctx.sourcedb.list()
|
||||||
list.sort()
|
l.sort()
|
||||||
for p in list:
|
for p in l:
|
||||||
sf, repo = ctx.sourcedb.get_spec_repo(p)
|
sf, repo = ctx.sourcedb.get_spec_repo(p)
|
||||||
if self.options.long:
|
if self.options.long:
|
||||||
ctx.ui.info('[Repository: ' + repo + ']')
|
ctx.ui.info('[Repository: ' + repo + ']')
|
||||||
@@ -1524,7 +1524,7 @@ Lists the packages that will be upgraded.
|
|||||||
ctx.ui.info(_('Package Name |St| Version| Rel.| Build| Distro| Date'))
|
ctx.ui.info(_('Package Name |St| Version| Rel.| Build| Distro| Date'))
|
||||||
print '========================================================================'
|
print '========================================================================'
|
||||||
for pkg in upgradable_pkgs:
|
for pkg in upgradable_pkgs:
|
||||||
package = pisi.api.get_installed_package(pkg)
|
package = ctx.packagedb.get_package(pkg, pisi.itembyrepodb.installed)
|
||||||
inst_info = ctx.installdb.get_info(pkg)
|
inst_info = ctx.installdb.get_info(pkg)
|
||||||
if self.options.long:
|
if self.options.long:
|
||||||
ctx.ui.info(package)
|
ctx.ui.info(package)
|
||||||
|
|||||||
@@ -26,9 +26,6 @@ from pisi.cli.commands import *
|
|||||||
class ParserError(pisi.Exception):
|
class ParserError(pisi.Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class Error(pisi.Error):
|
|
||||||
pass
|
|
||||||
|
|
||||||
class PreParser(OptionParser):
|
class PreParser(OptionParser):
|
||||||
"""consumes any options, and finds arguments from command line"""
|
"""consumes any options, and finds arguments from command line"""
|
||||||
|
|
||||||
|
|||||||
@@ -15,8 +15,11 @@ __trans = gettext.translation('pisi', fallback=True)
|
|||||||
_ = __trans.ugettext
|
_ = __trans.ugettext
|
||||||
|
|
||||||
import pisi
|
import pisi
|
||||||
|
import pisi.context as ctx
|
||||||
import pisi.pxml.xmlfile as xmlfile
|
import pisi.pxml.xmlfile as xmlfile
|
||||||
import pisi.pxml.autoxml as autoxml
|
import pisi.pxml.autoxml as autoxml
|
||||||
|
import pisi.lockeddbshelve as shelve
|
||||||
|
import pisi.itembyrepodb
|
||||||
|
|
||||||
class Error(pisi.Error):
|
class Error(pisi.Error):
|
||||||
pass
|
pass
|
||||||
@@ -76,4 +79,173 @@ class Component(xmlfile.XmlFile):
|
|||||||
# the parts of this component.
|
# the parts of this component.
|
||||||
# to be filled by the component database, thus it is optional.
|
# to be filled by the component database, thus it is optional.
|
||||||
t_Packages = [ [autoxml.String], autoxml.optional, "Parts/Package"]
|
t_Packages = [ [autoxml.String], autoxml.optional, "Parts/Package"]
|
||||||
|
|
||||||
t_Sources = [ [autoxml.String], autoxml.optional, "Parts/Source"]
|
t_Sources = [ [autoxml.String], autoxml.optional, "Parts/Source"]
|
||||||
|
|
||||||
|
class ComponentDB(object):
|
||||||
|
"""a database of components"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.d = pisi.itembyrepodb.ItemByRepoDB('component')
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
self.d.close()
|
||||||
|
|
||||||
|
def destroy(self):
|
||||||
|
self.d.destroy()
|
||||||
|
|
||||||
|
def has_component(self, name, repo = pisi.itembyrepodb.repos, txn = None):
|
||||||
|
name = str(name)
|
||||||
|
return self.d.has_key(name, repo, txn)
|
||||||
|
|
||||||
|
def get_component(self, name, repo=None, txn = None):
|
||||||
|
try:
|
||||||
|
return self.d.get_item(name, repo, txn=txn)
|
||||||
|
except pisi.itembyrepodb.NotfoundError, e:
|
||||||
|
raise Error(_('Component %s not found') % name)
|
||||||
|
|
||||||
|
def get_component_repo(self, name, repo=None, txn = None):
|
||||||
|
try:
|
||||||
|
return self.d.get_item_repo(name, repo, txn=txn)
|
||||||
|
except pisi.itembyrepodb.NotfoundError, e:
|
||||||
|
raise Error(_('Component %s not found') % name)
|
||||||
|
|
||||||
|
def get_union_comp(self, name, txn = None, repo = pisi.itembyrepodb.repos ):
|
||||||
|
"""get a union of all repository components packages, not just the first repo in order.
|
||||||
|
get only basic repo info from the first repo"""
|
||||||
|
def proc(txn):
|
||||||
|
s = self.d.d.get(name, txn=txn)
|
||||||
|
pkgs = set()
|
||||||
|
srcs = set()
|
||||||
|
for repostr in self.d.order(repo = repo):
|
||||||
|
if s.has_key(repostr):
|
||||||
|
pkgs |= set(s[repostr].packages)
|
||||||
|
srcs |= set(s[repostr].sources)
|
||||||
|
comp = self.get_component(name)
|
||||||
|
comp.packages = list(pkgs)
|
||||||
|
comp.sources = list(srcs)
|
||||||
|
return comp
|
||||||
|
return self.d.txn_proc(proc, txn)
|
||||||
|
|
||||||
|
def list_components(self, repo=None):
|
||||||
|
return self.d.list(repo)
|
||||||
|
|
||||||
|
# walk: walks through the underlying components' packages
|
||||||
|
def get_union_packages(self, component_name, walk=False, repo=pisi.itembyrepodb.repos, txn = None):
|
||||||
|
"""returns union of all repository component's packages, not just the first repo's
|
||||||
|
component's in order"""
|
||||||
|
|
||||||
|
component = self.get_union_comp(component_name, txn, repo)
|
||||||
|
if not walk:
|
||||||
|
return component.packages
|
||||||
|
|
||||||
|
packages = []
|
||||||
|
packages.extend(component.packages)
|
||||||
|
for dep in component.dependencies:
|
||||||
|
packages.extend(self.get_union_packages(dep, walk, repo, txn))
|
||||||
|
|
||||||
|
return packages
|
||||||
|
|
||||||
|
# walk: walks through the underlying components' packages
|
||||||
|
def get_packages(self, component_name, walk=False, repo=None, txn = None):
|
||||||
|
"""returns the given component's and underlying recursive components' packages"""
|
||||||
|
|
||||||
|
component = self.get_component(component_name, repo, txn)
|
||||||
|
if not walk:
|
||||||
|
return component.packages
|
||||||
|
|
||||||
|
packages = []
|
||||||
|
packages.extend(component.packages)
|
||||||
|
for dep in component.dependencies:
|
||||||
|
packages.extend(self.get_packages(dep, walk, repo, txn))
|
||||||
|
|
||||||
|
return packages
|
||||||
|
|
||||||
|
def add_child(self, component, repo, txn = None):
|
||||||
|
"""update component tree"""
|
||||||
|
parent_name = ".".join(component.name.split(".")[:-1])
|
||||||
|
if not parent_name: # root component
|
||||||
|
return
|
||||||
|
|
||||||
|
if self.has_component(parent_name, repo, txn):
|
||||||
|
parent = self.get_component(parent_name, repo, txn)
|
||||||
|
else:
|
||||||
|
parent = Component(name = parent_name)
|
||||||
|
|
||||||
|
if component.name not in parent.dependencies:
|
||||||
|
parent.dependencies.append(component.name)
|
||||||
|
self.d.add_item(parent_name, parent, repo, txn)
|
||||||
|
|
||||||
|
def update_component(self, component, repo, txn = None):
|
||||||
|
def proc(txn):
|
||||||
|
if self.has_component(component.name, repo, txn):
|
||||||
|
# preserve list of sources, packages and dependencies
|
||||||
|
current = self.d.get_item(component.name, repo, txn)
|
||||||
|
component.packages = current.packages
|
||||||
|
component.sources = current.sources
|
||||||
|
component.dependencies = current.dependencies
|
||||||
|
self.d.add_item(component.name, component, repo, txn)
|
||||||
|
self.add_child(component, repo, txn)
|
||||||
|
self.d.txn_proc(proc, txn)
|
||||||
|
|
||||||
|
def add_package(self, component_name, package, repo, txn = None):
|
||||||
|
def proc(txn):
|
||||||
|
assert component_name
|
||||||
|
if self.has_component(component_name, repo, txn):
|
||||||
|
component = self.get_component(component_name, repo, txn)
|
||||||
|
else:
|
||||||
|
component = Component( name = component_name )
|
||||||
|
if not package in component.packages:
|
||||||
|
component.packages.append(package)
|
||||||
|
self.d.add_item(component_name, component, repo, txn) # update
|
||||||
|
self.add_child(component, repo, txn)
|
||||||
|
self.d.txn_proc(proc, txn)
|
||||||
|
|
||||||
|
def remove_package(self, component_name, package, repo = None, txn = None):
|
||||||
|
def proc(txn, repo):
|
||||||
|
if not self.has_component(component_name, repo, txn):
|
||||||
|
raise Error(_('Information for component %s not available') % component_name)
|
||||||
|
if not repo:
|
||||||
|
repo = self.d.which_repo(component_name, txn=txn) # get default repo then
|
||||||
|
component = self.get_component(component_name, repo, txn)
|
||||||
|
if package in component.packages:
|
||||||
|
component.packages.remove(package)
|
||||||
|
self.d.add_item(component_name, component, repo, txn) # update
|
||||||
|
|
||||||
|
ctx.txn_proc(lambda x: proc(txn, repo), txn)
|
||||||
|
|
||||||
|
def add_spec(self, component_name, spec, repo, txn = None):
|
||||||
|
def proc(txn):
|
||||||
|
assert component_name
|
||||||
|
if self.has_component(component_name, repo, txn):
|
||||||
|
component = self.get_component(component_name, repo, txn)
|
||||||
|
else:
|
||||||
|
component = Component( name = component_name )
|
||||||
|
if not spec in component.sources:
|
||||||
|
component.sources.append(spec)
|
||||||
|
self.d.add_item(component_name, component, repo, txn) # update
|
||||||
|
self.add_child(component, repo, txn)
|
||||||
|
self.d.txn_proc(proc, txn)
|
||||||
|
|
||||||
|
def remove_spec(self, component_name, spec, repo = None, txn = None):
|
||||||
|
def proc(txn, repo):
|
||||||
|
if not self.has_component(component_name, repo, txn):
|
||||||
|
raise Error(_('Information for component %s not available') % component_name)
|
||||||
|
if not repo:
|
||||||
|
repo = self.d.which_repo(component_name, txn=txn) # get default repo then
|
||||||
|
component = self.get_component(component_name, repo, txn)
|
||||||
|
if spec in component.sources:
|
||||||
|
component.sources.remove(spec)
|
||||||
|
self.d.add_item(component_name, component, repo, txn) # update
|
||||||
|
|
||||||
|
ctx.txn_proc(lambda x: proc(txn, repo), txn)
|
||||||
|
|
||||||
|
def clear(self, txn = None):
|
||||||
|
self.d.clear(txn)
|
||||||
|
|
||||||
|
def remove_component(self, name, repo = None, txn = None):
|
||||||
|
name = str(name)
|
||||||
|
self.d.remove_item(name, repo, txn)
|
||||||
|
|
||||||
|
def remove_repo(self, repo, txn = None):
|
||||||
|
self.d.remove_repo(repo, txn=txn)
|
||||||
|
|||||||
+3
-3
@@ -82,9 +82,9 @@ class Config(object):
|
|||||||
return self.destdir
|
return self.destdir
|
||||||
|
|
||||||
def subdir(self, path):
|
def subdir(self, path):
|
||||||
dir = pisi.util.join_path(self.dest_dir(), path)
|
subdir = pisi.util.join_path(self.dest_dir(), path)
|
||||||
pisi.util.check_dir(dir)
|
pisi.util.check_dir(subdir)
|
||||||
return dir
|
return subdir
|
||||||
|
|
||||||
def log_dir(self):
|
def log_dir(self):
|
||||||
return self.subdir(self.values.dirs.log_dir)
|
return self.subdir(self.values.dirs.log_dir)
|
||||||
|
|||||||
+3
-3
@@ -64,9 +64,9 @@ class GeneralDefaults:
|
|||||||
autoclean = False
|
autoclean = False
|
||||||
distribution = "Pardus"
|
distribution = "Pardus"
|
||||||
distribution_release = "2007"
|
distribution_release = "2007"
|
||||||
http_proxy = (os.getenv("http_proxy") or os.getenv("HTTP_PROXY")) or None
|
http_proxy = os.getenv("HTTP_PROXY") or None
|
||||||
https_proxy = (os.getenv("https_proxy") or os.getenv("HTTPS_PROXY")) or None
|
https_proxy = os.getenv("HTTPS_PROXY") or None
|
||||||
ftp_proxy = (os.getenv("ftp_proxy") or os.getenv("FTP_PROXY")) or None
|
ftp_proxy = os.getenv("FTP_PROXY") or None
|
||||||
package_cache = False
|
package_cache = False
|
||||||
package_cache_limit = 0
|
package_cache_limit = 0
|
||||||
|
|
||||||
|
|||||||
+44
-43
@@ -16,23 +16,10 @@ import gettext
|
|||||||
__trans = gettext.translation('pisi', fallback=True)
|
__trans = gettext.translation('pisi', fallback=True)
|
||||||
_ = __trans.ugettext
|
_ = __trans.ugettext
|
||||||
|
|
||||||
import pisi.context as ctx
|
import pisi.relation
|
||||||
import pisi.version
|
|
||||||
import pisi.pxml.autoxml as autoxml
|
|
||||||
import pisi.db.itembyrepodb
|
|
||||||
|
|
||||||
class Conflict:
|
|
||||||
|
|
||||||
__metaclass__ = autoxml.autoxml
|
|
||||||
|
|
||||||
s_Package = [autoxml.String, autoxml.mandatory]
|
|
||||||
a_version = [autoxml.String, autoxml.optional]
|
|
||||||
a_versionFrom = [autoxml.String, autoxml.optional]
|
|
||||||
a_versionTo = [autoxml.String, autoxml.optional]
|
|
||||||
a_release = [autoxml.String, autoxml.optional]
|
|
||||||
a_releaseFrom = [autoxml.String, autoxml.optional]
|
|
||||||
a_releaseTo = [autoxml.String, autoxml.optional]
|
|
||||||
|
|
||||||
|
""" Conflict relation """
|
||||||
|
class Conflict(pisi.relation.Relation):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
s = self.package
|
s = self.package
|
||||||
if self.versionFrom:
|
if self.versionFrom:
|
||||||
@@ -49,39 +36,53 @@ class Conflict:
|
|||||||
s += _(" release ") + self.release
|
s += _(" release ") + self.release
|
||||||
return s
|
return s
|
||||||
|
|
||||||
def conflicts(self, pkg_name, version, release):
|
|
||||||
"""determine if a package ver. conflicts with given conflicting spec"""
|
|
||||||
ret = True
|
|
||||||
v = pisi.version.Version(version)
|
|
||||||
if self.version:
|
|
||||||
ret &= v == pisi.version.Version(self.version)
|
|
||||||
if self.versionFrom:
|
|
||||||
ret &= v >= pisi.version.Version(self.versionFrom)
|
|
||||||
if self.versionTo:
|
|
||||||
ret &= v <= pisi.version.Version(self.versionTo)
|
|
||||||
r = pisi.version.Version(release)
|
|
||||||
if self.release:
|
|
||||||
ret &= r == pisi.version.Version(self.release)
|
|
||||||
if self.releaseFrom:
|
|
||||||
ret &= r >= pisi.version.Version(self.releaseFrom)
|
|
||||||
if self.releaseTo:
|
|
||||||
ret &= r <= pisi.version.Version(self.releaseTo)
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def installed_package_conflicts(confinfo):
|
def installed_package_conflicts(confinfo):
|
||||||
"""determine if an installed package in *repository* conflicts with
|
"""determine if an installed package in *repository* conflicts with
|
||||||
given conflicting spec"""
|
given conflicting spec"""
|
||||||
pkg_name = confinfo.package
|
return pisi.relation.installed_package_satisfies(confinfo)
|
||||||
if not ctx.installdb.is_installed(pkg_name):
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
pkg = api.get_installed_package(pkg_name)
|
|
||||||
(version, release) = (pkg.version, pkg.release)
|
|
||||||
return confinfo.conflicts(pkg_name, version, release)
|
|
||||||
|
|
||||||
def package_conflicts(pkg, confs):
|
def package_conflicts(pkg, confs):
|
||||||
for c in confs:
|
for c in confs:
|
||||||
if pkg.name == c.package and c.conflicts(pkg.name, pkg.version, pkg.release):
|
if pkg.name == c.package and c.satisfies_relation(pkg.name, pkg.version, pkg.release):
|
||||||
return c
|
return c
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def calculate_conflicts(order, packagedb):
|
||||||
|
|
||||||
|
# check conflicting packages in the installed system
|
||||||
|
def check_installed(pkg, order):
|
||||||
|
conflicts = []
|
||||||
|
|
||||||
|
for conflict in pkg.conflicts:
|
||||||
|
if conflict.package not in order and installed_package_conflicts(conflict):
|
||||||
|
conflicts.append(conflict)
|
||||||
|
|
||||||
|
return conflicts
|
||||||
|
|
||||||
|
B_0 = set(order)
|
||||||
|
conflicting_pkgs = conflicts_inorder = set()
|
||||||
|
conflicting_pairs = {}
|
||||||
|
|
||||||
|
for x in order:
|
||||||
|
pkg = packagedb.get_package(x)
|
||||||
|
|
||||||
|
# check if any package has conflicts with the installed packages
|
||||||
|
conflicts = check_installed(pkg, order)
|
||||||
|
if conflicts:
|
||||||
|
conflicting_pairs[x] = map(lambda c:str(c), conflicts)
|
||||||
|
conflicting_pkgs = conflicting_pkgs.union(map(lambda c:c.package, conflicts))
|
||||||
|
|
||||||
|
# now check if any package has conflicts with each other
|
||||||
|
B_i = B_0.intersection(set(map(lambda c:c.package, pkg.conflicts)))
|
||||||
|
conflicts_inorder_i = set()
|
||||||
|
for p in map(lambda x:packagedb.get_package(x), B_i):
|
||||||
|
conflicted = package_conflicts(p, pkg.conflicts)
|
||||||
|
if conflicted:
|
||||||
|
conflicts_inorder_i.add(str(conflicted))
|
||||||
|
|
||||||
|
if conflicts_inorder_i:
|
||||||
|
conflicts_inorder = conflicts_inorder.union(conflicts_inorder_i)
|
||||||
|
conflicts_inorder.add(pkg.name)
|
||||||
|
|
||||||
|
return (conflicting_pkgs, conflicts_inorder, conflicting_pairs)
|
||||||
|
|||||||
+1
-2
@@ -18,8 +18,6 @@ import gettext
|
|||||||
__trans = gettext.translation('pisi', fallback=True)
|
__trans = gettext.translation('pisi', fallback=True)
|
||||||
_ = __trans.ugettext
|
_ = __trans.ugettext
|
||||||
|
|
||||||
import pisi
|
|
||||||
|
|
||||||
class _constant:
|
class _constant:
|
||||||
"Constant members implementation"
|
"Constant members implementation"
|
||||||
class ConstError(TypeError):
|
class ConstError(TypeError):
|
||||||
@@ -75,6 +73,7 @@ class Constants:
|
|||||||
self.__c.actions_file = "actions.py"
|
self.__c.actions_file = "actions.py"
|
||||||
self.__c.files_dir = "files"
|
self.__c.files_dir = "files"
|
||||||
self.__c.metadata_dir = "metadata"
|
self.__c.metadata_dir = "metadata"
|
||||||
|
self.__c.translations_file = "translations.xml"
|
||||||
self.__c.comar_dir = "comar"
|
self.__c.comar_dir = "comar"
|
||||||
self.__c.files_xml = "files.xml"
|
self.__c.files_xml = "files.xml"
|
||||||
self.__c.metadata_xml = "metadata.xml"
|
self.__c.metadata_xml = "metadata.xml"
|
||||||
|
|||||||
@@ -41,6 +41,9 @@ dbenv = None
|
|||||||
installdb = None
|
installdb = None
|
||||||
packagedb = None
|
packagedb = None
|
||||||
repodb = None
|
repodb = None
|
||||||
|
sourcedb = None
|
||||||
|
filesdb = None
|
||||||
|
componentdb = None
|
||||||
invidx = None
|
invidx = None
|
||||||
|
|
||||||
comar = None
|
comar = None
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
#
|
|
||||||
# Copyright (C) 2005 - 2007, TUBITAK/UEKAE
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
|
||||||
# the terms of the GNU General Public License as published by the Free
|
|
||||||
# Software Foundation; either version 2 of the License, or (at your option)
|
|
||||||
# any later version.
|
|
||||||
#
|
|
||||||
# Please read the COPYING file.
|
|
||||||
#
|
|
||||||
@@ -1,190 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
#
|
|
||||||
# Copyright (C) 2005 - 2007, TUBITAK/UEKAE
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
|
||||||
# the terms of the GNU General Public License as published by the Free
|
|
||||||
# Software Foundation; either version 2 of the License, or (at your option)
|
|
||||||
# any later version.
|
|
||||||
#
|
|
||||||
# Please read the COPYING file.
|
|
||||||
#
|
|
||||||
|
|
||||||
import types
|
|
||||||
|
|
||||||
import gettext
|
|
||||||
__trans = gettext.translation('pisi', fallback=True)
|
|
||||||
_ = __trans.ugettext
|
|
||||||
|
|
||||||
import pisi
|
|
||||||
import pisi.context as ctx
|
|
||||||
import pisi.db.itembyrepodb as itembyrepodb
|
|
||||||
import pisi.component
|
|
||||||
|
|
||||||
|
|
||||||
class ComponentDB(object):
|
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
self.d = itembyrepodb.ItemByRepoDB('component')
|
|
||||||
|
|
||||||
def close(self):
|
|
||||||
self.d.close()
|
|
||||||
|
|
||||||
def destroy(self):
|
|
||||||
self.d.destroy()
|
|
||||||
|
|
||||||
def has_component(self, name, repo = itembyrepodb.repos, txn = None):
|
|
||||||
name = str(name)
|
|
||||||
return self.d.has_key(name, repo, txn)
|
|
||||||
|
|
||||||
def get_component(self, name, repo=None, txn = None):
|
|
||||||
try:
|
|
||||||
return self.d.get_item(name, repo, txn=txn)
|
|
||||||
except itembyrepodb.NotfoundError, e:
|
|
||||||
raise Error(_('Component %s not found') % name)
|
|
||||||
|
|
||||||
def get_component_repo(self, name, repo=None, txn = None):
|
|
||||||
try:
|
|
||||||
return self.d.get_item_repo(name, repo, txn=txn)
|
|
||||||
except itembyrepodb.NotfoundError, e:
|
|
||||||
raise Error(_('Component %s not found') % name)
|
|
||||||
|
|
||||||
def get_union_comp(self, name, txn = None, repo = itembyrepodb.repos ):
|
|
||||||
"""get a union of all repository components packages, not just the first repo in order.
|
|
||||||
get only basic repo info from the first repo"""
|
|
||||||
def proc(txn):
|
|
||||||
s = self.d.d.get(name, txn=txn)
|
|
||||||
pkgs = set()
|
|
||||||
srcs = set()
|
|
||||||
for repostr in self.d.order(repo = repo):
|
|
||||||
if s.has_key(repostr):
|
|
||||||
pkgs |= set(s[repostr].packages)
|
|
||||||
srcs |= set(s[repostr].sources)
|
|
||||||
comp = self.get_component(name)
|
|
||||||
comp.packages = list(pkgs)
|
|
||||||
comp.sources = list(srcs)
|
|
||||||
return comp
|
|
||||||
return self.d.txn_proc(proc, txn)
|
|
||||||
|
|
||||||
def list_components(self, repo=None):
|
|
||||||
return self.d.list(repo)
|
|
||||||
|
|
||||||
# walk: walks through the underlying components' packages
|
|
||||||
def get_union_packages(self, component_name, walk=False, repo=pisi.db.itembyrepodb.repos, txn = None):
|
|
||||||
"""returns union of all repository component's packages, not just the first repo's
|
|
||||||
component's in order"""
|
|
||||||
|
|
||||||
component = self.get_union_comp(component_name, txn, repo)
|
|
||||||
if not walk:
|
|
||||||
return component.packages
|
|
||||||
|
|
||||||
packages = []
|
|
||||||
packages.extend(component.packages)
|
|
||||||
for dep in component.dependencies:
|
|
||||||
packages.extend(self.get_union_packages(dep, walk, repo, txn))
|
|
||||||
|
|
||||||
return packages
|
|
||||||
|
|
||||||
# walk: walks through the underlying components' packages
|
|
||||||
def get_packages(self, component_name, walk=False, repo=None, txn = None):
|
|
||||||
"""returns the given component's and underlying recursive components' packages"""
|
|
||||||
|
|
||||||
component = self.get_component(component_name, repo, txn)
|
|
||||||
if not walk:
|
|
||||||
return component.packages
|
|
||||||
|
|
||||||
packages = []
|
|
||||||
packages.extend(component.packages)
|
|
||||||
for dep in component.dependencies:
|
|
||||||
packages.extend(self.get_packages(dep, walk, repo, txn))
|
|
||||||
|
|
||||||
return packages
|
|
||||||
|
|
||||||
def add_child(self, component, repo, txn = None):
|
|
||||||
"""update component tree"""
|
|
||||||
parent_name = ".".join(component.name.split(".")[:-1])
|
|
||||||
if not parent_name: # root component
|
|
||||||
return
|
|
||||||
|
|
||||||
if self.has_component(parent_name, repo, txn):
|
|
||||||
parent = self.get_component(parent_name, repo, txn)
|
|
||||||
else:
|
|
||||||
parent = pisi.component.Component(name = parent_name)
|
|
||||||
|
|
||||||
if component.name not in parent.dependencies:
|
|
||||||
parent.dependencies.append(component.name)
|
|
||||||
self.d.add_item(parent_name, parent, repo, txn)
|
|
||||||
|
|
||||||
def update_component(self, component, repo, txn = None):
|
|
||||||
def proc(txn):
|
|
||||||
if self.has_component(component.name, repo, txn):
|
|
||||||
# preserve list of sources, packages and dependencies
|
|
||||||
current = self.d.get_item(component.name, repo, txn)
|
|
||||||
component.packages = current.packages
|
|
||||||
component.sources = current.sources
|
|
||||||
component.dependencies = current.dependencies
|
|
||||||
self.d.add_item(component.name, component, repo, txn)
|
|
||||||
self.add_child(component, repo, txn)
|
|
||||||
self.d.txn_proc(proc, txn)
|
|
||||||
|
|
||||||
def add_package(self, component_name, package, repo, txn = None):
|
|
||||||
def proc(txn):
|
|
||||||
assert component_name
|
|
||||||
if self.has_component(component_name, repo, txn):
|
|
||||||
component = self.get_component(component_name, repo, txn)
|
|
||||||
else:
|
|
||||||
component = pisi.component.Component( name = component_name )
|
|
||||||
if not package in component.packages:
|
|
||||||
component.packages.append(package)
|
|
||||||
self.d.add_item(component_name, component, repo, txn) # update
|
|
||||||
self.add_child(component, repo, txn)
|
|
||||||
self.d.txn_proc(proc, txn)
|
|
||||||
|
|
||||||
def remove_package(self, component_name, package, repo = None, txn = None):
|
|
||||||
def proc(txn, repo):
|
|
||||||
if not self.has_component(component_name, repo, txn):
|
|
||||||
raise Error(_('Information for component %s not available') % component_name)
|
|
||||||
if not repo:
|
|
||||||
repo = self.d.which_repo(component_name, txn=txn) # get default repo then
|
|
||||||
component = self.get_component(component_name, repo, txn)
|
|
||||||
if package in component.packages:
|
|
||||||
component.packages.remove(package)
|
|
||||||
self.d.add_item(component_name, component, repo, txn) # update
|
|
||||||
|
|
||||||
ctx.txn_proc(lambda x: proc(txn, repo), txn)
|
|
||||||
|
|
||||||
def add_spec(self, component_name, spec, repo, txn = None):
|
|
||||||
def proc(txn):
|
|
||||||
assert component_name
|
|
||||||
if self.has_component(component_name, repo, txn):
|
|
||||||
component = self.get_component(component_name, repo, txn)
|
|
||||||
else:
|
|
||||||
component = pisi.component.Component( name = component_name )
|
|
||||||
if not spec in component.sources:
|
|
||||||
component.sources.append(spec)
|
|
||||||
self.d.add_item(component_name, component, repo, txn) # update
|
|
||||||
self.add_child(component, repo, txn)
|
|
||||||
self.d.txn_proc(proc, txn)
|
|
||||||
|
|
||||||
def remove_spec(self, component_name, spec, repo = None, txn = None):
|
|
||||||
def proc(txn, repo):
|
|
||||||
if not self.has_component(component_name, repo, txn):
|
|
||||||
raise Error(_('Information for component %s not available') % component_name)
|
|
||||||
if not repo:
|
|
||||||
repo = self.d.which_repo(component_name, txn=txn) # get default repo then
|
|
||||||
component = self.get_component(component_name, repo, txn)
|
|
||||||
if spec in component.sources:
|
|
||||||
component.sources.remove(spec)
|
|
||||||
self.d.add_item(component_name, component, repo, txn) # update
|
|
||||||
|
|
||||||
ctx.txn_proc(lambda x: proc(txn, repo), txn)
|
|
||||||
|
|
||||||
def clear(self, txn = None):
|
|
||||||
self.d.clear(txn)
|
|
||||||
|
|
||||||
def remove_component(self, name, repo = None, txn = None):
|
|
||||||
name = str(name)
|
|
||||||
self.d.remove_item(name, repo, txn)
|
|
||||||
|
|
||||||
def remove_repo(self, repo, txn = None):
|
|
||||||
self.d.remove_repo(repo, txn=txn)
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
# -*- coding: utf-8 -*-
|
|
||||||
#
|
|
||||||
# Copyright (C) 2005 - 2007, TUBITAK/UEKAE
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify it under
|
|
||||||
# the terms of the GNU General Public License as published by the Free
|
|
||||||
# Software Foundation; either version 2 of the License, or (at your option)
|
|
||||||
# any later version.
|
|
||||||
#
|
|
||||||
# Please read the COPYING file.
|
|
||||||
#
|
|
||||||
|
|
||||||
import pisi.db.lockeddbshelve as shelve
|
|
||||||
import pisi.files
|
|
||||||
|
|
||||||
class FilesDB(shelve.LockedDBShelf):
|
|
||||||
'''
|
|
||||||
FilesDB provides db access operations for Files objects (files.Files)
|
|
||||||
'''
|
|
||||||
def __init__(self):
|
|
||||||
shelve.LockedDBShelf.__init__(self, 'files')
|
|
||||||
|
|
||||||
def add_files(self, pkg_name, files, txn = None):
|
|
||||||
def proc(txn):
|
|
||||||
for x in files.list:
|
|
||||||
path = x.path
|
|
||||||
del x.path # don't store redundant attribute in db
|
|
||||||
self.put(path, (pkg_name, x), txn)
|
|
||||||
x.path = path # store it back in
|
|
||||||
self.txn_proc(proc, txn)
|
|
||||||
|
|
||||||
def remove_files(self, files, txn = None):
|
|
||||||
def proc(txn):
|
|
||||||
for x in files.list:
|
|
||||||
if self.has_key(x.path):
|
|
||||||
self.delete(x.path, txn)
|
|
||||||
self.txn_proc(proc, txn)
|
|
||||||
|
|
||||||
def has_file(self, path, txn = None):
|
|
||||||
return self.has_key(str(path), txn)
|
|
||||||
|
|
||||||
def get_file(self, path, txn = None):
|
|
||||||
path = str(path)
|
|
||||||
def proc(txn):
|
|
||||||
if not self.has_key(path, txn):
|
|
||||||
return None
|
|
||||||
else:
|
|
||||||
(name, fileinfo) = self.get(path, txn)
|
|
||||||
fileinfo.path = path
|
|
||||||
return (name, fileinfo)
|
|
||||||
return self.txn_proc(proc, txn)
|
|
||||||
|
|
||||||
def match_files(self, glob):
|
|
||||||
# NB: avoid using, this reads the entire db
|
|
||||||
import fnmatch
|
|
||||||
glob = str(glob)
|
|
||||||
infos = []
|
|
||||||
for key in self.keys():
|
|
||||||
if fnmatch.fnmatch(key, glob):
|
|
||||||
|
|
||||||
# FIXME: Why should we assign path attribute manually
|
|
||||||
# in fileinfo? This is also done in get_file(), seems
|
|
||||||
# like a dirty workaround... - baris
|
|
||||||
name = self[key][0]
|
|
||||||
fileinfo = self[key][1]
|
|
||||||
fileinfo.path = key
|
|
||||||
infos.append((name, fileinfo))
|
|
||||||
return infos
|
|
||||||
@@ -89,7 +89,7 @@ class DBShelf:
|
|||||||
raise CodingError()
|
raise CodingError()
|
||||||
|
|
||||||
def encode(self, obj):
|
def encode(self, obj):
|
||||||
return cPickle.dumps(obj, 2)
|
return cPickle.dumps(obj, 1)
|
||||||
|
|
||||||
def clear(self, txn = None):
|
def clear(self, txn = None):
|
||||||
def proc(txn):
|
def proc(txn):
|
||||||
+20
-15
@@ -74,8 +74,8 @@ def create_delta_package(old_package, new_package):
|
|||||||
ctx.build_leftover = util.join_path(ctx.config.tmp_dir(), ctx.const.install_tar_lzma)
|
ctx.build_leftover = util.join_path(ctx.config.tmp_dir(), ctx.const.install_tar_lzma)
|
||||||
|
|
||||||
tar = archive.ArchiveTar(util.join_path(ctx.config.tmp_dir(), ctx.const.install_tar_lzma), "tarlzma")
|
tar = archive.ArchiveTar(util.join_path(ctx.config.tmp_dir(), ctx.const.install_tar_lzma), "tarlzma")
|
||||||
for file in files_delta:
|
for f in files_delta:
|
||||||
tar.add_to_archive(file.path)
|
tar.add_to_archive(f.path)
|
||||||
tar.close()
|
tar.close()
|
||||||
|
|
||||||
os.chdir(ctx.config.tmp_dir())
|
os.chdir(ctx.config.tmp_dir())
|
||||||
@@ -99,34 +99,39 @@ def create_delta_package(old_package, new_package):
|
|||||||
def find_delta(oldfiles, newfiles):
|
def find_delta(oldfiles, newfiles):
|
||||||
|
|
||||||
hashto_files = {}
|
hashto_files = {}
|
||||||
for file in newfiles.list:
|
for f in newfiles.list:
|
||||||
hashto_files.setdefault(file.hash, []).append(file)
|
hashto_files.setdefault(f.hash, []).append(f)
|
||||||
|
|
||||||
files_new = sets.Set(map(lambda x:x.hash, newfiles.list))
|
files_new = sets.Set(map(lambda x:x.hash, newfiles.list))
|
||||||
files_old = sets.Set(map(lambda x:x.hash, oldfiles.list))
|
files_old = sets.Set(map(lambda x:x.hash, oldfiles.list))
|
||||||
files_delta = files_new - files_old
|
files_delta = files_new - files_old
|
||||||
|
|
||||||
deltas = []
|
deltas = []
|
||||||
for hash in files_delta:
|
for h in files_delta:
|
||||||
deltas.extend(hashto_files[hash])
|
deltas.extend(hashto_files[h])
|
||||||
|
|
||||||
|
# Directory hashes are None. There was a bug with PolicyKit that should have an empty directory.
|
||||||
|
if hashto_files.has_key(None):
|
||||||
|
deltas.extend(hashto_files[None])
|
||||||
|
|
||||||
return deltas
|
return deltas
|
||||||
|
|
||||||
def find_relocations(oldfiles, newfiles):
|
def find_relocations(oldfiles, newfiles):
|
||||||
|
|
||||||
files_new = {}
|
files_new = {}
|
||||||
for file in newfiles.list:
|
for f in newfiles.list:
|
||||||
files_new.setdefault(file.hash, []).append(file)
|
files_new.setdefault(f.hash, []).append(f)
|
||||||
|
|
||||||
files_old = {}
|
files_old = {}
|
||||||
for file in oldfiles.list:
|
for f in oldfiles.list:
|
||||||
files_old.setdefault(file.hash, []).append(file)
|
files_old.setdefault(f.hash, []).append(f)
|
||||||
|
|
||||||
relocations = []
|
relocations = []
|
||||||
for hash in files_new.keys():
|
for h in files_new.keys():
|
||||||
if hash and hash in files_old:
|
if h and h in files_old:
|
||||||
for i in range(len(files_new[hash])):
|
old_paths = [x.path for x in files_old[h]]
|
||||||
if files_old[hash][0].path != files_new[hash][i].path:
|
for i in range(len(files_new[h])):
|
||||||
relocations.append((files_old[hash][0], files_new[hash][i]))
|
if files_new[h][i].path not in old_paths:
|
||||||
|
relocations.append((files_old[h][0], files_new[h][i]))
|
||||||
|
|
||||||
return relocations
|
return relocations
|
||||||
|
|||||||
+8
-47
@@ -16,25 +16,11 @@ import gettext
|
|||||||
__trans = gettext.translation('pisi', fallback=True)
|
__trans = gettext.translation('pisi', fallback=True)
|
||||||
_ = __trans.ugettext
|
_ = __trans.ugettext
|
||||||
|
|
||||||
import pisi
|
|
||||||
import pisi.context as ctx
|
import pisi.context as ctx
|
||||||
import pisi.db.packagedb as packagedb
|
import pisi.relation
|
||||||
import pisi.version
|
|
||||||
import pisi.pxml.autoxml as autoxml
|
|
||||||
import pisi.db.itembyrepodb
|
|
||||||
|
|
||||||
class Dependency:
|
|
||||||
|
|
||||||
__metaclass__ = autoxml.autoxml
|
|
||||||
|
|
||||||
s_Package = [autoxml.String, autoxml.mandatory]
|
|
||||||
a_version = [autoxml.String, autoxml.optional]
|
|
||||||
a_versionFrom = [autoxml.String, autoxml.optional]
|
|
||||||
a_versionTo = [autoxml.String, autoxml.optional]
|
|
||||||
a_release = [autoxml.String, autoxml.optional]
|
|
||||||
a_releaseFrom = [autoxml.String, autoxml.optional]
|
|
||||||
a_releaseTo = [autoxml.String, autoxml.optional]
|
|
||||||
|
|
||||||
|
""" Dependency relation """
|
||||||
|
class Dependency(pisi.relation.Relation):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
s = self.package
|
s = self.package
|
||||||
if self.versionFrom:
|
if self.versionFrom:
|
||||||
@@ -51,25 +37,6 @@ class Dependency:
|
|||||||
s += _(" release ") + self.release
|
s += _(" release ") + self.release
|
||||||
return s
|
return s
|
||||||
|
|
||||||
def satisfies(self, pkg_name, version, release):
|
|
||||||
"""determine if a package ver. satisfies given dependency spec"""
|
|
||||||
ret = True
|
|
||||||
v = pisi.version.Version(version)
|
|
||||||
if self.version:
|
|
||||||
ret &= v == pisi.version.Version(self.version)
|
|
||||||
if self.versionFrom:
|
|
||||||
ret &= v >= pisi.version.Version(self.versionFrom)
|
|
||||||
if self.versionTo:
|
|
||||||
ret &= v <= pisi.version.Version(self.versionTo)
|
|
||||||
r = pisi.version.Version(release)
|
|
||||||
if self.release:
|
|
||||||
ret &= r == pisi.version.Version(self.release)
|
|
||||||
if self.releaseFrom:
|
|
||||||
ret &= r >= pisi.version.Version(self.releaseFrom)
|
|
||||||
if self.releaseTo:
|
|
||||||
ret &= r <= pisi.version.Version(self.releaseTo)
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def dict_satisfies_dep(dict, depinfo):
|
def dict_satisfies_dep(dict, depinfo):
|
||||||
"""determine if a package in a dictionary satisfies given dependency spec"""
|
"""determine if a package in a dictionary satisfies given dependency spec"""
|
||||||
pkg_name = depinfo.package
|
pkg_name = depinfo.package
|
||||||
@@ -78,18 +45,12 @@ def dict_satisfies_dep(dict, depinfo):
|
|||||||
else:
|
else:
|
||||||
pkg = dict[pkg_name]
|
pkg = dict[pkg_name]
|
||||||
(version, release) = (pkg.version, pkg.release)
|
(version, release) = (pkg.version, pkg.release)
|
||||||
return depinfo.satisfies(pkg_name, version, release)
|
return depinfo.satisfies_relation(pkg_name, version, release)
|
||||||
|
|
||||||
def installed_satisfies_dep(depinfo):
|
def installed_satisfies_dep(depinfo):
|
||||||
"""determine if a package in *repository* satisfies given
|
"""determine if a package in *repository* satisfies given
|
||||||
dependency spec"""
|
dependency spec"""
|
||||||
pkg_name = depinfo.package
|
return pisi.relation.installed_package_satisfies(depinfo)
|
||||||
if not ctx.installdb.is_installed(pkg_name):
|
|
||||||
return False
|
|
||||||
else:
|
|
||||||
pkg = pisi.api.get_installed_package(pkg_name)
|
|
||||||
(version, release) = (pkg.version, pkg.release)
|
|
||||||
return depinfo.satisfies(pkg_name, version, release)
|
|
||||||
|
|
||||||
def repo_satisfies_dep(depinfo):
|
def repo_satisfies_dep(depinfo):
|
||||||
"""determine if a package in *repository* satisfies given
|
"""determine if a package in *repository* satisfies given
|
||||||
@@ -98,9 +59,9 @@ dependency spec"""
|
|||||||
if not ctx.packagedb.has_package(pkg_name):
|
if not ctx.packagedb.has_package(pkg_name):
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
pkg = pisi.api.get_repo_package(pkg_name)
|
pkg = ctx.packagedb.get_package(pkg_name)
|
||||||
(version, release) = (pkg.version, pkg.release)
|
(version, release) = (pkg.version, pkg.release)
|
||||||
return depinfo.satisfies(pkg_name, version, release)
|
return depinfo.satisfies_relation(pkg_name, version, release)
|
||||||
|
|
||||||
def satisfies_dependencies(pkg, deps, sat = installed_satisfies_dep):
|
def satisfies_dependencies(pkg, deps, sat = installed_satisfies_dep):
|
||||||
for dep in deps:
|
for dep in deps:
|
||||||
@@ -111,7 +72,7 @@ def satisfies_dependencies(pkg, deps, sat = installed_satisfies_dep):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
def satisfies_runtime_deps(pkg):
|
def satisfies_runtime_deps(pkg):
|
||||||
deps = pisi.api.get_repo_package(pkg).runtimeDependencies()
|
deps = ctx.packagedb.get_package(pkg).runtimeDependencies()
|
||||||
return satisfies_dependencies(pkg, deps)
|
return satisfies_dependencies(pkg, deps)
|
||||||
|
|
||||||
def installable(pkg):
|
def installable(pkg):
|
||||||
|
|||||||
+6
-5
@@ -282,17 +282,17 @@ class FTPRangeHandler(urllib2.FTPHandler):
|
|||||||
path, attrs = urllib.splitattr(req.get_selector())
|
path, attrs = urllib.splitattr(req.get_selector())
|
||||||
dirs = path.split('/')
|
dirs = path.split('/')
|
||||||
dirs = map(urllib.unquote, dirs)
|
dirs = map(urllib.unquote, dirs)
|
||||||
dirs, file = dirs[:-1], dirs[-1]
|
dirs, f = dirs[:-1], dirs[-1]
|
||||||
if dirs and not dirs[0]:
|
if dirs and not dirs[0]:
|
||||||
dirs = dirs[1:]
|
dirs = dirs[1:]
|
||||||
try:
|
try:
|
||||||
fw = self.connect_ftp('', '', host, port, dirs)
|
fw = self.connect_ftp('', '', host, port, dirs)
|
||||||
type = file and 'I' or 'D'
|
t = f and 'I' or 'D'
|
||||||
for attr in attrs:
|
for attr in attrs:
|
||||||
attr, value = urllib.splitattr(attr)
|
attr, value = urllib.splitattr(attr)
|
||||||
if attr.lower() == 'type' and \
|
if attr.lower() == 'type' and \
|
||||||
value in ('a', 'A', 'i', 'I', 'd', 'D'):
|
value in ('a', 'A', 'i', 'I', 'd', 'D'):
|
||||||
type = value.upper()
|
t = value.upper()
|
||||||
|
|
||||||
rawr = req.headers.get('Range', None)
|
rawr = req.headers.get('Range', None)
|
||||||
if rawr:
|
if rawr:
|
||||||
@@ -300,7 +300,7 @@ class FTPRangeHandler(urllib2.FTPHandler):
|
|||||||
else:
|
else:
|
||||||
rest = 0
|
rest = 0
|
||||||
|
|
||||||
fp, retrlen = fw.retrfile(file, type, rest)
|
fp, retrlen = fw.retrfile(f, t, rest)
|
||||||
|
|
||||||
fb, lb = rest, retrlen
|
fb, lb = rest, retrlen
|
||||||
if retrlen is None or retrlen == 0:
|
if retrlen is None or retrlen == 0:
|
||||||
@@ -327,7 +327,7 @@ class FTPRangeHandler(urllib2.FTPHandler):
|
|||||||
raise IOError, (_('ftp error'), msg), sys.exc_info()[2]
|
raise IOError, (_('ftp error'), msg), sys.exc_info()[2]
|
||||||
|
|
||||||
def connect_ftp(self, user, passwd, host, port, dirs):
|
def connect_ftp(self, user, passwd, host, port, dirs):
|
||||||
fw = ftpwrapper('', '', host, port, dirs)
|
fw = ftpwrapper(user, passwd, host, port, dirs)
|
||||||
return fw
|
return fw
|
||||||
|
|
||||||
class ftpwrapper(urllib.ftpwrapper):
|
class ftpwrapper(urllib.ftpwrapper):
|
||||||
@@ -355,6 +355,7 @@ class ftpwrapper(urllib.ftpwrapper):
|
|||||||
if str(reason)[:3] == '501':
|
if str(reason)[:3] == '501':
|
||||||
# workaround for REST not suported error
|
# workaround for REST not suported error
|
||||||
fp, retrlen = self.retrfile(file, type)
|
fp, retrlen = self.retrfile(file, type)
|
||||||
|
# WTF? No global (RangeableFileObject) found. RangeableFileObject only defined in urlgrabber / caglar
|
||||||
fp = RangeableFileObject(fp, (rest,''))
|
fp = RangeableFileObject(fp, (rest,''))
|
||||||
return (fp, retrlen)
|
return (fp, retrlen)
|
||||||
elif str(reason)[:3] != '550':
|
elif str(reason)[:3] != '550':
|
||||||
|
|||||||
@@ -144,7 +144,6 @@ class File:
|
|||||||
"it is pointless to open a file without a URI and a mode"
|
"it is pointless to open a file without a URI and a mode"
|
||||||
|
|
||||||
self.transfer_dir = transfer_dir
|
self.transfer_dir = transfer_dir
|
||||||
|
|
||||||
self.sha1sum = sha1sum
|
self.sha1sum = sha1sum
|
||||||
self.compress = compress
|
self.compress = compress
|
||||||
self.sign = sign
|
self.sign = sign
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ during the build process of a package and used in installation.'''
|
|||||||
|
|
||||||
|
|
||||||
import pisi.pxml.autoxml as autoxml
|
import pisi.pxml.autoxml as autoxml
|
||||||
|
import pisi.lockeddbshelve as shelve
|
||||||
|
|
||||||
|
|
||||||
class FileInfo:
|
class FileInfo:
|
||||||
"""File holds the information for a File node/tag in files.xml"""
|
"""File holds the information for a File node/tag in files.xml"""
|
||||||
@@ -47,3 +49,55 @@ class Files(autoxml.xmlfile.XmlFile):
|
|||||||
def append(self, fileinfo):
|
def append(self, fileinfo):
|
||||||
self.list.append(fileinfo)
|
self.list.append(fileinfo)
|
||||||
|
|
||||||
|
|
||||||
|
class FilesDB(shelve.LockedDBShelf):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
shelve.LockedDBShelf.__init__(self, 'files')
|
||||||
|
|
||||||
|
def add_files(self, pkg_name, files, txn = None):
|
||||||
|
def proc(txn):
|
||||||
|
for x in files.list:
|
||||||
|
path = x.path
|
||||||
|
del x.path # don't store redundant attribute in db
|
||||||
|
self.put(path, (pkg_name, x), txn)
|
||||||
|
x.path = path # store it back in
|
||||||
|
self.txn_proc(proc, txn)
|
||||||
|
|
||||||
|
def remove_files(self, files, txn = None):
|
||||||
|
def proc(txn):
|
||||||
|
for x in files.list:
|
||||||
|
if self.has_key(x.path):
|
||||||
|
self.delete(x.path, txn)
|
||||||
|
self.txn_proc(proc, txn)
|
||||||
|
|
||||||
|
def has_file(self, path, txn = None):
|
||||||
|
return self.has_key(str(path), txn)
|
||||||
|
|
||||||
|
def get_file(self, path, txn = None):
|
||||||
|
path = str(path)
|
||||||
|
def proc(txn):
|
||||||
|
if not self.has_key(path, txn):
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
(name, fileinfo) = self.get(path, txn)
|
||||||
|
fileinfo.path = path
|
||||||
|
return (name, fileinfo)
|
||||||
|
return self.txn_proc(proc, txn)
|
||||||
|
|
||||||
|
def match_files(self, glob):
|
||||||
|
# NB: avoid using, this reads the entire db
|
||||||
|
import fnmatch
|
||||||
|
glob = str(glob)
|
||||||
|
infos = []
|
||||||
|
for key in self.keys():
|
||||||
|
if fnmatch.fnmatch(key, glob):
|
||||||
|
|
||||||
|
# FIXME: Why should we assign path attribute manually
|
||||||
|
# in fileinfo? This is also done in get_file(), seems
|
||||||
|
# like a dirty workaround... - baris
|
||||||
|
name = self[key][0]
|
||||||
|
fileinfo = self[key][1]
|
||||||
|
fileinfo.path = key
|
||||||
|
infos.append((name, fileinfo))
|
||||||
|
return infos
|
||||||
|
|||||||
+3
-3
@@ -44,11 +44,11 @@ class Digraph(object):
|
|||||||
|
|
||||||
def edges(self):
|
def edges(self):
|
||||||
"return a list of edge descriptors"
|
"return a list of edge descriptors"
|
||||||
list = []
|
l = []
|
||||||
for u in self.__v:
|
for u in self.__v:
|
||||||
for v in self.__adj[u]:
|
for v in self.__adj[u]:
|
||||||
list.append( (u,v) )
|
l.append( (u,v) )
|
||||||
return list
|
return l
|
||||||
|
|
||||||
def from_list(self, el):
|
def from_list(self, el):
|
||||||
"convert a list of edges (u,v) to graph"
|
"convert a list of edges (u,v) to graph"
|
||||||
|
|||||||
+1
-3
@@ -23,15 +23,12 @@ import pisi
|
|||||||
import pisi.context as ctx
|
import pisi.context as ctx
|
||||||
import pisi.specfile as specfile
|
import pisi.specfile as specfile
|
||||||
import pisi.metadata as metadata
|
import pisi.metadata as metadata
|
||||||
import pisi.db.packagedb as packagedb
|
|
||||||
import pisi.db.sourcedb as sourcedb
|
|
||||||
import pisi.util as util
|
import pisi.util as util
|
||||||
import pisi.package
|
import pisi.package
|
||||||
import pisi.pxml.xmlfile as xmlfile
|
import pisi.pxml.xmlfile as xmlfile
|
||||||
import pisi.file
|
import pisi.file
|
||||||
import pisi.pxml.autoxml as autoxml
|
import pisi.pxml.autoxml as autoxml
|
||||||
import pisi.component as component
|
import pisi.component as component
|
||||||
import pisi.specfile as specfile
|
|
||||||
|
|
||||||
class Error(pisi.Error):
|
class Error(pisi.Error):
|
||||||
pass
|
pass
|
||||||
@@ -129,6 +126,7 @@ class Index(xmlfile.XmlFile):
|
|||||||
for comp in self.components:
|
for comp in self.components:
|
||||||
ctx.componentdb.update_component(comp, repo, txn)
|
ctx.componentdb.update_component(comp, repo, txn)
|
||||||
ctx.packagedb.remove_repo(repo, txn=txn)
|
ctx.packagedb.remove_repo(repo, txn=txn)
|
||||||
|
ctx.packagedb.add_obsoletes(self.distribution.obsoletes, repo, txn=txn)
|
||||||
for pkg in self.packages:
|
for pkg in self.packages:
|
||||||
ctx.packagedb.add_package(pkg, repo, txn=txn)
|
ctx.packagedb.add_package(pkg, repo, txn=txn)
|
||||||
update_progress()
|
update_progress()
|
||||||
|
|||||||
@@ -13,10 +13,6 @@
|
|||||||
# installation database
|
# installation database
|
||||||
#
|
#
|
||||||
|
|
||||||
# System
|
|
||||||
import os
|
|
||||||
import fcntl
|
|
||||||
|
|
||||||
import gettext
|
import gettext
|
||||||
__trans = gettext.translation('pisi', fallback=True)
|
__trans = gettext.translation('pisi', fallback=True)
|
||||||
_ = __trans.ugettext
|
_ = __trans.ugettext
|
||||||
@@ -24,8 +20,7 @@ _ = __trans.ugettext
|
|||||||
# PiSi
|
# PiSi
|
||||||
import pisi
|
import pisi
|
||||||
import pisi.context as ctx
|
import pisi.context as ctx
|
||||||
import pisi.oo
|
import pisi.lockeddbshelve as shelve
|
||||||
import pisi.db.lockeddbshelve as dbshelve
|
|
||||||
import pisi.files
|
import pisi.files
|
||||||
import pisi.util
|
import pisi.util
|
||||||
|
|
||||||
@@ -68,11 +63,10 @@ class InstallInfo:
|
|||||||
|
|
||||||
|
|
||||||
class InstallDB:
|
class InstallDB:
|
||||||
__metaclass__ = pisi.oo.Singleton
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.d = dbshelve.LockedDBShelf('install')
|
self.d = shelve.LockedDBShelf('install')
|
||||||
self.dp = dbshelve.LockedDBShelf('configpending')
|
self.dp = shelve.LockedDBShelf('configpending')
|
||||||
self.files_dir = pisi.util.join_path(ctx.config.db_dir(), 'files')
|
self.files_dir = pisi.util.join_path(ctx.config.db_dir(), 'files')
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
@@ -112,20 +106,20 @@ class InstallDB:
|
|||||||
|
|
||||||
def list_installed(self, txn = None):
|
def list_installed(self, txn = None):
|
||||||
def proc(txn):
|
def proc(txn):
|
||||||
list = []
|
l = []
|
||||||
for (pkg, info) in self.d.items(txn):
|
for (pkg, info) in self.d.items(txn):
|
||||||
if info.state=='i' or info.state=='ip':
|
if info.state=='i' or info.state=='ip':
|
||||||
list.append(pkg)
|
l.append(pkg)
|
||||||
return list
|
return l
|
||||||
return self.d.txn_proc(proc, txn)
|
return self.d.txn_proc(proc, txn)
|
||||||
|
|
||||||
def list_pending(self):
|
def list_pending(self):
|
||||||
# warning: reads the entire db
|
# warning: reads the entire db
|
||||||
dict = {}
|
d = {}
|
||||||
for (pkg, x) in self.dp.items():
|
for (pkg, x) in self.dp.items():
|
||||||
pkginfo = self.d[pkg]
|
pkginfo = self.d[pkg]
|
||||||
dict[pkg] = pkginfo
|
d[pkg] = pkginfo
|
||||||
return dict
|
return d
|
||||||
|
|
||||||
def get_info(self, pkg):
|
def get_info(self, pkg):
|
||||||
pkg = str(pkg)
|
pkg = str(pkg)
|
||||||
@@ -198,3 +192,19 @@ class InstallDB:
|
|||||||
if self.d.has_key(pkg, txn):
|
if self.d.has_key(pkg, txn):
|
||||||
self.d.delete(pkg, txn)
|
self.d.delete(pkg, txn)
|
||||||
self.d.txn_proc(proc, txn)
|
self.d.txn_proc(proc, txn)
|
||||||
|
|
||||||
|
db = None
|
||||||
|
|
||||||
|
def init():
|
||||||
|
global db
|
||||||
|
if db:
|
||||||
|
return db
|
||||||
|
|
||||||
|
db = InstallDB()
|
||||||
|
return db
|
||||||
|
|
||||||
|
def finalize():
|
||||||
|
global db
|
||||||
|
if db:
|
||||||
|
db.close()
|
||||||
|
db = None
|
||||||
@@ -10,18 +10,13 @@
|
|||||||
# Please read the COPYING file.
|
# Please read the COPYING file.
|
||||||
#
|
#
|
||||||
|
|
||||||
import os
|
|
||||||
import fcntl
|
|
||||||
import types
|
|
||||||
|
|
||||||
import gettext
|
import gettext
|
||||||
__trans = gettext.translation('pisi', fallback=True)
|
__trans = gettext.translation('pisi', fallback=True)
|
||||||
_ = __trans.ugettext
|
_ = __trans.ugettext
|
||||||
|
|
||||||
import pisi
|
import pisi
|
||||||
import pisi.util as util
|
|
||||||
import pisi.context as ctx
|
import pisi.context as ctx
|
||||||
import pisi.db.lockeddbshelve as shelve
|
import pisi.lockeddbshelve as shelve
|
||||||
|
|
||||||
installed, thirdparty, repos, all = range(1, 5)
|
installed, thirdparty, repos, all = range(1, 5)
|
||||||
|
|
||||||
@@ -16,7 +16,7 @@ import types
|
|||||||
|
|
||||||
import bsddb3.db as db
|
import bsddb3.db as db
|
||||||
import bsddb3.dbobj as dbobj
|
import bsddb3.dbobj as dbobj
|
||||||
import pisi.db.dbshelve as dbshelve
|
import pisi.dbshelve as shelve
|
||||||
|
|
||||||
import gettext
|
import gettext
|
||||||
__trans = gettext.translation('pisi', fallback=True)
|
__trans = gettext.translation('pisi', fallback=True)
|
||||||
@@ -24,7 +24,7 @@ _ = __trans.ugettext
|
|||||||
|
|
||||||
import pisi
|
import pisi
|
||||||
import pisi.context as ctx
|
import pisi.context as ctx
|
||||||
import pisi.util as util
|
import pisi.util
|
||||||
import pisi.version
|
import pisi.version
|
||||||
|
|
||||||
class Error(pisi.Error):
|
class Error(pisi.Error):
|
||||||
@@ -34,7 +34,7 @@ class Error(pisi.Error):
|
|||||||
# if write is given it knows it has write access
|
# if write is given it knows it has write access
|
||||||
# if force is given it updates the specified db version
|
# if force is given it updates the specified db version
|
||||||
def check_dbversion(versionfile, ver, write=False, update=False):
|
def check_dbversion(versionfile, ver, write=False, update=False):
|
||||||
verfn = util.join_path(ctx.config.db_dir(), versionfile)
|
verfn = pisi.util.join_path(pisi.context.config.db_dir(), versionfile)
|
||||||
firsttime = False
|
firsttime = False
|
||||||
if os.path.exists(verfn):
|
if os.path.exists(verfn):
|
||||||
verfile = file(verfn, 'r')
|
verfile = file(verfn, 'r')
|
||||||
@@ -43,11 +43,11 @@ def check_dbversion(versionfile, ver, write=False, update=False):
|
|||||||
dbver = pisi.version.Version(ver)
|
dbver = pisi.version.Version(ver)
|
||||||
if currver < dbver:
|
if currver < dbver:
|
||||||
if not update:
|
if not update:
|
||||||
raise Error(_('Database version %s is obsolete. Please run the rebuild-db command.') % versionfile)
|
raise Error(_('Database version for %s insufficient. Please run rebuild-db command.') % versionfile)
|
||||||
else:
|
else:
|
||||||
pass # continue to update, then
|
pass # continue to update, then
|
||||||
elif currver > dbver:
|
elif currver > dbver:
|
||||||
raise Error(_('Database version %s is too new for your PiSi version. You need to upgrade PiSi.') % versionfile)
|
raise Error(_('Database version for %s greater than PiSi version. You need a newer PiSi.') % versionfile)
|
||||||
elif not update:
|
elif not update:
|
||||||
return True # db version is OK
|
return True # db version is OK
|
||||||
else:
|
else:
|
||||||
@@ -63,7 +63,7 @@ def check_dbversion(versionfile, ver, write=False, update=False):
|
|||||||
raise Error(_('Database version %s not present.') % versionfile)
|
raise Error(_('Database version %s not present.') % versionfile)
|
||||||
|
|
||||||
def lock_dbenv():
|
def lock_dbenv():
|
||||||
ctx.dbenv_lock = file(util.join_path(pisi.context.config.db_dir(), 'dbenv.lock'), 'w')
|
ctx.dbenv_lock = file(pisi.util.join_path(pisi.context.config.db_dir(), 'dbenv.lock'), 'w')
|
||||||
try:
|
try:
|
||||||
fcntl.flock(ctx.dbenv_lock, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
fcntl.flock(ctx.dbenv_lock, fcntl.LOCK_EX | fcntl.LOCK_NB)
|
||||||
except IOError:
|
except IOError:
|
||||||
@@ -95,15 +95,15 @@ def init_dbenv(write=False, writeversion=False):
|
|||||||
else:
|
else:
|
||||||
ctx.dbenv = None # read-only access to database
|
ctx.dbenv = None # read-only access to database
|
||||||
|
|
||||||
class LockedDBShelf(dbshelve.DBShelf):
|
class LockedDBShelf(shelve.DBShelf):
|
||||||
"""A simple wrapper to implement locking for bsddb's dbshelf"""
|
"""A simple wrapper to implement locking for bsddb's dbshelf"""
|
||||||
|
|
||||||
def __init__(self, dbname, mode=0644,
|
def __init__(self, dbname, mode=0644,
|
||||||
filetype=db.DB_BTREE, dbenv = None):
|
filetype=db.DB_BTREE, dbenv = None):
|
||||||
if dbenv == None:
|
if dbenv == None:
|
||||||
dbenv = ctx.dbenv
|
dbenv = ctx.dbenv
|
||||||
dbshelve.DBShelf.__init__(self, dbenv)
|
shelve.DBShelf.__init__(self, dbenv)
|
||||||
filename = util.join_path(pisi.context.config.db_dir(), dbname + '.bdb')
|
filename = pisi.util.join_path(pisi.context.config.db_dir(), dbname + '.bdb')
|
||||||
if dbenv and os.access(os.path.dirname(filename), os.W_OK):
|
if dbenv and os.access(os.path.dirname(filename), os.W_OK):
|
||||||
flags = 'w'
|
flags = 'w'
|
||||||
elif os.access(filename, os.R_OK):
|
elif os.access(filename, os.R_OK):
|
||||||
@@ -110,6 +110,7 @@ class MetaData(xmlfile.XmlFile):
|
|||||||
# FIXME: no need to copy full history with comments
|
# FIXME: no need to copy full history with comments
|
||||||
self.package.history = history
|
self.package.history = history
|
||||||
self.package.conflicts = pkg.conflicts
|
self.package.conflicts = pkg.conflicts
|
||||||
|
self.package.replaces = pkg.replaces
|
||||||
self.package.providesComar = pkg.providesComar
|
self.package.providesComar = pkg.providesComar
|
||||||
#self.package.requiresComar = pkg.requiresComar
|
#self.package.requiresComar = pkg.requiresComar
|
||||||
self.package.additionalFiles = pkg.additionalFiles
|
self.package.additionalFiles = pkg.additionalFiles
|
||||||
|
|||||||
-10
@@ -37,13 +37,3 @@ class Struct:
|
|||||||
|
|
||||||
def __init__(self, **entries):
|
def __init__(self, **entries):
|
||||||
self.__dict__.update(entries)
|
self.__dict__.update(entries)
|
||||||
|
|
||||||
class Singleton(type):
|
|
||||||
def __init__(cls, name, bases, dic):
|
|
||||||
super(Singleton, cls).__init__(name, bases, dic)
|
|
||||||
cls.instance = None
|
|
||||||
|
|
||||||
def __call__(cls, *args, **kwargs):
|
|
||||||
if not cls.instance:
|
|
||||||
cls.instance = super(Singleton, cls).__call__(*args, **kwargs)
|
|
||||||
return cls.instance
|
|
||||||
|
|||||||
+60
-60
@@ -24,9 +24,8 @@ import pisi.util as util
|
|||||||
import pisi.dependency as dependency
|
import pisi.dependency as dependency
|
||||||
import pisi.conflict
|
import pisi.conflict
|
||||||
import pisi.pgraph as pgraph
|
import pisi.pgraph as pgraph
|
||||||
import pisi.db.packagedb as packagedb
|
import pisi.repodb
|
||||||
import pisi.db.repodb
|
import pisi.installdb
|
||||||
import pisi.db.installdb
|
|
||||||
import pisi.cli
|
import pisi.cli
|
||||||
import pisi.atomicoperations as atomicoperations
|
import pisi.atomicoperations as atomicoperations
|
||||||
import pisi.ui as ui
|
import pisi.ui as ui
|
||||||
@@ -178,7 +177,7 @@ in the respective order to satisfy extra dependencies:
|
|||||||
while len(B) > 0:
|
while len(B) > 0:
|
||||||
Bp = set()
|
Bp = set()
|
||||||
for x in B:
|
for x in B:
|
||||||
pkg = pisi.api.get_repo_package(x)
|
pkg = packagedb.get_package(x)
|
||||||
for dep in pkg.runtimeDependencies():
|
for dep in pkg.runtimeDependencies():
|
||||||
if dependency.dict_satisfies_dep(d_t, dep):
|
if dependency.dict_satisfies_dep(d_t, dep):
|
||||||
if not dep.package in G_f.vertices():
|
if not dep.package in G_f.vertices():
|
||||||
@@ -208,53 +207,37 @@ in the respective order to satisfy extra dependencies:
|
|||||||
if 'pisi' in order and pisi_installed:
|
if 'pisi' in order and pisi_installed:
|
||||||
upgrade_pisi()
|
upgrade_pisi()
|
||||||
|
|
||||||
def check_conflict(pkg, order):
|
# FIXME: this should be done in atomicoperations automatically.
|
||||||
conflicts = []
|
def remove_replaced_packages(order, replaces):
|
||||||
|
|
||||||
for conflict in pkg.conflicts:
|
replaced = []
|
||||||
if conflict.package not in order and pisi.conflict.installed_package_conflicts(conflict):
|
inorder = set(order).intersection(replaces.values())
|
||||||
conflicts.append(conflict)
|
|
||||||
|
|
||||||
return conflicts
|
if inorder:
|
||||||
|
for pkg in replaces.keys():
|
||||||
|
if replaces[pkg] in inorder:
|
||||||
|
replaced.append(pkg)
|
||||||
|
|
||||||
def calculate_conflicts(order, packagedb):
|
if replaced:
|
||||||
B_0 = set(order)
|
if remove(replaced, ignore_dep=True, ignore_safety=True):
|
||||||
C = D = set()
|
raise Error(_("Replaced package remains"))
|
||||||
pkg_conflicts = {}
|
|
||||||
|
|
||||||
for x in order:
|
|
||||||
pkg = pisi.api.get_repo_package(x)
|
|
||||||
|
|
||||||
# check if any package has conflicts with the installed packages
|
|
||||||
conflicts = check_conflict(pkg, order)
|
|
||||||
if conflicts:
|
|
||||||
pkg_conflicts[x] = map(lambda c:str(c), conflicts)
|
|
||||||
C = C.union(map(lambda c:c.package, conflicts))
|
|
||||||
|
|
||||||
# now check if any package has conflicts with each other
|
|
||||||
B_i = B_0.intersection(set(map(lambda c:c.package, pkg.conflicts)))
|
|
||||||
D_i = set()
|
|
||||||
for p in map(lambda x:pisi.api.get_repo_package(x), B_i):
|
|
||||||
conflicted = pisi.conflict.package_conflicts(p, pkg.conflicts)
|
|
||||||
if conflicted:
|
|
||||||
D_i.add(str(conflicted))
|
|
||||||
|
|
||||||
if D_i:
|
|
||||||
D = D.union(D_i)
|
|
||||||
D.add(pkg.name)
|
|
||||||
|
|
||||||
return (C, D, pkg_conflicts)
|
|
||||||
|
|
||||||
def remove_conflicting_packages(conflicts):
|
def remove_conflicting_packages(conflicts):
|
||||||
if remove(conflicts, ignore_dep=True, ignore_safety=True) == False:
|
if remove(conflicts, ignore_dep=True, ignore_safety=True):
|
||||||
raise Error(_("Conflicts remain"))
|
raise Error(_("Conflicts remain"))
|
||||||
|
|
||||||
|
def remove_obsoleted_packages():
|
||||||
|
obsoletes = filter(ctx.installdb.is_installed, ctx.packagedb.get_obsoletes())
|
||||||
|
if obsoletes:
|
||||||
|
if remove(obsoletes, ignore_dep=True, ignore_safety=True):
|
||||||
|
raise Error(_("Obsoleted packages remaining"))
|
||||||
|
|
||||||
def check_conflicts(order, packagedb):
|
def check_conflicts(order, packagedb):
|
||||||
"""check if upgrading to the latest versions will cause havoc
|
"""check if upgrading to the latest versions will cause havoc
|
||||||
done in a simple minded way without regard for dependencies of
|
done in a simple minded way without regard for dependencies of
|
||||||
conflicts, etc."""
|
conflicts, etc."""
|
||||||
|
|
||||||
(C, D, pkg_conflicts) = calculate_conflicts(order, packagedb)
|
(C, D, pkg_conflicts) = pisi.conflict.calculate_conflicts(order, packagedb)
|
||||||
|
|
||||||
if D:
|
if D:
|
||||||
raise Error(_("Selected packages [%s] are in conflict with each other.") %
|
raise Error(_("Selected packages [%s] are in conflict with each other.") %
|
||||||
@@ -278,11 +261,12 @@ def is_upgradable(name, ignore_build = False):
|
|||||||
return False
|
return False
|
||||||
(version, release, build) = ctx.installdb.get_version(name)
|
(version, release, build) = ctx.installdb.get_version(name)
|
||||||
try:
|
try:
|
||||||
pkg = pisi.api.get_repo_package(name)
|
pkg = ctx.packagedb.get_package(name)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
raise
|
raise
|
||||||
except Exception, e: #FIXME: what exception could we catch here, replace with that.
|
except Exception, e: #FIXME: what exception could we catch here, replace with that.
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if ignore_build or (not build) or (not pkg.build):
|
if ignore_build or (not build) or (not pkg.build):
|
||||||
return pisi.version.Version(release) < pisi.version.Version(pkg.release)
|
return pisi.version.Version(release) < pisi.version.Version(pkg.release)
|
||||||
else:
|
else:
|
||||||
@@ -303,7 +287,7 @@ def upgrade_base(A = set(), ignore_package_conflicts = False):
|
|||||||
if extra_upgrades:
|
if extra_upgrades:
|
||||||
ctx.ui.warning(_('Safety switch: Following packages in system.base will be upgraded: ') +
|
ctx.ui.warning(_('Safety switch: Following packages in system.base will be upgraded: ') +
|
||||||
util.strlist(extra_upgrades))
|
util.strlist(extra_upgrades))
|
||||||
G_f, upgrade_order = plan_upgrade(extra_upgrades, ignore_build)
|
G_f, upgrade_order = plan_upgrade(extra_upgrades)
|
||||||
# return packages that must be added to any installation
|
# return packages that must be added to any installation
|
||||||
return set(install_order + upgrade_order)
|
return set(install_order + upgrade_order)
|
||||||
else:
|
else:
|
||||||
@@ -384,7 +368,7 @@ def plan_install_pkg_names(A, ignore_package_conflicts = False):
|
|||||||
while len(B) > 0:
|
while len(B) > 0:
|
||||||
Bp = set()
|
Bp = set()
|
||||||
for x in B:
|
for x in B:
|
||||||
pkg = pisi.api.get_repo_package(x)
|
pkg = ctx.packagedb.get_package(x)
|
||||||
for dep in pkg.runtimeDependencies():
|
for dep in pkg.runtimeDependencies():
|
||||||
ctx.ui.debug('checking %s' % str(dep))
|
ctx.ui.debug('checking %s' % str(dep))
|
||||||
# we don't deal with already *satisfied* dependencies
|
# we don't deal with already *satisfied* dependencies
|
||||||
@@ -413,6 +397,9 @@ def upgrade_pkg_names(A = []):
|
|||||||
ignore_build = ctx.get_option('ignore_build_no')
|
ignore_build = ctx.get_option('ignore_build_no')
|
||||||
security_only = ctx.get_option('security_only')
|
security_only = ctx.get_option('security_only')
|
||||||
|
|
||||||
|
replaced = []
|
||||||
|
replaces = ctx.packagedb.get_replaces()
|
||||||
|
|
||||||
if not A:
|
if not A:
|
||||||
# if A is empty, then upgrade all packages
|
# if A is empty, then upgrade all packages
|
||||||
A = ctx.installdb.list_installed()
|
A = ctx.installdb.list_installed()
|
||||||
@@ -424,19 +411,27 @@ def upgrade_pkg_names(A = []):
|
|||||||
if x.endswith(ctx.const.package_suffix):
|
if x.endswith(ctx.const.package_suffix):
|
||||||
ctx.ui.debug(_("Warning: package *name* ends with '.pisi'"))
|
ctx.ui.debug(_("Warning: package *name* ends with '.pisi'"))
|
||||||
|
|
||||||
|
# Handling of replacement packages
|
||||||
|
if x in replaces.values():
|
||||||
|
Ap.append(x)
|
||||||
|
continue
|
||||||
|
|
||||||
|
if x in replaces.keys():
|
||||||
|
Ap.append(replaces[x])
|
||||||
|
continue
|
||||||
|
|
||||||
if not ctx.installdb.is_installed(x):
|
if not ctx.installdb.is_installed(x):
|
||||||
ctx.ui.info(_('Package %s is not installed.') % x, True)
|
ctx.ui.info(_('Package %s is not installed.') % x, True)
|
||||||
continue
|
continue
|
||||||
(version, release, build) = ctx.installdb.get_version(x)
|
(version, release, build) = ctx.installdb.get_version(x)
|
||||||
if ctx.packagedb.has_package(x):
|
if ctx.packagedb.has_package(x):
|
||||||
pkg = pisi.api.get_repo_package(x)
|
pkg = ctx.packagedb.get_package(x)
|
||||||
else:
|
else:
|
||||||
ctx.ui.info(_('Package %s is not available in repositories.') % x, True)
|
ctx.ui.info(_('Package %s is not available in repositories.') % x, True)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if security_only:
|
if security_only:
|
||||||
history = ctx.packageDB.get_history(x)
|
updates = [i for i in pkg.history if pisi.version.Version(i.release) > pisi.version.Version(release)]
|
||||||
updates = [i for i in history if pisi.version.Version(i.release) > pisi.version.Version(release)]
|
|
||||||
if not pisi.util.any(lambda i:i.type == 'security', updates):
|
if not pisi.util.any(lambda i:i.type == 'security', updates):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@@ -465,7 +460,7 @@ def upgrade_pkg_names(A = []):
|
|||||||
ctx.ui.debug('A = %s' % str(A))
|
ctx.ui.debug('A = %s' % str(A))
|
||||||
|
|
||||||
if not ctx.config.get_option('ignore_dependency'):
|
if not ctx.config.get_option('ignore_dependency'):
|
||||||
G_f, order = plan_upgrade(A, ignore_build)
|
G_f, order = plan_upgrade(A)
|
||||||
else:
|
else:
|
||||||
G_f = None
|
G_f = None
|
||||||
order = list(A)
|
order = list(A)
|
||||||
@@ -487,7 +482,7 @@ def upgrade_pkg_names(A = []):
|
|||||||
if ctx.get_option('dry_run'):
|
if ctx.get_option('dry_run'):
|
||||||
return
|
return
|
||||||
|
|
||||||
if set(order) - A_0:
|
if set(order) - A_0 - set(replaces.values()):
|
||||||
if not ctx.ui.confirm(_('There are extra packages due to dependencies. Do you want to continue?')):
|
if not ctx.ui.confirm(_('There are extra packages due to dependencies. Do you want to continue?')):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -495,7 +490,7 @@ def upgrade_pkg_names(A = []):
|
|||||||
|
|
||||||
paths = []
|
paths = []
|
||||||
for x in order:
|
for x in order:
|
||||||
ctx.ui.info(_("Downloading %d / %d") % (order.index(x)+1, len(order)))
|
ctx.ui.info(util.colorize(_("Downloading %d / %d") % (order.index(x)+1, len(order)), "yellow"))
|
||||||
install_op = atomicoperations.Install.from_name(x)
|
install_op = atomicoperations.Install.from_name(x)
|
||||||
paths.append(install_op.package_fname)
|
paths.append(install_op.package_fname)
|
||||||
|
|
||||||
@@ -507,15 +502,20 @@ def upgrade_pkg_names(A = []):
|
|||||||
if conflicts:
|
if conflicts:
|
||||||
remove_conflicting_packages(conflicts)
|
remove_conflicting_packages(conflicts)
|
||||||
|
|
||||||
|
if replaces:
|
||||||
|
remove_replaced_packages(order, replaces)
|
||||||
|
|
||||||
|
remove_obsoleted_packages()
|
||||||
|
|
||||||
for path in paths:
|
for path in paths:
|
||||||
ctx.ui.info(_("Installing %d / %d") % (paths.index(path)+1, len(paths)))
|
ctx.ui.info(util.colorize(_("Installing %d / %d") % (paths.index(path)+1, len(paths)), "yellow"))
|
||||||
install_op = atomicoperations.Install(path, ignore_file_conflicts = True)
|
install_op = atomicoperations.Install(path, ignore_file_conflicts = True)
|
||||||
install_op.install(True)
|
install_op.install(True)
|
||||||
|
|
||||||
if 'pisi' in order:
|
if 'pisi' in order:
|
||||||
upgrade_pisi()
|
upgrade_pisi()
|
||||||
|
|
||||||
def plan_upgrade(A, ignore_build = False):
|
def plan_upgrade(A):
|
||||||
# try to construct a pisi graph of packages to
|
# try to construct a pisi graph of packages to
|
||||||
# install / reinstall
|
# install / reinstall
|
||||||
|
|
||||||
@@ -534,7 +534,7 @@ def plan_upgrade(A, ignore_build = False):
|
|||||||
while len(B) > 0:
|
while len(B) > 0:
|
||||||
Bp = set()
|
Bp = set()
|
||||||
for x in B:
|
for x in B:
|
||||||
pkg = pisi.api.get_repo_package(x)
|
pkg = packagedb.get_package(x)
|
||||||
for dep in pkg.runtimeDependencies():
|
for dep in pkg.runtimeDependencies():
|
||||||
# add packages that can be upgraded
|
# add packages that can be upgraded
|
||||||
if ctx.installdb.is_installed(dep.package) and dependency.installed_satisfies_dep(dep):
|
if ctx.installdb.is_installed(dep.package) and dependency.installed_satisfies_dep(dep):
|
||||||
@@ -547,6 +547,7 @@ def plan_upgrade(A, ignore_build = False):
|
|||||||
else:
|
else:
|
||||||
ctx.ui.error(_('Dependency %s of %s cannot be satisfied') % (dep, x))
|
ctx.ui.error(_('Dependency %s of %s cannot be satisfied') % (dep, x))
|
||||||
raise Error(_("Upgrade is not possible."))
|
raise Error(_("Upgrade is not possible."))
|
||||||
|
|
||||||
B = Bp
|
B = Bp
|
||||||
# now, search reverse dependencies to see if anything
|
# now, search reverse dependencies to see if anything
|
||||||
# should be upgraded
|
# should be upgraded
|
||||||
@@ -554,7 +555,7 @@ def plan_upgrade(A, ignore_build = False):
|
|||||||
while len(B) > 0:
|
while len(B) > 0:
|
||||||
Bp = set()
|
Bp = set()
|
||||||
for x in B:
|
for x in B:
|
||||||
pkg = pisi.api.get_repo_package(x)
|
pkg = packagedb.get_package(x)
|
||||||
rev_deps = packagedb.get_rev_deps(x)
|
rev_deps = packagedb.get_rev_deps(x)
|
||||||
for (rev_dep, depinfo) in rev_deps:
|
for (rev_dep, depinfo) in rev_deps:
|
||||||
# add only installed but unsatisfied reverse dependencies
|
# add only installed but unsatisfied reverse dependencies
|
||||||
@@ -633,7 +634,7 @@ def plan_remove(A):
|
|||||||
# try to construct a pisi graph of packages to
|
# try to construct a pisi graph of packages to
|
||||||
# install / reinstall
|
# install / reinstall
|
||||||
|
|
||||||
G_f = pgraph.PGraph(ctx.packagedb, pisi.db.itembyrepodb.installed) # construct G_f
|
G_f = pgraph.PGraph(ctx.packagedb, pisi.itembyrepodb.installed) # construct G_f
|
||||||
|
|
||||||
# find the (install closure) graph of G_f by package
|
# find the (install closure) graph of G_f by package
|
||||||
# set A using packagedb
|
# set A using packagedb
|
||||||
@@ -643,12 +644,11 @@ def plan_remove(A):
|
|||||||
while len(B) > 0:
|
while len(B) > 0:
|
||||||
Bp = set()
|
Bp = set()
|
||||||
for x in B:
|
for x in B:
|
||||||
pkg = pisi.api.get_installed_package(x)
|
rev_deps = ctx.packagedb.get_rev_deps(x, pisi.itembyrepodb.installed)
|
||||||
rev_deps = ctx.packagedb.get_rev_deps(x, pisi.db.itembyrepodb.installed)
|
|
||||||
for (rev_dep, depinfo) in rev_deps:
|
for (rev_dep, depinfo) in rev_deps:
|
||||||
# we don't deal with uninstalled rev deps
|
# we don't deal with uninstalled rev deps
|
||||||
# and unsatisfied dependencies (this is important, too)
|
# and unsatisfied dependencies (this is important, too)
|
||||||
if ctx.packagedb.has_package(rev_dep, pisi.db.itembyrepodb.installed) and \
|
if ctx.packagedb.has_package(rev_dep, pisi.itembyrepodb.installed) and \
|
||||||
dependency.installed_satisfies_dep(depinfo):
|
dependency.installed_satisfies_dep(depinfo):
|
||||||
if not rev_dep in G_f.vertices():
|
if not rev_dep in G_f.vertices():
|
||||||
Bp.add(rev_dep)
|
Bp.add(rev_dep)
|
||||||
@@ -668,7 +668,7 @@ def expand_src_components(A):
|
|||||||
Ap.add(x)
|
Ap.add(x)
|
||||||
return Ap
|
return Ap
|
||||||
|
|
||||||
def emerge(A, rebuild_all = False):
|
def emerge(A):
|
||||||
|
|
||||||
# A was a list, remove duplicates and expand components
|
# A was a list, remove duplicates and expand components
|
||||||
A = [str(x) for x in A]
|
A = [str(x) for x in A]
|
||||||
@@ -684,7 +684,7 @@ def emerge(A, rebuild_all = False):
|
|||||||
# FIXME: Errr... order_build changes type conditionally and this
|
# FIXME: Errr... order_build changes type conditionally and this
|
||||||
# is not good. - baris
|
# is not good. - baris
|
||||||
if not ctx.config.get_option('ignore_dependency'):
|
if not ctx.config.get_option('ignore_dependency'):
|
||||||
G_f, order_inst, order_build = plan_emerge(A, rebuild_all)
|
G_f, order_inst, order_build = plan_emerge(A)
|
||||||
else:
|
else:
|
||||||
G_f = None
|
G_f = None
|
||||||
order_inst = []
|
order_inst = []
|
||||||
@@ -725,7 +725,7 @@ installed in the respective order to satisfy dependencies:
|
|||||||
if 'pisi' in order_build or (('pisi' in U) and pisi_installed):
|
if 'pisi' in order_build or (('pisi' in U) and pisi_installed):
|
||||||
upgrade_pisi()
|
upgrade_pisi()
|
||||||
|
|
||||||
def plan_emerge(A, rebuild_all):
|
def plan_emerge(A):
|
||||||
|
|
||||||
# try to construct a pisi graph of packages to
|
# try to construct a pisi graph of packages to
|
||||||
# install / reinstall
|
# install / reinstall
|
||||||
@@ -793,7 +793,7 @@ def plan_emerge(A, rebuild_all):
|
|||||||
def calculate_download_sizes(order):
|
def calculate_download_sizes(order):
|
||||||
total_size = cached_size = 0
|
total_size = cached_size = 0
|
||||||
|
|
||||||
for pkg in [pisi.api.get_repo_package(name) for name in order]:
|
for pkg in [ctx.packagedb.get_package(name) for name in order]:
|
||||||
|
|
||||||
delta = None
|
delta = None
|
||||||
if ctx.installdb.is_installed(pkg.name):
|
if ctx.installdb.is_installed(pkg.name):
|
||||||
|
|||||||
+1
-1
@@ -54,7 +54,7 @@ class Package:
|
|||||||
# Bug 3465
|
# Bug 3465
|
||||||
if ctx.get_option('reinstall'):
|
if ctx.get_option('reinstall'):
|
||||||
raise Error(_("There was a problem while fetching '%s'.\nThe package "
|
raise Error(_("There was a problem while fetching '%s'.\nThe package "
|
||||||
"may have been upgraded. Please try again to upgrade the package.") % url);
|
"may have been upgraded. Please try to upgrade the package.") % url);
|
||||||
raise
|
raise
|
||||||
else:
|
else:
|
||||||
ctx.ui.info(_('%s [cached]') % url.filename())
|
ctx.ui.info(_('%s [cached]') % url.filename())
|
||||||
|
|||||||
@@ -17,20 +17,13 @@ we basically store everything in PackageInfo class
|
|||||||
yes, we are cheap
|
yes, we are cheap
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
|
||||||
import fcntl
|
|
||||||
import types
|
|
||||||
|
|
||||||
import gettext
|
import gettext
|
||||||
__trans = gettext.translation('pisi', fallback=True)
|
__trans = gettext.translation('pisi', fallback=True)
|
||||||
_ = __trans.ugettext
|
_ = __trans.ugettext
|
||||||
|
|
||||||
import pisi
|
import pisi
|
||||||
import pisi.util as util
|
|
||||||
import pisi.context as ctx
|
import pisi.context as ctx
|
||||||
import pisi.oo
|
import pisi.itembyrepodb
|
||||||
import pisi.db.itembyrepodb as itembyrepodb
|
|
||||||
|
|
||||||
|
|
||||||
class Error(pisi.Error):
|
class Error(pisi.Error):
|
||||||
pass
|
pass
|
||||||
@@ -43,27 +36,24 @@ class NotfoundError(pisi.Error):
|
|||||||
class PackageDB(object):
|
class PackageDB(object):
|
||||||
"""PackageDB class provides an interface to the package database
|
"""PackageDB class provides an interface to the package database
|
||||||
using shelf objects"""
|
using shelf objects"""
|
||||||
__metaclass__ = pisi.oo.Singleton
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.d = itembyrepodb.ItemByRepoDB('package')
|
self.d = pisi.itembyrepodb.ItemByRepoDB('package')
|
||||||
self.dbHistory = itembyrepodb.ItemByRepoDB('package_history')
|
self.dr = pisi.itembyrepodb.ItemByRepoDB('revdep')
|
||||||
self.dr = itembyrepodb.ItemByRepoDB('revdep')
|
self.do = pisi.itembyrepodb.ItemByRepoDB('obsoleted')
|
||||||
|
self.drp = pisi.itembyrepodb.ItemByRepoDB('replaces')
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
self.d.close()
|
self.d.close()
|
||||||
self.dbHistory.close()
|
|
||||||
self.dr.close()
|
self.dr.close()
|
||||||
|
self.do.close()
|
||||||
|
self.drp.close()
|
||||||
|
|
||||||
def destroy(self):
|
def destroy(self):
|
||||||
self.d.destroy()
|
self.d.destroy()
|
||||||
self.dbHistory.destroy()
|
|
||||||
self.dr.destroy()
|
self.dr.destroy()
|
||||||
|
self.do.destroy()
|
||||||
def clear(self, txn = None):
|
self.drp.destroy()
|
||||||
self.d.clear()
|
|
||||||
self.dbHistory.clear()
|
|
||||||
self.dr.clear()
|
|
||||||
|
|
||||||
def has_package(self, name, repo=None, txn = None):
|
def has_package(self, name, repo=None, txn = None):
|
||||||
return self.d.has_key(name, repo, txn=txn)
|
return self.d.has_key(name, repo, txn=txn)
|
||||||
@@ -71,21 +61,34 @@ class PackageDB(object):
|
|||||||
def get_package(self, name, repo=None, txn = None):
|
def get_package(self, name, repo=None, txn = None):
|
||||||
try:
|
try:
|
||||||
return self.d.get_item(name, repo, txn=txn)
|
return self.d.get_item(name, repo, txn=txn)
|
||||||
except pisi.db.itembyrepodb.NotfoundError, e:
|
except pisi.itembyrepodb.NotfoundError:
|
||||||
raise Error(_('Package %s not found') % name)
|
raise Error(_('Package %s not found') % name)
|
||||||
|
|
||||||
def get_history(self, name, repo=None, txn = None):
|
|
||||||
try:
|
|
||||||
return self.dbHistory.get_item(name, repo, txn=txn)
|
|
||||||
except pisi.db.itembyrepodb.NotfoundError, e:
|
|
||||||
raise Error(_('History for Package %s not found') % name)
|
|
||||||
|
|
||||||
def get_package_repo(self, name, repo=None, txn = None):
|
def get_package_repo(self, name, repo=None, txn = None):
|
||||||
return self.d.get_item_repo(name, repo, txn=txn)
|
return self.d.get_item_repo(name, repo, txn=txn)
|
||||||
|
|
||||||
def which_repo(self, name, txn = None):
|
def which_repo(self, name, txn = None):
|
||||||
return self.d.which_repo(name, txn=txn)
|
return self.d.which_repo(name, txn=txn)
|
||||||
|
|
||||||
|
def get_obsoletes(self, repo=None):
|
||||||
|
obsoletes = []
|
||||||
|
for r in self.do.list(repo):
|
||||||
|
obsoletes.extend(self.do.get_item(r, repo))
|
||||||
|
|
||||||
|
replaces = self.get_replaces(repo)
|
||||||
|
return set(str(o) for o in obsoletes) - set(replaces.keys())
|
||||||
|
|
||||||
|
# replacesdb holds the info about the replaced packages (ex. gaim -> pidgin)
|
||||||
|
def get_replaces(self, repo = None):
|
||||||
|
pairs = {}
|
||||||
|
for pkg_name in self.drp.list(repo):
|
||||||
|
replaces = self.drp.get_item(pkg_name, repo)
|
||||||
|
for r in replaces:
|
||||||
|
if pisi.replace.installed_package_replaced(r):
|
||||||
|
pairs[r.package] = pkg_name
|
||||||
|
|
||||||
|
return pairs
|
||||||
|
|
||||||
def get_rev_deps(self, name, repo = None, txn = None):
|
def get_rev_deps(self, name, repo = None, txn = None):
|
||||||
if self.dr.has_key(name, repo, txn=txn):
|
if self.dr.has_key(name, repo, txn=txn):
|
||||||
return self.dr.get_item(name, repo, txn=txn)
|
return self.dr.get_item(name, repo, txn=txn)
|
||||||
@@ -102,12 +105,15 @@ class PackageDB(object):
|
|||||||
def list_packages(self, repo=None):
|
def list_packages(self, repo=None):
|
||||||
return self.d.list(repo)
|
return self.d.list(repo)
|
||||||
|
|
||||||
|
def add_obsoletes(self, obsoletes, repo, txn = None):
|
||||||
|
def proc(txn):
|
||||||
|
self.do.add_item(repo, obsoletes, repo, txn)
|
||||||
|
ctx.txn_proc(proc, txn)
|
||||||
|
|
||||||
def add_package(self, package_info, repo, txn = None):
|
def add_package(self, package_info, repo, txn = None):
|
||||||
name = str(package_info.name)
|
name = str(package_info.name)
|
||||||
|
|
||||||
def proc(txn):
|
def proc(txn):
|
||||||
self.dbHistory.add_item(name, package_info.history, repo, txn)
|
|
||||||
package_info.history = None
|
|
||||||
self.d.add_item(name, package_info, repo, txn)
|
self.d.add_item(name, package_info, repo, txn)
|
||||||
for dep in package_info.runtimeDependencies():
|
for dep in package_info.runtimeDependencies():
|
||||||
dep_name = str(dep.package)
|
dep_name = str(dep.package)
|
||||||
@@ -118,16 +124,26 @@ class PackageDB(object):
|
|||||||
self.dr.add_item(dep_name, revdep, repo, txn)
|
self.dr.add_item(dep_name, revdep, repo, txn)
|
||||||
else:
|
else:
|
||||||
self.dr.add_item(dep_name, [ (name, dep) ], repo, txn)
|
self.dr.add_item(dep_name, [ (name, dep) ], repo, txn)
|
||||||
|
|
||||||
|
if package_info.replaces:
|
||||||
|
self.drp.add_item(name, package_info.replaces, repo, txn)
|
||||||
|
|
||||||
# add component
|
# add component
|
||||||
ctx.componentdb.add_package(package_info.partOf, package_info.name, repo, txn)
|
ctx.componentdb.add_package(package_info.partOf, package_info.name, repo, txn)
|
||||||
|
|
||||||
ctx.txn_proc(proc, txn)
|
ctx.txn_proc(proc, txn)
|
||||||
|
|
||||||
|
def clear(self, txn = None):
|
||||||
|
self.d.clear()
|
||||||
|
self.dr.clear()
|
||||||
|
self.do.clear()
|
||||||
|
self.drp.clear()
|
||||||
|
|
||||||
def remove_package(self, name, repo = None, txn = None):
|
def remove_package(self, name, repo = None, txn = None):
|
||||||
name = str(name)
|
name = str(name)
|
||||||
def proc(txn):
|
def proc(txn):
|
||||||
package_info = self.d.get_item(name, repo, txn=txn)
|
package_info = self.d.get_item(name, repo, txn=txn)
|
||||||
self.d.remove_item(name, repo, txn=txn)
|
self.d.remove_item(name, repo, txn=txn)
|
||||||
self.dbHistory.remove_item(name, repo, txn=txn)
|
|
||||||
for dep in package_info.runtimeDependencies():
|
for dep in package_info.runtimeDependencies():
|
||||||
dep_name = str(dep.package)
|
dep_name = str(dep.package)
|
||||||
if self.dr.has_key(dep_name, repo, txn):
|
if self.dr.has_key(dep_name, repo, txn):
|
||||||
@@ -152,11 +168,25 @@ class PackageDB(object):
|
|||||||
def proc(txn):
|
def proc(txn):
|
||||||
self.d.remove_repo(repo, txn=txn)
|
self.d.remove_repo(repo, txn=txn)
|
||||||
self.dr.remove_repo(repo, txn=txn)
|
self.dr.remove_repo(repo, txn=txn)
|
||||||
|
self.do.remove_repo(repo, txn=txn)
|
||||||
|
self.drp.remove_repo(repo, txn=txn)
|
||||||
self.d.txn_proc(proc, txn)
|
self.d.txn_proc(proc, txn)
|
||||||
|
|
||||||
|
pkgdb = None
|
||||||
|
|
||||||
def remove_tracking_package(name, txn = None):
|
def remove_tracking_package(name, txn = None):
|
||||||
# remove the guy from the tracking databases
|
# remove the guy from the tracking databases
|
||||||
if pkgdb.has_package(name, itembyrepodb.installed, txn=txn):
|
if pkgdb.has_package(name, pisi.itembyrepodb.installed, txn=txn):
|
||||||
pkgdb.remove_package(name, itembyrepodb.installed, txn=txn)
|
pkgdb.remove_package(name, pisi.itembyrepodb.installed, txn=txn)
|
||||||
if pkgdb.has_package(name, itembyrepodb.thirdparty, txn=txn):
|
if pkgdb.has_package(name, pisi.itembyrepodb.thirdparty, txn=txn):
|
||||||
pkgdb.remove_package(name, itembyrepodb.thirdparty, txn=txn)
|
pkgdb.remove_package(name, pisi.itembyrepodb.thirdparty, txn=txn)
|
||||||
|
|
||||||
|
def init_db():
|
||||||
|
global pkgdb
|
||||||
|
pkgdb = PackageDB()
|
||||||
|
return pkgdb
|
||||||
|
|
||||||
|
def finalize_db():
|
||||||
|
global pkgdb
|
||||||
|
if pkgdb:
|
||||||
|
pkgdb.close()
|
||||||
+3
-2
@@ -14,14 +14,14 @@
|
|||||||
|
|
||||||
import string
|
import string
|
||||||
|
|
||||||
import pisi.db
|
import pisi
|
||||||
import graph
|
import graph
|
||||||
|
|
||||||
# Cache the results from packagedb queries in a graph
|
# Cache the results from packagedb queries in a graph
|
||||||
|
|
||||||
class PGraph(graph.Digraph):
|
class PGraph(graph.Digraph):
|
||||||
|
|
||||||
def __init__(self, packagedb, repo = pisi.db.itembyrepodb.repos):
|
def __init__(self, packagedb, repo = pisi.itembyrepodb.repos):
|
||||||
super(PGraph, self).__init__()
|
super(PGraph, self).__init__()
|
||||||
self.packagedb = packagedb
|
self.packagedb = packagedb
|
||||||
self.repo = repo
|
self.repo = repo
|
||||||
@@ -76,6 +76,7 @@ class PGraph(graph.Digraph):
|
|||||||
pkg2 = self.packagedb.get_package(conflinfo.package, self.repo)
|
pkg2 = self.packagedb.get_package(conflinfo.package, self.repo)
|
||||||
pkg2data = (pkg2.version, pkg2.release)
|
pkg2data = (pkg2.version, pkg2.release)
|
||||||
|
|
||||||
|
# FIXME: WTF? /usr/lib/pardus/pisi/pgraph.py:80: Invalid arguments to (add_biedge), got 5, expected between 2 and 3 / caglar
|
||||||
self.add_biedge(str(pkg), str(conflinfo.package), ('c', conflinfo)
|
self.add_biedge(str(pkg), str(conflinfo.package), ('c', conflinfo)
|
||||||
, pkg1data, pkg2data )
|
, pkg1data, pkg2data )
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,59 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# Copyright (C) 2007, TUBITAK/UEKAE
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it under
|
||||||
|
# the terms of the GNU General Public License as published by the Free
|
||||||
|
# Software Foundation; either version 2 of the License, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
#
|
||||||
|
# Please read the COPYING file.
|
||||||
|
#
|
||||||
|
|
||||||
|
import gettext
|
||||||
|
__trans = gettext.translation('pisi', fallback=True)
|
||||||
|
_ = __trans.ugettext
|
||||||
|
|
||||||
|
import pisi.context as ctx
|
||||||
|
import pisi.version
|
||||||
|
import pisi.pxml.autoxml as autoxml
|
||||||
|
import pisi.itembyrepodb
|
||||||
|
|
||||||
|
class Relation:
|
||||||
|
|
||||||
|
__metaclass__ = autoxml.autoxml
|
||||||
|
|
||||||
|
s_Package = [autoxml.String, autoxml.mandatory]
|
||||||
|
a_version = [autoxml.String, autoxml.optional]
|
||||||
|
a_versionFrom = [autoxml.String, autoxml.optional]
|
||||||
|
a_versionTo = [autoxml.String, autoxml.optional]
|
||||||
|
a_release = [autoxml.String, autoxml.optional]
|
||||||
|
a_releaseFrom = [autoxml.String, autoxml.optional]
|
||||||
|
a_releaseTo = [autoxml.String, autoxml.optional]
|
||||||
|
|
||||||
|
def satisfies_relation(self, pkg_name, version, release):
|
||||||
|
ret = True
|
||||||
|
v = pisi.version.Version(version)
|
||||||
|
if self.version:
|
||||||
|
ret &= v == pisi.version.Version(self.version)
|
||||||
|
if self.versionFrom:
|
||||||
|
ret &= v >= pisi.version.Version(self.versionFrom)
|
||||||
|
if self.versionTo:
|
||||||
|
ret &= v <= pisi.version.Version(self.versionTo)
|
||||||
|
r = pisi.version.Version(release)
|
||||||
|
if self.release:
|
||||||
|
ret &= r == pisi.version.Version(self.release)
|
||||||
|
if self.releaseFrom:
|
||||||
|
ret &= r >= pisi.version.Version(self.releaseFrom)
|
||||||
|
if self.releaseTo:
|
||||||
|
ret &= r <= pisi.version.Version(self.releaseTo)
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def installed_package_satisfies(relation):
|
||||||
|
pkg_name = relation.package
|
||||||
|
if not ctx.installdb.is_installed(pkg_name):
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
pkg = ctx.packagedb.get_package(pkg_name, pisi.itembyrepodb.installed)
|
||||||
|
(version, release) = (pkg.version, pkg.release)
|
||||||
|
return relation.satisfies_relation(pkg_name, version, release)
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# Copyright (C) 2005 - 2007, TUBITAK/UEKAE
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it under
|
||||||
|
# the terms of the GNU General Public License as published by the Free
|
||||||
|
# Software Foundation; either version 2 of the License, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
#
|
||||||
|
# Please read the COPYING file.
|
||||||
|
#
|
||||||
|
|
||||||
|
import gettext
|
||||||
|
__trans = gettext.translation('pisi', fallback=True)
|
||||||
|
_ = __trans.ugettext
|
||||||
|
|
||||||
|
import pisi.relation
|
||||||
|
|
||||||
|
""" Replace relation """
|
||||||
|
class Replace(pisi.relation.Relation):
|
||||||
|
def __str__(self):
|
||||||
|
s = self.package
|
||||||
|
if self.versionFrom:
|
||||||
|
s += _(" version >= ") + self.versionFrom
|
||||||
|
if self.versionTo:
|
||||||
|
s += _(" version <= ") + self.versionTo
|
||||||
|
if self.version:
|
||||||
|
s += _(" version ") + self.version
|
||||||
|
if self.releaseFrom:
|
||||||
|
s += _(" release >= ") + self.releaseFrom
|
||||||
|
if self.releaseTo:
|
||||||
|
s += _(" release <= ") + self.releaseTo
|
||||||
|
if self.release:
|
||||||
|
s += _(" release ") + self.release
|
||||||
|
return s
|
||||||
|
|
||||||
|
def installed_package_replaced(repinfo):
|
||||||
|
"""determine if an installed package in *repository* replaced with
|
||||||
|
given a package"""
|
||||||
|
return pisi.relation.installed_package_satisfies(repinfo)
|
||||||
|
|
||||||
@@ -15,10 +15,8 @@ __trans = gettext.translation('pisi', fallback=True)
|
|||||||
_ = __trans.ugettext
|
_ = __trans.ugettext
|
||||||
|
|
||||||
import pisi
|
import pisi
|
||||||
import pisi.db.lockeddbshelve as shelve
|
import pisi.lockeddbshelve as shelve
|
||||||
import pisi.context as ctx
|
import pisi.context as ctx
|
||||||
import pisi.db.packagedb as packagedb
|
|
||||||
import pisi.oo
|
|
||||||
|
|
||||||
class Error(pisi.Error):
|
class Error(pisi.Error):
|
||||||
pass
|
pass
|
||||||
@@ -36,7 +34,6 @@ class Repo:
|
|||||||
|
|
||||||
class RepoDB(object):
|
class RepoDB(object):
|
||||||
"""RepoDB maps repo ids to repository information"""
|
"""RepoDB maps repo ids to repository information"""
|
||||||
__metaclass__ = pisi.oo.Singleton
|
|
||||||
|
|
||||||
def __init__(self, txn = None):
|
def __init__(self, txn = None):
|
||||||
self.d = shelve.LockedDBShelf("repo")
|
self.d = shelve.LockedDBShelf("repo")
|
||||||
@@ -100,10 +97,28 @@ class RepoDB(object):
|
|||||||
name = str(name)
|
name = str(name)
|
||||||
def proc(txn):
|
def proc(txn):
|
||||||
self.d.delete("repo-" + name, txn)
|
self.d.delete("repo-" + name, txn)
|
||||||
list = self.d.get("order", txn)
|
l = self.d.get("order", txn)
|
||||||
list.remove(name)
|
l.remove(name)
|
||||||
self.d.put("order", list, txn)
|
self.d.put("order", l, txn)
|
||||||
ctx.packagedb.remove_repo(name, txn=txn)
|
ctx.packagedb.remove_repo(name, txn=txn)
|
||||||
ctx.sourcedb.remove_repo(name, txn=txn)
|
ctx.sourcedb.remove_repo(name, txn=txn)
|
||||||
ctx.componentdb.remove_repo(name, txn=txn)
|
ctx.componentdb.remove_repo(name, txn=txn)
|
||||||
self.d.txn_proc(proc, txn)
|
self.d.txn_proc(proc, txn)
|
||||||
|
|
||||||
|
db = None
|
||||||
|
|
||||||
|
def init():
|
||||||
|
global db
|
||||||
|
|
||||||
|
if db:
|
||||||
|
return db
|
||||||
|
|
||||||
|
db = RepoDB()
|
||||||
|
return db
|
||||||
|
|
||||||
|
def finalize():
|
||||||
|
global db
|
||||||
|
|
||||||
|
if db:
|
||||||
|
db.close()
|
||||||
|
db = None
|
||||||
@@ -25,19 +25,17 @@ __trans = gettext.translation('pisi', fallback=True)
|
|||||||
_ = __trans.ugettext
|
_ = __trans.ugettext
|
||||||
|
|
||||||
import pisi.context as ctx
|
import pisi.context as ctx
|
||||||
import pisi.db.repodb
|
import pisi.repodb
|
||||||
import pisi.db.itembyrepodb as itembyrepodb
|
import pisi.itembyrepodb
|
||||||
import pisi.oo
|
|
||||||
|
|
||||||
class NotfoundError(pisi.Error):
|
class NotfoundError(pisi.Error):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class SourceDB(object):
|
class SourceDB(object):
|
||||||
__metaclass__ = pisi.oo.Singleton
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.d = itembyrepodb.ItemByRepoDB('source')
|
self.d = pisi.itembyrepodb.ItemByRepoDB('source')
|
||||||
self.dpkgtosrc = itembyrepodb.ItemByRepoDB('pkgtosrc')
|
self.dpkgtosrc = pisi.itembyrepodb.ItemByRepoDB('pkgtosrc')
|
||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
self.d.close()
|
self.d.close()
|
||||||
@@ -52,13 +50,13 @@ class SourceDB(object):
|
|||||||
def get_spec(self, name, repo=None, txn = None):
|
def get_spec(self, name, repo=None, txn = None):
|
||||||
try:
|
try:
|
||||||
return self.d.get_item(name, repo, txn)
|
return self.d.get_item(name, repo, txn)
|
||||||
except pisi.db.itembyrepodb.NotfoundError, e:
|
except pisi.itembyrepodb.NotfoundError:
|
||||||
raise NotfoundError(_("Source package %s not found") % name)
|
raise NotfoundError(_("Source package %s not found") % name)
|
||||||
|
|
||||||
def get_spec_repo(self, name, repo=None, txn = None):
|
def get_spec_repo(self, name, repo=None, txn = None):
|
||||||
try:
|
try:
|
||||||
return self.d.get_item_repo(name, repo, txn)
|
return self.d.get_item_repo(name, repo, txn)
|
||||||
except pisi.db.itembyrepodb.NotfoundError, e:
|
except pisi.itembyrepodb.NotfoundError:
|
||||||
raise NotfoundError(_("Source package %s not found") % name)
|
raise NotfoundError(_("Source package %s not found") % name)
|
||||||
|
|
||||||
def pkgtosrc(self, name, txn = None):
|
def pkgtosrc(self, name, txn = None):
|
||||||
@@ -83,6 +81,7 @@ class SourceDB(object):
|
|||||||
for pkg in spec.packages:
|
for pkg in spec.packages:
|
||||||
self.dpkgtosrc.remove_item_repo(pkg.name, repo, txn)
|
self.dpkgtosrc.remove_item_repo(pkg.name, repo, txn)
|
||||||
ctx.componentdb.remove_spec(spec.source.partOf, spec.source.name, repo, txn)
|
ctx.componentdb.remove_spec(spec.source.partOf, spec.source.name, repo, txn)
|
||||||
|
|
||||||
self.d.txn_proc(proc, txn)
|
self.d.txn_proc(proc, txn)
|
||||||
|
|
||||||
def remove_repo(self, repo, txn = None):
|
def remove_repo(self, repo, txn = None):
|
||||||
@@ -90,3 +89,19 @@ class SourceDB(object):
|
|||||||
self.d.remove_repo(repo, txn=txn)
|
self.d.remove_repo(repo, txn=txn)
|
||||||
self.dpkgtosrc.remove_repo(repo, txn=txn)
|
self.dpkgtosrc.remove_repo(repo, txn=txn)
|
||||||
self.d.txn_proc(proc, txn)
|
self.d.txn_proc(proc, txn)
|
||||||
|
|
||||||
|
sourcedb = None
|
||||||
|
|
||||||
|
def init():
|
||||||
|
global sourcedb
|
||||||
|
if sourcedb:
|
||||||
|
return sourcedb
|
||||||
|
|
||||||
|
sourcedb = SourceDB()
|
||||||
|
return sourcedb
|
||||||
|
|
||||||
|
def finalize():
|
||||||
|
global sourcedb
|
||||||
|
if sourcedb:
|
||||||
|
sourcedb.close()
|
||||||
|
sourcedb = None
|
||||||
+22
-2
@@ -22,12 +22,14 @@ _ = __trans.ugettext
|
|||||||
|
|
||||||
# standard python modules
|
# standard python modules
|
||||||
import os.path
|
import os.path
|
||||||
|
import piksemel
|
||||||
|
|
||||||
# pisi modules
|
# pisi modules
|
||||||
import pisi.pxml.xmlfile as xmlfile
|
import pisi.pxml.xmlfile as xmlfile
|
||||||
import pisi.pxml.autoxml as autoxml
|
import pisi.pxml.autoxml as autoxml
|
||||||
import pisi.context as ctx
|
import pisi.context as ctx
|
||||||
import pisi.dependency
|
import pisi.dependency
|
||||||
|
import pisi.replace
|
||||||
import pisi.conflict
|
import pisi.conflict
|
||||||
import pisi.component as component
|
import pisi.component as component
|
||||||
import pisi.util as util
|
import pisi.util as util
|
||||||
@@ -170,8 +172,8 @@ class Package:
|
|||||||
t_ComponentDependencies = [ [autoxml.String], autoxml.optional, "RuntimeDependencies/Component"]
|
t_ComponentDependencies = [ [autoxml.String], autoxml.optional, "RuntimeDependencies/Component"]
|
||||||
t_Files = [ [Path], autoxml.optional]
|
t_Files = [ [Path], autoxml.optional]
|
||||||
t_Conflicts = [ [pisi.conflict.Conflict], autoxml.optional, "Conflicts/Package"]
|
t_Conflicts = [ [pisi.conflict.Conflict], autoxml.optional, "Conflicts/Package"]
|
||||||
|
t_Replaces = [ [pisi.replace.Replace], autoxml.optional, "Replaces/Package"]
|
||||||
t_ProvidesComar = [ [ComarProvide], autoxml.optional, "Provides/COMAR"]
|
t_ProvidesComar = [ [ComarProvide], autoxml.optional, "Provides/COMAR"]
|
||||||
#t_RequiresComar = [ [autoxml.String], autoxml.mandatory, "Requires/COMAR"]
|
|
||||||
t_AdditionalFiles = [ [AdditionalFile], autoxml.optional]
|
t_AdditionalFiles = [ [AdditionalFile], autoxml.optional]
|
||||||
t_History = [ [Update], autoxml.optional]
|
t_History = [ [Update], autoxml.optional]
|
||||||
|
|
||||||
@@ -181,7 +183,7 @@ class Package:
|
|||||||
|
|
||||||
def runtimeDependencies(self):
|
def runtimeDependencies(self):
|
||||||
deps = self.packageDependencies
|
deps = self.packageDependencies
|
||||||
deps += [ ctx.componentdb.get_component(x).packages for x in self.componentDependencies ]
|
deps += [ ctx.componentdb.get_component[x].packages for x in self.componentDependencies ]
|
||||||
return deps
|
return deps
|
||||||
|
|
||||||
def pkg_dir(self):
|
def pkg_dir(self):
|
||||||
@@ -239,3 +241,21 @@ class SpecFile(xmlfile.XmlFile):
|
|||||||
#http://liste.pardus.org.tr/gelistirici/2006-September/002332.html
|
#http://liste.pardus.org.tr/gelistirici/2006-September/002332.html
|
||||||
self.source.description = autoxml.LocalText("Description")
|
self.source.description = autoxml.LocalText("Description")
|
||||||
self.source.description["en"] = self.source.summary["en"]
|
self.source.description["en"] = self.source.summary["en"]
|
||||||
|
|
||||||
|
def _set_i18n(self, tag, inst):
|
||||||
|
for summary in tag.tags("Summary"):
|
||||||
|
inst.summary[summary.getAttribute("xml:lang")] = summary.firstChild().data()
|
||||||
|
for desc in tag.tags("Description"):
|
||||||
|
inst.description[desc.getAttribute("xml:lang")] = desc.firstChild().data()
|
||||||
|
|
||||||
|
def read_translations(self, path):
|
||||||
|
if not os.path.exists(path):
|
||||||
|
return
|
||||||
|
doc = piksemel.parse(path)
|
||||||
|
|
||||||
|
self._set_i18n(doc.getTag("Source"), self.source)
|
||||||
|
for pak in doc.tags("Package"):
|
||||||
|
for inst in self.packages:
|
||||||
|
if inst.name == pak.getTagData("Name"):
|
||||||
|
break
|
||||||
|
self._set_i18n(pak, inst)
|
||||||
|
|||||||
@@ -12,11 +12,6 @@
|
|||||||
# generic user interface
|
# generic user interface
|
||||||
#
|
#
|
||||||
|
|
||||||
import sys
|
|
||||||
|
|
||||||
import pisi
|
|
||||||
import pisi.context as ctx
|
|
||||||
|
|
||||||
(installed, upgraded, removed, installing, removing, configuring, configured, extracting,
|
(installed, upgraded, removed, installing, removing, configuring, configured, extracting,
|
||||||
downloading, packagestogo, updatingrepo, cached) = range(12)
|
downloading, packagestogo, updatingrepo, cached) = range(12)
|
||||||
|
|
||||||
|
|||||||
+14
-22
@@ -57,6 +57,9 @@ def every(pred, seq):
|
|||||||
def any(pred, seq):
|
def any(pred, seq):
|
||||||
return reduce(operator.or_, map(pred, seq), False)
|
return reduce(operator.or_, map(pred, seq), False)
|
||||||
|
|
||||||
|
def unzip(seq):
|
||||||
|
return zip(*seq)
|
||||||
|
|
||||||
def concat(l):
|
def concat(l):
|
||||||
"""Concatenate a list of lists."""
|
"""Concatenate a list of lists."""
|
||||||
return reduce( operator.concat, l )
|
return reduce( operator.concat, l )
|
||||||
@@ -262,12 +265,12 @@ def check_file(file, mode = os.F_OK):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
# FIXME: check_dir is not a good name considering it can also create the dir
|
# FIXME: check_dir is not a good name considering it can also create the dir
|
||||||
def check_dir(dir):
|
def check_dir(d):
|
||||||
"""Make sure given directory path exists."""
|
"""Make sure given directory path exists."""
|
||||||
# FIXME: What is first strip doing there?
|
# FIXME: What is first strip doing there?
|
||||||
dir = dir.strip().rstrip("/")
|
d = d.strip().rstrip("/")
|
||||||
if not os.access(dir, os.F_OK):
|
if not os.access(d, os.F_OK):
|
||||||
os.makedirs(dir)
|
os.makedirs(d)
|
||||||
|
|
||||||
def clean_dir(path):
|
def clean_dir(path):
|
||||||
"""Remove all content of a directory."""
|
"""Remove all content of a directory."""
|
||||||
@@ -294,7 +297,7 @@ def dir_size(dir):
|
|||||||
return os.path.getsize(dir)
|
return os.path.getsize(dir)
|
||||||
|
|
||||||
if os.path.islink(dir):
|
if os.path.islink(dir):
|
||||||
return 0
|
return long(len(os.readlink(dir)))
|
||||||
|
|
||||||
def sizes():
|
def sizes():
|
||||||
for root, dirs, files in os.walk(dir):
|
for root, dirs, files in os.walk(dir):
|
||||||
@@ -390,8 +393,8 @@ def get_file_hashes(top, excludePrefix=None, removePrefix=None):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
#bug 397
|
#bug 397
|
||||||
for dir in dirs:
|
for directory in dirs:
|
||||||
d = join_path(root, dir)
|
d = join_path(root, directory)
|
||||||
if os.path.islink(d) and not has_excluded_prefix(d):
|
if os.path.islink(d) and not has_excluded_prefix(d):
|
||||||
yield (d, sha1_sum(os.readlink(d), True))
|
yield (d, sha1_sum(os.readlink(d), True))
|
||||||
excludePrefix.append(remove_prefix(removePrefix, d) + "/")
|
excludePrefix.append(remove_prefix(removePrefix, d) + "/")
|
||||||
@@ -452,7 +455,7 @@ def sha1_data(data):
|
|||||||
return m.hexdigest()
|
return m.hexdigest()
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
raise
|
raise
|
||||||
except Exception, e: #FIXME: what exception could we catch here, replace with that.
|
except Exception: #FIXME: what exception could we catch here, replace with that.
|
||||||
raise Error(_("Cannot calculate SHA1 hash of given data"))
|
raise Error(_("Cannot calculate SHA1 hash of given data"))
|
||||||
|
|
||||||
def uncompress(patchFile, compressType="gz", targetDir=None):
|
def uncompress(patchFile, compressType="gz", targetDir=None):
|
||||||
@@ -497,8 +500,8 @@ def do_patch(sourceDir, patchFile, level = 0):
|
|||||||
(ret, out, err) = run_batch('quilt push')
|
(ret, out, err) = run_batch('quilt push')
|
||||||
else:
|
else:
|
||||||
# run GNU patch to apply original patch into tree
|
# run GNU patch to apply original patch into tree
|
||||||
(ret, out, err) = run_batch("patch --remove-empty-files -p%d < \"%s\"" %
|
(ret, out, err) = run_batch("patch --remove-empty-files -p%d < \"%s\"" % (level, patchFile))
|
||||||
(level, patchFile))
|
|
||||||
if ret:
|
if ret:
|
||||||
if out is None and err is None:
|
if out is None and err is None:
|
||||||
# Which means stderr and stdout directed so they are None
|
# Which means stderr and stdout directed so they are None
|
||||||
@@ -614,24 +617,13 @@ def is_package_name(fn, package_name = None):
|
|||||||
# get version string, skip separator '-'
|
# get version string, skip separator '-'
|
||||||
verstr = fn[len(package_name) + 1:
|
verstr = fn[len(package_name) + 1:
|
||||||
len(fn)-len(ctx.const.package_suffix)]
|
len(fn)-len(ctx.const.package_suffix)]
|
||||||
import string
|
|
||||||
for x in verstr.split('-'):
|
for x in verstr.split('-'):
|
||||||
# weak rule: version components after '-' start with a digit
|
# weak rule: version components after '-' start with a digit
|
||||||
if x is '' or (not x[0] in string.digits):
|
if x == '' or (not x[0] in string.digits):
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def env_update():
|
|
||||||
import pisi.environment
|
|
||||||
ctx.ui.info(_('Updating environment...'))
|
|
||||||
|
|
||||||
env_dir = join_path(ctx.config.dest_dir(), "/etc/env.d")
|
|
||||||
if not os.path.exists(env_dir):
|
|
||||||
os.makedirs(env_dir, 0755)
|
|
||||||
|
|
||||||
pisi.environment.update_environment(ctx.config.dest_dir())
|
|
||||||
|
|
||||||
def parse_package_name(package_name):
|
def parse_package_name(package_name):
|
||||||
"""Separate package name and version string.
|
"""Separate package name and version string.
|
||||||
|
|
||||||
|
|||||||
+531
-474
File diff suppressed because it is too large
Load Diff
-2710
File diff suppressed because it is too large
Load Diff
+8
-1
@@ -1,2 +1,9 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
pisi li -i | grep None
|
|
||||||
|
b=/var/lib/pisi/package
|
||||||
|
|
||||||
|
for d in `ls $b`;do
|
||||||
|
if ! grep "<Build>" $b/$d/metadata.xml &>/dev/null ; then
|
||||||
|
echo "$d"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ def cleanPisis(clean, root = '/var/cache/pisi/packages'):
|
|||||||
l = findUnneededFiles(list)
|
l = findUnneededFiles(list)
|
||||||
doit(root, l, clean, ".pisi")
|
doit(root, l, clean, ".pisi")
|
||||||
|
|
||||||
def cleanBuilds(clean, root = '/var/pisi'):
|
def cleanBuilds(clean, root = '/var/tmp/pisi'):
|
||||||
# Build remnant
|
# Build remnant
|
||||||
list = []
|
list = []
|
||||||
for f in os.listdir(root):
|
for f in os.listdir(root):
|
||||||
|
|||||||
Executable
+84
@@ -0,0 +1,84 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import codecs
|
||||||
|
import xml.dom.minidom as mdom
|
||||||
|
|
||||||
|
def find_pspecs(folder):
|
||||||
|
paks = []
|
||||||
|
for root, dirs, files in os.walk(folder):
|
||||||
|
if "pspec.xml" in files:
|
||||||
|
paks.append(root)
|
||||||
|
# dont walk into the versioned stuff
|
||||||
|
if ".svn" in dirs:
|
||||||
|
dirs.remove(".svn")
|
||||||
|
return paks
|
||||||
|
|
||||||
|
def addText(doc, parent, text):
|
||||||
|
cdata =doc.createTextNode(text)
|
||||||
|
parent.appendChild(cdata)
|
||||||
|
|
||||||
|
def getTags(parent, childName):
|
||||||
|
return [x for x in parent.childNodes if x.nodeType == x.ELEMENT_NODE if x.tagName == childName]
|
||||||
|
|
||||||
|
def getNodeText(node, tag, default=None):
|
||||||
|
try:
|
||||||
|
c = getTags(node, tag)[0].firstChild.data
|
||||||
|
except:
|
||||||
|
c = default
|
||||||
|
return c
|
||||||
|
|
||||||
|
def newNode(doc, tag, text):
|
||||||
|
node = doc.createElement(tag)
|
||||||
|
cdata = doc.createTextNode(text)
|
||||||
|
node.appendChild(cdata)
|
||||||
|
return node
|
||||||
|
|
||||||
|
def fixIndent(doc, node):
|
||||||
|
for x in node.childNodes:
|
||||||
|
if x.nodeType == x.ELEMENT_NODE:
|
||||||
|
if x.tagName == "Update":
|
||||||
|
fixIndent(doc, x)
|
||||||
|
else:
|
||||||
|
x.data = "\n" + x.data[5:]
|
||||||
|
|
||||||
|
def fixTags(doc, hist):
|
||||||
|
for update in hist.childNodes:
|
||||||
|
if update.nodeType == update.ELEMENT_NODE:
|
||||||
|
rno = getNodeText(update, "Release")
|
||||||
|
update.setAttribute("release", rno)
|
||||||
|
if rno == "1":
|
||||||
|
comment = newNode(doc, "Comment", "First release.")
|
||||||
|
paker = getTags(getTags(doc.documentElement, "Source")[0], "Packager")[0]
|
||||||
|
name = newNode(doc, "Name", getNodeText(paker, "Name"))
|
||||||
|
email = newNode(doc, "Email", getNodeText(paker, "Email"))
|
||||||
|
else:
|
||||||
|
comment = newNode(doc, "Comment", "FIXHISTORY")
|
||||||
|
name = newNode(doc, "Name", "FIXHISTORY")
|
||||||
|
email = newNode(doc, "Email", "FIXHISTORY")
|
||||||
|
update.replaceChild(comment, getTags(update, "Release")[0])
|
||||||
|
addText(doc, update, " ")
|
||||||
|
update.appendChild(name)
|
||||||
|
addText(doc, update, "\n ")
|
||||||
|
update.appendChild(email)
|
||||||
|
addText(doc, update, "\n ")
|
||||||
|
|
||||||
|
def fixPspec(path):
|
||||||
|
doc = mdom.parse(path)
|
||||||
|
pisi = doc.documentElement
|
||||||
|
source = getTags(pisi, "Source")[0]
|
||||||
|
history = getTags(source, "History")[0]
|
||||||
|
item = source.removeChild(history)
|
||||||
|
addText(doc, pisi, "\n ")
|
||||||
|
fixIndent(doc, item)
|
||||||
|
fixTags(doc, item)
|
||||||
|
pisi.appendChild(item)
|
||||||
|
addText(doc, pisi, "\n")
|
||||||
|
f = codecs.open(path,'w', "utf-8")
|
||||||
|
f.write(doc.toxml())
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
pakages = find_pspecs(sys.argv[1])
|
||||||
|
for pak in pakages:
|
||||||
|
fixPspec(os.path.join(pak, "pspec.xml"))
|
||||||
+11
-16
@@ -14,8 +14,7 @@ import string
|
|||||||
|
|
||||||
packagerfile = ".pisipackager"
|
packagerfile = ".pisipackager"
|
||||||
|
|
||||||
data = {"date": time.strftime("%Y-%m-%d"),
|
data = {"date": time.strftime("%Y-%m-%d")}
|
||||||
"year": time.strftime("%Y")}
|
|
||||||
|
|
||||||
temp_pspec = '''<?xml version="1.0" ?>
|
temp_pspec = '''<?xml version="1.0" ?>
|
||||||
<!DOCTYPE PISI SYSTEM "http://www.pardus.org.tr/projeler/pisi/pisi-spec.dtd">
|
<!DOCTYPE PISI SYSTEM "http://www.pardus.org.tr/projeler/pisi/pisi-spec.dtd">
|
||||||
@@ -28,20 +27,21 @@ temp_pspec = '''<?xml version="1.0" ?>
|
|||||||
<Email>%(packager_email)s</Email>
|
<Email>%(packager_email)s</Email>
|
||||||
</Packager>
|
</Packager>
|
||||||
<License>GPL-2</License>
|
<License>GPL-2</License>
|
||||||
<Icon>%(package)s</Icon>
|
|
||||||
<IsA>app:gui</IsA>
|
<IsA>app:gui</IsA>
|
||||||
<Summary></Summary>
|
<Summary></Summary>
|
||||||
<Description></Description>
|
<Description></Description>
|
||||||
|
<Summary xml:lang="tr"></Summary>
|
||||||
|
<Description xml:lang="tr"></Description>
|
||||||
<Archive sha1sum="" type="targz"></Archive>
|
<Archive sha1sum="" type="targz"></Archive>
|
||||||
<BuildDependencies>
|
<BuildDependencies>
|
||||||
<Dependency versionFrom=""></Dependency>
|
<Dependency versionFrom=""></Dependency>
|
||||||
<Dependency></Dependency>
|
<Dependency></Dependency>
|
||||||
</BuildDependencies>
|
</BuildDependencies>
|
||||||
<!--
|
|
||||||
<Patches>
|
<Patches>
|
||||||
|
<!--
|
||||||
<Patch level="1"></Patch>
|
<Patch level="1"></Patch>
|
||||||
</Patches>
|
|
||||||
-->
|
-->
|
||||||
|
</Patches>
|
||||||
</Source>
|
</Source>
|
||||||
|
|
||||||
<Package>
|
<Package>
|
||||||
@@ -51,17 +51,15 @@ temp_pspec = '''<?xml version="1.0" ?>
|
|||||||
<Files>
|
<Files>
|
||||||
<Path fileType="data">/</Path>
|
<Path fileType="data">/</Path>
|
||||||
</Files>
|
</Files>
|
||||||
<!--
|
|
||||||
<AdditionalFiles>
|
<AdditionalFiles>
|
||||||
<AdditionalFile owner="root" permission="0644" target="/usr/share/applications/%(package)s.desktop">%(package)s.desktop</AdditionalFile>
|
|
||||||
</AdditionalFiles>
|
|
||||||
-->
|
|
||||||
<!--
|
<!--
|
||||||
|
<AdditionalFile owner="root" permission="0644" target="/usr/share/applications/%(package)s.desktop">%(package)s.desktop</AdditionalFile>
|
||||||
|
-->
|
||||||
|
</AdditionalFiles>
|
||||||
<Provides>
|
<Provides>
|
||||||
<COMAR script="package.py">System.Package</COMAR>
|
<COMAR script="package.py">System.Package</COMAR>
|
||||||
<COMAR script="service.py">System.Service</COMAR>
|
<COMAR script="service.py">System.Service</COMAR>
|
||||||
</Provides>
|
</Provides>
|
||||||
-->
|
|
||||||
</Package>
|
</Package>
|
||||||
|
|
||||||
<History>
|
<History>
|
||||||
@@ -79,7 +77,7 @@ temp_pspec = '''<?xml version="1.0" ?>
|
|||||||
temp_actions = '''#!/usr/bin/python
|
temp_actions = '''#!/usr/bin/python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright %(year)s TUBITAK/UEKAE
|
# Copyright 2006 TUBITAK/UEKAE
|
||||||
# Licensed under the GNU General Public License, version 2.
|
# Licensed under the GNU General Public License, version 2.
|
||||||
# See the file http://www.gnu.org/copyleft/gpl.txt.
|
# See the file http://www.gnu.org/copyleft/gpl.txt.
|
||||||
|
|
||||||
@@ -119,13 +117,10 @@ Categories=Application;Game;ArcadeGame
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
temp_service = '''serviceType = "local"
|
temp_service = '''serviceType = "local"
|
||||||
from comar.service import *
|
serviceDesc = "%(package_cap)s"
|
||||||
|
|
||||||
serviceType = "local"
|
|
||||||
serviceDefault = "off"
|
serviceDefault = "off"
|
||||||
|
|
||||||
serviceDesc = _({"en": "%(package_cap)s",
|
from comar.service import *
|
||||||
"tr": "%(package_cap)s"})
|
|
||||||
|
|
||||||
def start():
|
def start():
|
||||||
if 0 == run('/sbin/start-stop-daemon --quiet --start --exec /usr/bin/%(package)s --pidfile /var/run/%(package)s.pid'):
|
if 0 == run('/sbin/start-stop-daemon --quiet --start --exec /usr/bin/%(package)s --pidfile /var/run/%(package)s.pid'):
|
||||||
|
|||||||
Executable
+92
@@ -0,0 +1,92 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# Copyright (C) 2005, TUBITAK/UEKAE
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it under
|
||||||
|
# the terms of the GNU General Public License as published by the Free
|
||||||
|
# Software Foundation; either version 2 of the License, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
#
|
||||||
|
# Please read the COPYING file.
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
from pisi.specfile import SpecFile
|
||||||
|
from pisi.util import join_path
|
||||||
|
|
||||||
|
def findPspec(folder):
|
||||||
|
pspecList = []
|
||||||
|
for root, dirs, files in os.walk(folder):
|
||||||
|
if "pspec.xml" in files:
|
||||||
|
pspecList.append(root)
|
||||||
|
# dont walk into the versioned stuff
|
||||||
|
if ".svn" in dirs:
|
||||||
|
dirs.remove(".svn")
|
||||||
|
return pspecList
|
||||||
|
|
||||||
|
def getVersion(pspecList):
|
||||||
|
sources = {}
|
||||||
|
for pspec in pspecList:
|
||||||
|
specFile = SpecFile(join_path(pspec, "pspec.xml"))
|
||||||
|
sources[specFile.source.name] = (specFile.source.version, specFile.source.release)
|
||||||
|
return sources
|
||||||
|
|
||||||
|
def listIntersection(firstRepo, secondRepo):
|
||||||
|
keys = list(set(firstRepo.keys()).__and__(set(secondRepo.keys())))
|
||||||
|
keys.sort()
|
||||||
|
for i in keys:
|
||||||
|
if firstRepo[i] != secondRepo[i]:
|
||||||
|
print " %s: %s (r%s) -> %s (r%s)" % (i, firstRepo[i][0], firstRepo[i][1], secondRepo[i][0], secondRepo[i][1])
|
||||||
|
|
||||||
|
def listComplement(firstRepo, secondRepo):
|
||||||
|
keys = list(set(firstRepo.keys()) - set(secondRepo.keys()))
|
||||||
|
keys.sort()
|
||||||
|
for i in keys:
|
||||||
|
print " %s" % i
|
||||||
|
|
||||||
|
def usage(miniMe):
|
||||||
|
print """Usage:
|
||||||
|
%s pathToSvn component (ex: %s /home/caglar/svn/pardus/ system/devel)
|
||||||
|
""" % (miniMe, miniMe)
|
||||||
|
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
svnRoot = sys.argv[1]
|
||||||
|
except IndexError:
|
||||||
|
usage(sys.argv[0])
|
||||||
|
|
||||||
|
try:
|
||||||
|
postfix = sys.argv[2]
|
||||||
|
except IndexError:
|
||||||
|
postfix = ""
|
||||||
|
|
||||||
|
tag = getVersion(findPspec(join_path(svnRoot, "tags/pardus-1.0/", postfix)))
|
||||||
|
stable = getVersion(findPspec(join_path(svnRoot,"stable/pardus-1/", postfix)))
|
||||||
|
devel = getVersion(findPspec(join_path(svnRoot, "devel/", postfix)))
|
||||||
|
|
||||||
|
print "Tag --> Stable"
|
||||||
|
listIntersection(tag, stable)
|
||||||
|
print
|
||||||
|
|
||||||
|
print "Tag has, Stable hasn't"
|
||||||
|
listComplement(tag, stable)
|
||||||
|
print
|
||||||
|
|
||||||
|
print "Stable has, Tag hasn't"
|
||||||
|
listComplement(stable, tag)
|
||||||
|
print
|
||||||
|
|
||||||
|
print "Stable --> Devel"
|
||||||
|
listIntersection(stable, devel)
|
||||||
|
print
|
||||||
|
|
||||||
|
print "Stable has, Devel hasn't"
|
||||||
|
listComplement(stable, devel)
|
||||||
|
print
|
||||||
|
|
||||||
|
print "Devel has, Stable hasn't"
|
||||||
|
listComplement(devel, stable)
|
||||||
|
print
|
||||||
Executable
+598
@@ -0,0 +1,598 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
#
|
||||||
|
# Copyright (C) 2005-2007, TUBITAK/UEKAE
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify it under
|
||||||
|
# the terms of the GNU General Public License as published by the Free
|
||||||
|
# Software Foundation; either version 2 of the License, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
#
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
import codecs
|
||||||
|
import re
|
||||||
|
import getopt
|
||||||
|
|
||||||
|
import gettext
|
||||||
|
__trans = gettext.translation('pisi', fallback=True)
|
||||||
|
_ = __trans.ugettext
|
||||||
|
|
||||||
|
from svn import core, client
|
||||||
|
|
||||||
|
sys.path.append('.')
|
||||||
|
import pisi.specfile
|
||||||
|
import pisi.uri
|
||||||
|
import pisi.package
|
||||||
|
import pisi.metadata
|
||||||
|
import pisi.files
|
||||||
|
from pisi.cli import printu
|
||||||
|
|
||||||
|
# Main HTML template
|
||||||
|
|
||||||
|
html_header = """
|
||||||
|
<html><head>
|
||||||
|
<title>%(title)s</title>
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||||
|
<link href="%(root)sstil.css" rel="stylesheet" type="text/css">
|
||||||
|
</head><body>
|
||||||
|
<div id='header-bugzilla'>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class='menu'>
|
||||||
|
<a href='%(root)sindex.html'>Genel Bilgiler</a>
|
||||||
|
| <a href='%(root)ssources.html'>Kaynak Paketler</a>
|
||||||
|
| <a href='%(root)sbinaries.html'>İkili Paketler</a>
|
||||||
|
| <a href='%(root)spackagers.html'>Paketçiler</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h1 align='center'>%(title)s</h1>
|
||||||
|
|
||||||
|
<div class='content'>
|
||||||
|
%(content)s
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body></html>
|
||||||
|
"""
|
||||||
|
|
||||||
|
css_template = """
|
||||||
|
body {
|
||||||
|
margin-left:0;
|
||||||
|
margin-top:0;
|
||||||
|
margin-right:0;
|
||||||
|
background-image:url('http://www.pardus.org.tr/styles/images/HeadTile.png');
|
||||||
|
background-repeat:repeat-x;
|
||||||
|
background-color: #FFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
#header-bugzilla {
|
||||||
|
background-image:url('http://www.pardus.org.tr/styles/images/HeadLogo.png');
|
||||||
|
background-repeat:no-repeat;
|
||||||
|
background-position: 0px 0px;
|
||||||
|
height:119px;
|
||||||
|
padding-bottom:5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: #F55400;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
color: #444;
|
||||||
|
background-color:#EEE;
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu {
|
||||||
|
padding-left: 1em;
|
||||||
|
padding-top: 3px;
|
||||||
|
padding-bottom: 3px;
|
||||||
|
border-bottom: 1px solid #CCC;
|
||||||
|
border-top: 1px solid #CCC;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
margin: 0.5em;
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
# default html templates (now obsolete)
|
||||||
|
|
||||||
|
def_repo_sizes_html = u"""
|
||||||
|
<h3>Boyutlar</h3>
|
||||||
|
<p>Toplam kurulu boyut %(total)s</p>
|
||||||
|
<p>Dosya tiplerine göre liste:</p>
|
||||||
|
<table><tbody>
|
||||||
|
%(sizes)s
|
||||||
|
</table></tbody>
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def svn_uri(path):
|
||||||
|
# init
|
||||||
|
core.apr_initialize()
|
||||||
|
pool = core.svn_pool_create(None)
|
||||||
|
core.svn_config_ensure(None, pool)
|
||||||
|
# get commit date
|
||||||
|
uri = client.svn_client_url_from_path(path, pool)
|
||||||
|
# cleanup
|
||||||
|
core.svn_pool_destroy(pool)
|
||||||
|
core.apr_terminate()
|
||||||
|
return uri
|
||||||
|
|
||||||
|
|
||||||
|
def find_pspecs(folder):
|
||||||
|
paks = []
|
||||||
|
for root, dirs, files in os.walk(folder):
|
||||||
|
if "pspec.xml" in files:
|
||||||
|
paks.append(root)
|
||||||
|
# dont walk into the versioned stuff
|
||||||
|
if ".svn" in dirs:
|
||||||
|
dirs.remove(".svn")
|
||||||
|
return paks
|
||||||
|
|
||||||
|
def write_html(filename, title, content):
|
||||||
|
f = codecs.open(filename, "w", "utf-8")
|
||||||
|
root = "./"
|
||||||
|
if len(filename.split("/")) > 2:
|
||||||
|
root = "../"
|
||||||
|
dict = {
|
||||||
|
"title": title,
|
||||||
|
"content": content,
|
||||||
|
"root": root,
|
||||||
|
}
|
||||||
|
f.write(html_header % dict)
|
||||||
|
f.close()
|
||||||
|
|
||||||
|
def make_table(elements, titles=None):
|
||||||
|
def make_row(element):
|
||||||
|
return "<td>%s" % "<td>".join(map(str, element))
|
||||||
|
|
||||||
|
title_html = ""
|
||||||
|
if titles:
|
||||||
|
title_html = """
|
||||||
|
<thead><tr><th>%s</tr></thead>
|
||||||
|
""" % "<th>".join(titles)
|
||||||
|
|
||||||
|
html = """
|
||||||
|
<table>%s<tbody>
|
||||||
|
<tr>%s
|
||||||
|
</tbody></table>
|
||||||
|
""" % (title_html, "<tr>".join(map(make_row, elements)))
|
||||||
|
|
||||||
|
return html
|
||||||
|
|
||||||
|
def make_url(name, path="./"):
|
||||||
|
if not path.endswith("/"):
|
||||||
|
path += "/"
|
||||||
|
return "<a href='%s%s.html'>%s</a>" % (path, name, name)
|
||||||
|
|
||||||
|
def mangle_email(email):
|
||||||
|
return re.sub("@", " [at] ", email)
|
||||||
|
|
||||||
|
|
||||||
|
class Histogram:
|
||||||
|
def __init__(self):
|
||||||
|
self.list = {}
|
||||||
|
|
||||||
|
def add(self, name, value=None):
|
||||||
|
if value:
|
||||||
|
self.list[name] = value
|
||||||
|
else:
|
||||||
|
self.list[name] = self.list.get(name, 0) + 1
|
||||||
|
|
||||||
|
def note(self, name):
|
||||||
|
if not self.list.has_key(name):
|
||||||
|
self.list[name] = 0
|
||||||
|
|
||||||
|
def get_list(self, max=0):
|
||||||
|
items = self.list.items()
|
||||||
|
items.sort(key=lambda x: x[1], reverse=True)
|
||||||
|
if max != 0:
|
||||||
|
return items[:max]
|
||||||
|
else:
|
||||||
|
return items
|
||||||
|
|
||||||
|
|
||||||
|
# Dictionary of all source packages keyed by the source name
|
||||||
|
sources = {}
|
||||||
|
|
||||||
|
# Dictionary of all binary packages keyed by the package name
|
||||||
|
packages = {}
|
||||||
|
|
||||||
|
# Dictionary of all packagers keyed by the packager name
|
||||||
|
packagers = {}
|
||||||
|
|
||||||
|
# Dictionary of missing depended binary packages keyed by the package name
|
||||||
|
missing = {}
|
||||||
|
|
||||||
|
# List of all repository problems
|
||||||
|
errors = []
|
||||||
|
|
||||||
|
|
||||||
|
class Missing:
|
||||||
|
def __init__(self, name):
|
||||||
|
missing[name] = self
|
||||||
|
self.name = name
|
||||||
|
self.revBuildDeps = []
|
||||||
|
self.revRuntimeDeps = []
|
||||||
|
|
||||||
|
|
||||||
|
class Package:
|
||||||
|
def __init__(self, source, pakspec):
|
||||||
|
name = pakspec.name
|
||||||
|
if packages.has_key(name):
|
||||||
|
errors.append(_("Duplicate binary packages:\n%s\n%s\n") % (
|
||||||
|
source.name, packages[name].source.name))
|
||||||
|
return
|
||||||
|
packages[name] = self
|
||||||
|
self.name = name
|
||||||
|
self.source = source
|
||||||
|
self.pakspec = pakspec
|
||||||
|
self.revBuildDeps = []
|
||||||
|
self.revRuntimeDeps = []
|
||||||
|
self.installedSize = 0
|
||||||
|
|
||||||
|
def markDeps(self):
|
||||||
|
# mark reverse build dependencies
|
||||||
|
for d in self.source.spec.source.buildDependencies:
|
||||||
|
p = d.package
|
||||||
|
if packages.has_key(p):
|
||||||
|
packages[p].revBuildDeps.append(self.name)
|
||||||
|
else:
|
||||||
|
if not missing.has_key(p):
|
||||||
|
Missing(p)
|
||||||
|
missing[p].revBuildDeps.append(self.name)
|
||||||
|
# mark reverse runtime dependencies
|
||||||
|
for d in self.pakspec.packageDependencies:
|
||||||
|
p = d.package
|
||||||
|
if packages.has_key(p):
|
||||||
|
packages[p].revRuntimeDeps.append(self.name)
|
||||||
|
else:
|
||||||
|
if not missing.has_key(p):
|
||||||
|
Missing(p)
|
||||||
|
missing[p].revRuntimeDeps.append(self.name)
|
||||||
|
|
||||||
|
def report_html(self):
|
||||||
|
source = self.source.spec.source
|
||||||
|
bDeps = map(lambda x: "<a href='./%s.html'>%s</a>" % (x, x),
|
||||||
|
(map(lambda x: x.package, source.buildDependencies)))
|
||||||
|
rDeps = map(lambda x: "<a href='./%s.html'>%s</a>" % (x, x),
|
||||||
|
(map(lambda x: x.package, self.pakspec.packageDependencies)))
|
||||||
|
rbDeps = map(lambda x: "<a href='./%s.html'>%s</a>" % (x, x), self.revBuildDeps)
|
||||||
|
rrDeps = map(lambda x: "<a href='./%s.html'>%s</a>" % (x, x), self.revRuntimeDeps)
|
||||||
|
|
||||||
|
html = """
|
||||||
|
<h1>İkili paket: %s</h1>
|
||||||
|
<h2>Kaynak versiyon %s, depo sürümü %s</h2>
|
||||||
|
|
||||||
|
<h3>Kaynak paket: %s</h3>
|
||||||
|
|
||||||
|
<h3>Derlemek için gerekenler:</h3>
|
||||||
|
<p>%s</p>
|
||||||
|
|
||||||
|
<h3>Çalıştırmak için gerekenler:</h3>
|
||||||
|
<p>%s</p>
|
||||||
|
|
||||||
|
<h3>Bağımlı paketler (derlenmek için):</h3>
|
||||||
|
<p>%s</p>
|
||||||
|
|
||||||
|
<h3>Bağımlı paketler (çalışmak için):</h3>
|
||||||
|
<p>%s</p>
|
||||||
|
""" % (
|
||||||
|
self.name,
|
||||||
|
self.source.spec.getSourceVersion(),
|
||||||
|
self.source.spec.getSourceRelease(),
|
||||||
|
make_url(source.name, "../source/"),
|
||||||
|
", ".join(bDeps),
|
||||||
|
", ".join(rDeps),
|
||||||
|
", ".join(rbDeps),
|
||||||
|
", ".join(rrDeps),
|
||||||
|
)
|
||||||
|
|
||||||
|
write_html("paksite/binary/%s.html" % self.name, self.name, html)
|
||||||
|
|
||||||
|
|
||||||
|
class Source:
|
||||||
|
def __init__(self, path, spec):
|
||||||
|
name = spec.source.name
|
||||||
|
if sources.has_key(name):
|
||||||
|
errors.append(_("Duplicate source packages:\n%s\n%s\n") % (
|
||||||
|
path, sources[name].path))
|
||||||
|
return
|
||||||
|
sources[name] = self
|
||||||
|
self.spec = spec
|
||||||
|
self.name = name
|
||||||
|
self.path = path
|
||||||
|
self.uri = svn_uri(path)
|
||||||
|
for p in spec.packages:
|
||||||
|
Package(self, p)
|
||||||
|
|
||||||
|
def report_html(self):
|
||||||
|
source = self.spec.source
|
||||||
|
paks = map(lambda x: "<a href='../binary/%s.html'>%s</a>" % (x, x),
|
||||||
|
(map(lambda x: x.name, self.spec.packages)))
|
||||||
|
histdata = map(lambda x: (x.release, x.date, x.version, make_url(x.name, "../packager/"), x.comment), self.spec.history)
|
||||||
|
ptch = map(lambda x: "<a href='%s/files/%s'>%s</a>" % (self.uri,
|
||||||
|
x.filename, x.filename), source.patches)
|
||||||
|
|
||||||
|
titles = "Sürüm", "Sürüm Tarihi", "Versiyon", "Güncelleyen", "Açıklama"
|
||||||
|
hist = make_table(histdata, titles)
|
||||||
|
|
||||||
|
html = """
|
||||||
|
<h1>Kaynak paket: %s</h1>
|
||||||
|
<h2>Kaynak versiyon %s, depo sürümü %s</h2>
|
||||||
|
<h3><a href='%s'>%s</a></h3>
|
||||||
|
<h3>Açıklama</h3>
|
||||||
|
<p>%s</p>
|
||||||
|
<h3>Lisanslar:</h3>
|
||||||
|
<p>%s</p>
|
||||||
|
<h3>İşlemler:</h3>
|
||||||
|
<p><a href="%s">Paket dosyalarına bak</a></p>
|
||||||
|
<p><a href="http://bugs.pardus.org.tr/buglist.cgi?product=Paketler&component=%s&bug_status=NEW&bug_status=ASSIGNED&bug_status=REOPENED">Hata kayıtlarına bak</a></p>
|
||||||
|
|
||||||
|
<h3>Bu kaynaktan derlenen ikili paketler:</h3>
|
||||||
|
<p>%s</p>
|
||||||
|
|
||||||
|
<h3>Tarihçe</h3>
|
||||||
|
%s
|
||||||
|
|
||||||
|
<h3>Yamalar</h3>
|
||||||
|
%s
|
||||||
|
""" % (
|
||||||
|
self.name,
|
||||||
|
self.spec.getSourceVersion(),
|
||||||
|
self.spec.getSourceRelease(),
|
||||||
|
source.homepage,
|
||||||
|
source.homepage,
|
||||||
|
source.summary,
|
||||||
|
", ".join(source.license),
|
||||||
|
self.uri,
|
||||||
|
self.name,
|
||||||
|
"<br>".join(paks),
|
||||||
|
"".join(hist),
|
||||||
|
"<br>".join(ptch),
|
||||||
|
)
|
||||||
|
|
||||||
|
write_html("paksite/source/%s.html" % self.name, self.name, html)
|
||||||
|
|
||||||
|
|
||||||
|
class Packager:
|
||||||
|
def __init__(self, spec, update=None):
|
||||||
|
if update:
|
||||||
|
name = update.name
|
||||||
|
email = update.email
|
||||||
|
else:
|
||||||
|
name = spec.source.packager.name
|
||||||
|
email = spec.source.packager.email
|
||||||
|
if packagers.has_key(name):
|
||||||
|
if email != packagers[name].email:
|
||||||
|
e = _("Developer '%s <%s>' has another mail address '%s' in source package '%s'") % (
|
||||||
|
name, packagers[name].email, email, spec.source.name)
|
||||||
|
packagers[name].errors.append(e)
|
||||||
|
errors.append(e)
|
||||||
|
if update:
|
||||||
|
packagers[name].updates.append((spec.source.name, update.release, update.comment))
|
||||||
|
else:
|
||||||
|
packagers[name].sources.append(spec.source.name)
|
||||||
|
else:
|
||||||
|
packagers[name] = self
|
||||||
|
self.name = name
|
||||||
|
self.email = email
|
||||||
|
if update:
|
||||||
|
self.sources = []
|
||||||
|
self.updates = [(spec.source.name, update.release, update.comment)]
|
||||||
|
else:
|
||||||
|
self.sources = [spec.source.name]
|
||||||
|
self.updates = []
|
||||||
|
self.errors = []
|
||||||
|
if not update:
|
||||||
|
for update in spec.history:
|
||||||
|
Packager(spec, update)
|
||||||
|
|
||||||
|
def report_html(self):
|
||||||
|
srcs = map(lambda x: ("<a href='../source/%s.html'>%s</a>" % (x, x), ), self.sources)
|
||||||
|
srcs.sort()
|
||||||
|
upds = map(lambda x: (u"<b><a href='../source/%s.html'>%s</a> (%s)</b><br>%s<br>" % (
|
||||||
|
x[0], x[0], x[1], x[2]), ), self.updates)
|
||||||
|
|
||||||
|
html = """
|
||||||
|
<p>Paketçi: %s (%s)</p>
|
||||||
|
""" % (self.name, mangle_email(self.email))
|
||||||
|
|
||||||
|
html += """
|
||||||
|
<div class='statstat'>
|
||||||
|
<h3>Sahip olduğu paketler:</h3><p>
|
||||||
|
%s
|
||||||
|
</p></div>
|
||||||
|
""" % make_table(srcs)
|
||||||
|
|
||||||
|
html += """
|
||||||
|
<div class='statstat'>
|
||||||
|
<h3>Yaptığı güncellemeler:</h3><p>
|
||||||
|
%s
|
||||||
|
</p></div>
|
||||||
|
""" % make_table(upds)
|
||||||
|
|
||||||
|
write_html("paksite/packager/%s.html" % self.name, self.name, html)
|
||||||
|
|
||||||
|
|
||||||
|
class Repository:
|
||||||
|
def __init__(self, path):
|
||||||
|
self.path = path
|
||||||
|
self.nr_sources = 0
|
||||||
|
self.nr_packages = 0
|
||||||
|
self.nr_patches = 0
|
||||||
|
self.people = Histogram()
|
||||||
|
self.licenses = Histogram()
|
||||||
|
self.mostpatched = Histogram()
|
||||||
|
self.longpy = Histogram()
|
||||||
|
self.cscripts = Histogram()
|
||||||
|
self.total_installed_size = 0
|
||||||
|
self.installed_sizes = {}
|
||||||
|
|
||||||
|
def processPspec(self, path, spec):
|
||||||
|
# new classes
|
||||||
|
Packager(spec)
|
||||||
|
Source(path, spec)
|
||||||
|
# update global stats
|
||||||
|
self.nr_sources += 1
|
||||||
|
self.nr_packages += len(spec.packages)
|
||||||
|
self.nr_patches += len(spec.source.patches)
|
||||||
|
# update top fives
|
||||||
|
self.people.add(spec.source.packager.name)
|
||||||
|
for u in spec.history:
|
||||||
|
self.people.note(u.name)
|
||||||
|
for p in spec.packages:
|
||||||
|
for cs in p.providesComar:
|
||||||
|
self.cscripts.add(cs.om)
|
||||||
|
for L in spec.source.license:
|
||||||
|
self.licenses.add(L)
|
||||||
|
self.mostpatched.add(spec.source.name, len(spec.source.patches))
|
||||||
|
try:
|
||||||
|
f = file(os.path.join(path, "actions.py"))
|
||||||
|
L = len(f.readlines())
|
||||||
|
self.longpy.add(spec.source.name, L)
|
||||||
|
f.close()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def scan(self):
|
||||||
|
for pak in find_pspecs(self.path):
|
||||||
|
spec = pisi.specfile.SpecFile()
|
||||||
|
try:
|
||||||
|
spec.read(os.path.join(pak, "pspec.xml"))
|
||||||
|
except Exception, inst:
|
||||||
|
errors.append(_("Cannot parse '%s':\n%s\n") % (pak, inst.args[0]))
|
||||||
|
continue
|
||||||
|
self.processPspec(pak, spec)
|
||||||
|
for p in packages.values():
|
||||||
|
p.markDeps()
|
||||||
|
|
||||||
|
def processPisi(self, path):
|
||||||
|
p = pisi.package.Package(path)
|
||||||
|
p.extract_files(["metadata.xml", "files.xml"], ".")
|
||||||
|
md = pisi.metadata.MetaData()
|
||||||
|
md.read("metadata.xml")
|
||||||
|
self.total_installed_size += md.package.installedSize
|
||||||
|
if packages.has_key(md.package.name):
|
||||||
|
# FIXME: check version/release match too?
|
||||||
|
packages[md.package.name].installed_size = md.package.installedSize
|
||||||
|
else:
|
||||||
|
printu("Binary package '%s' has no source package in repository %s\n" % (path, self.path))
|
||||||
|
fd = pisi.files.Files()
|
||||||
|
fd.read("files.xml")
|
||||||
|
for f in fd.list:
|
||||||
|
if self.installed_sizes.has_key(f.type):
|
||||||
|
# Emtpy directories and symlinks has None size
|
||||||
|
if not f.size is None:
|
||||||
|
self.installed_sizes[f.type] += int(f.size)
|
||||||
|
else:
|
||||||
|
self.installed_sizes[f.type] = int(f.size)
|
||||||
|
|
||||||
|
def scan_bins(self, binpath):
|
||||||
|
for root, dirs, files in os.walk(binpath):
|
||||||
|
for fn in files:
|
||||||
|
if fn.endswith(".pisi"):
|
||||||
|
self.processPisi(os.path.join(root, fn))
|
||||||
|
|
||||||
|
def report_html(self):
|
||||||
|
table = (
|
||||||
|
("Kaynak paket sayısı", self.nr_sources),
|
||||||
|
("İkili paket sayısı", self.nr_packages),
|
||||||
|
("Yama sayısı", self.nr_patches),
|
||||||
|
("Paketçi sayısı", len(self.people.list)),
|
||||||
|
)
|
||||||
|
html = make_table(table)
|
||||||
|
|
||||||
|
html += """
|
||||||
|
<div class='statstat'>
|
||||||
|
<h3>En fazla yamalanmış beş kaynak paket:</h3><p>
|
||||||
|
%s
|
||||||
|
</p></div>
|
||||||
|
""" % make_table(map(lambda x: (make_url(x[0], "./source/"), x[1]), self.mostpatched.get_list(5)))
|
||||||
|
|
||||||
|
html += """
|
||||||
|
<div class='statstat'>
|
||||||
|
<h3>En uzun inşa betikli beş kaynak paket:</h3><p>
|
||||||
|
%s
|
||||||
|
</p></div>
|
||||||
|
""" % make_table(map(lambda x: (make_url(x[0], "./source/"), x[1]), self.longpy.get_list(5)))
|
||||||
|
|
||||||
|
write_html("paksite/index.html", "Genel Bilgiler", html)
|
||||||
|
|
||||||
|
titles = (
|
||||||
|
"<a href='packagers_by_name.html'>Paketçi</a>",
|
||||||
|
"<a href='packagers.html'>Paket sayısı</a>"
|
||||||
|
)
|
||||||
|
|
||||||
|
people = self.people.get_list()
|
||||||
|
people = map(lambda x: ("<a href='./packager/%s.html'>%s</a>" % (x[0], x[0]), x[1]), people)
|
||||||
|
write_html("paksite/packagers.html", "Paketçiler (paket sayısına göre)", make_table(people, titles))
|
||||||
|
|
||||||
|
people.sort(key=lambda x: x[0])
|
||||||
|
write_html("paksite/packagers_by_name.html", "Paketçiler (isme göre)", make_table(people, titles))
|
||||||
|
|
||||||
|
titles = "Paket adı", "Versiyon", "Açıklama"
|
||||||
|
|
||||||
|
srclist = map(lambda x: (make_url(x.name, "source/"), x.spec.getSourceVersion(), x.spec.source.summary), sources.values())
|
||||||
|
srclist.sort(key=lambda x: x[0])
|
||||||
|
html = make_table(srclist, titles)
|
||||||
|
write_html("paksite/sources.html", "Kaynak Paketler", html)
|
||||||
|
|
||||||
|
binlist = map(lambda x: (make_url(x.name, "binary/"), x.source.spec.getSourceVersion(), x.source.spec.source.summary), packages.values())
|
||||||
|
binlist.sort(key=lambda x: x[0])
|
||||||
|
html = make_table(binlist, titles)
|
||||||
|
write_html("paksite/binaries.html", "İkili Paketler", html)
|
||||||
|
|
||||||
|
|
||||||
|
# command line driver
|
||||||
|
|
||||||
|
def usage():
|
||||||
|
printu(_("Usage: repostats.py [OPTIONS] source-repo-path [binary-repo-path]\n"))
|
||||||
|
printu(" -t, --test-only: %s" % _("Dont generate the web site.\n"))
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
try:
|
||||||
|
opts, args = getopt.gnu_getopt(sys.argv[1:], "ht", ["help", "test-only"])
|
||||||
|
except:
|
||||||
|
usage()
|
||||||
|
|
||||||
|
if args == []:
|
||||||
|
usage()
|
||||||
|
|
||||||
|
do_web = True
|
||||||
|
|
||||||
|
for o, v in opts:
|
||||||
|
if o in ("-h", "--help"):
|
||||||
|
usage()
|
||||||
|
if o in ("-t", "--test-only"):
|
||||||
|
do_web = False
|
||||||
|
|
||||||
|
repo = Repository(args[0])
|
||||||
|
printu(_("Scanning source repository...\n"))
|
||||||
|
repo.scan()
|
||||||
|
|
||||||
|
if len(args) > 1:
|
||||||
|
printu(_("Scanning binary packages...\n"))
|
||||||
|
repo.scan_bins(args[1])
|
||||||
|
|
||||||
|
if do_web:
|
||||||
|
if not os.path.exists("paksite/packager"):
|
||||||
|
os.makedirs("paksite/packager")
|
||||||
|
if not os.path.exists("paksite/binary"):
|
||||||
|
os.makedirs("paksite/binary")
|
||||||
|
if not os.path.exists("paksite/source"):
|
||||||
|
os.makedirs("paksite/source")
|
||||||
|
|
||||||
|
file("paksite/stil.css", "w").write(css_template)
|
||||||
|
|
||||||
|
repo.report_html()
|
||||||
|
for p in packagers.values():
|
||||||
|
p.report_html()
|
||||||
|
for p in packages.values():
|
||||||
|
p.report_html()
|
||||||
|
for p in sources.values():
|
||||||
|
p.report_html()
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
#!/usr/bin/python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
#
|
|
||||||
# Copyright (C) 2005 - 2007, TUBITAK/UEKAE
|
|
||||||
#
|
|
||||||
# This program is free software; you can redistribute it and/or modify it
|
|
||||||
# under the terms of the GNU General Public License as published by the
|
|
||||||
# Free Software Foundation; either version 2 of the License, or (at your
|
|
||||||
# option) any later version. Please read the COPYING file.
|
|
||||||
#
|
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
import piksemel
|
|
||||||
|
|
||||||
|
|
||||||
def findFilesXML(path):
|
|
||||||
filesXMLs = list()
|
|
||||||
for root, dirs, files in os.walk(path):
|
|
||||||
for file in files:
|
|
||||||
if file == "files.xml":
|
|
||||||
filesXMLs.append(os.path.join(root, file))
|
|
||||||
return filesXMLs
|
|
||||||
|
|
||||||
def parseFilesXML():
|
|
||||||
files = set()
|
|
||||||
for filesXML in findFilesXML("/var/lib/pisi/package/"):
|
|
||||||
data = open(filesXML).read()
|
|
||||||
data = piksemel.parseString(data)
|
|
||||||
for filePath in data.tags("File"):
|
|
||||||
path = filePath.getTagData("Path")
|
|
||||||
if filePath.getTag("Hash"):
|
|
||||||
files.add("/%s" % path)
|
|
||||||
return files
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
try:
|
|
||||||
sys.argv[1]
|
|
||||||
except IndexError:
|
|
||||||
sys.exit("Unsufficient arguments...")
|
|
||||||
|
|
||||||
fileSet = parseFilesXML()
|
|
||||||
|
|
||||||
for root, dirs, files in os.walk(sys.argv[1]):
|
|
||||||
for file in files:
|
|
||||||
f = os.path.join(root, file)
|
|
||||||
if not fileSet.__contains__(f):
|
|
||||||
print f
|
|
||||||
@@ -64,6 +64,7 @@ class Install(install):
|
|||||||
return
|
return
|
||||||
|
|
||||||
pisiconf = open(confFile, "w")
|
pisiconf = open(confFile, "w")
|
||||||
|
|
||||||
klasses = inspect.getmembers(pisi.configfile, inspect.isclass)
|
klasses = inspect.getmembers(pisi.configfile, inspect.isclass)
|
||||||
defaults = [klass for klass in klasses if klass[0].endswith('Defaults')]
|
defaults = [klass for klass in klasses if klass[0].endswith('Defaults')]
|
||||||
|
|
||||||
@@ -76,8 +77,10 @@ class Install(install):
|
|||||||
and not m[0].endswith('__')]
|
and not m[0].endswith('__')]
|
||||||
|
|
||||||
for member in section_members:
|
for member in section_members:
|
||||||
pisiconf.write("%s = %s\n" % (member[0], member[1]))
|
if member[1] == None or member[1] == "":
|
||||||
|
pisiconf.write("# %s = %s\n" % (member[0], member[1]))
|
||||||
|
else:
|
||||||
|
pisiconf.write("%s = %s\n" % (member[0], member[1]))
|
||||||
pisiconf.write('\n')
|
pisiconf.write('\n')
|
||||||
|
|
||||||
|
|
||||||
@@ -90,7 +93,7 @@ setup(name="pisi",
|
|||||||
author_email="pisi@pardus.org.tr",
|
author_email="pisi@pardus.org.tr",
|
||||||
url="http://www.pardus.org.tr/eng/pisi/",
|
url="http://www.pardus.org.tr/eng/pisi/",
|
||||||
package_dir = {'': ''},
|
package_dir = {'': ''},
|
||||||
packages = ['pisi', 'pisi.cli', 'pisi.db', 'pisi.actionsapi', 'pisi.pxml', 'pisi.scenarioapi'],
|
packages = ['pisi', 'pisi.cli', 'pisi.actionsapi', 'pisi.pxml', 'pisi.scenarioapi'],
|
||||||
scripts = ['pisi-cli', 'scripts/lspisi', 'scripts/unpisi', 'scripts/check-newconfigs.py', 'scripts/revdep-rebuild'],
|
scripts = ['pisi-cli', 'scripts/lspisi', 'scripts/unpisi', 'scripts/check-newconfigs.py', 'scripts/revdep-rebuild'],
|
||||||
cmdclass = {'install' : Install}
|
cmdclass = {'install' : Install}
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -21,27 +21,27 @@ class DependencyTestCase(unittest.TestCase):
|
|||||||
gtkmmdep = Dependency()
|
gtkmmdep = Dependency()
|
||||||
gtkmmdep.versionFrom = '1.9.1'
|
gtkmmdep.versionFrom = '1.9.1'
|
||||||
gtkmmdep.package = 'atk'
|
gtkmmdep.package = 'atk'
|
||||||
self.assert_( not gtkmmdep.satisfies('atk', '1.8.0', '1') )
|
self.assert_( not gtkmmdep.satisfies_relation('atk', '1.8.0', '1') )
|
||||||
self.assert_( gtkmmdep.satisfies('atk', '1.9.1', '2') )
|
self.assert_( gtkmmdep.satisfies_relation('atk', '1.9.1', '2') )
|
||||||
self.assert_( gtkmmdep.satisfies('atk', '1.10.5', '3') )
|
self.assert_( gtkmmdep.satisfies_relation('atk', '1.10.5', '3') )
|
||||||
|
|
||||||
def testReleaseFrom(self):
|
def testReleaseFrom(self):
|
||||||
# releaseFrom isn't taken into account #2294
|
# releaseFrom isn't taken into account #2294
|
||||||
dep = Dependency()
|
dep = Dependency()
|
||||||
dep.releaseFrom = '121'
|
dep.releaseFrom = '121'
|
||||||
dep.package = 'dbus'
|
dep.package = 'dbus'
|
||||||
self.assert_(not dep.satisfies('dbus', '1.2', '2'))
|
self.assert_(not dep.satisfies_relation('dbus', '1.2', '2'))
|
||||||
|
|
||||||
def testReleaseTo(self):
|
def testReleaseTo(self):
|
||||||
dep = Dependency()
|
dep = Dependency()
|
||||||
dep.releaseTo = '22'
|
dep.releaseTo = '22'
|
||||||
dep.package = 'dbus'
|
dep.package = 'dbus'
|
||||||
self.assert_(not dep.satisfies('dbus', '1.2', '25'))
|
self.assert_(not dep.satisfies_relation('dbus', '1.2', '25'))
|
||||||
|
|
||||||
def testReleaseIs(self):
|
def testReleaseIs(self):
|
||||||
dep = Dependency()
|
dep = Dependency()
|
||||||
dep.release = '42'
|
dep.release = '42'
|
||||||
dep.package = 'dbus'
|
dep.package = 'dbus'
|
||||||
self.assert_(dep.satisfies('dbus', '1.2', '42'))
|
self.assert_(dep.satisfies_relation('dbus', '1.2', '42'))
|
||||||
|
|
||||||
suite = unittest.makeSuite(DependencyTestCase)
|
suite = unittest.makeSuite(DependencyTestCase)
|
||||||
|
|||||||
+1
-1
@@ -13,7 +13,7 @@ import os
|
|||||||
|
|
||||||
import pisi.context as ctx
|
import pisi.context as ctx
|
||||||
import pisi.api
|
import pisi.api
|
||||||
import pisi.db.installdb
|
import pisi.installdb
|
||||||
import pisi.files as files
|
import pisi.files as files
|
||||||
from pisi import util
|
from pisi import util
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import os
|
|||||||
|
|
||||||
import pisi.context as ctx
|
import pisi.context as ctx
|
||||||
import pisi.api
|
import pisi.api
|
||||||
import pisi.db.installdb
|
import pisi.installdb
|
||||||
from pisi import util
|
from pisi import util
|
||||||
|
|
||||||
import testcase
|
import testcase
|
||||||
|
|||||||
+13
-2
@@ -13,6 +13,7 @@ import os
|
|||||||
|
|
||||||
from pisi import metadata
|
from pisi import metadata
|
||||||
from pisi import util
|
from pisi import util
|
||||||
|
from pisi import specfile
|
||||||
|
|
||||||
class MetaDataTestCase(unittest.TestCase):
|
class MetaDataTestCase(unittest.TestCase):
|
||||||
|
|
||||||
@@ -20,11 +21,11 @@ class MetaDataTestCase(unittest.TestCase):
|
|||||||
md = metadata.MetaData()
|
md = metadata.MetaData()
|
||||||
md.read('tests/popt/metadata.xml')
|
md.read('tests/popt/metadata.xml')
|
||||||
|
|
||||||
self.assertEqual(md.package.license, ["As-Is"])
|
self.assertEqual(md.package.license, ["as-is"])
|
||||||
|
|
||||||
self.assertEqual(md.package.version, "1.7")
|
self.assertEqual(md.package.version, "1.7")
|
||||||
|
|
||||||
self.assertEqual(md.package.installedSize, 149691)
|
self.assertEqual(md.package.installedSize, 15982)
|
||||||
return md
|
return md
|
||||||
|
|
||||||
def testWrite(self):
|
def testWrite(self):
|
||||||
@@ -36,5 +37,15 @@ class MetaDataTestCase(unittest.TestCase):
|
|||||||
if md.errors():
|
if md.errors():
|
||||||
self.fail("Couldn't verify!")
|
self.fail("Couldn't verify!")
|
||||||
|
|
||||||
|
def testFromSpec(self):
|
||||||
|
specmd = metadata.MetaData()
|
||||||
|
spec = specfile.SpecFile('tests/popt/pspec.xml')
|
||||||
|
specmd.from_spec(spec.source, spec.packages[0], spec.history)
|
||||||
|
md = metadata.MetaData()
|
||||||
|
md.read('tests/popt/metadata.xml')
|
||||||
|
for key in md.package.__dict__.keys():
|
||||||
|
if key not in ('installedSize', 'packageFormat', 'distributionRelease',
|
||||||
|
'license', 'architecture', 'distribution', 'partOf'):
|
||||||
|
self.assertEqual(md.package.__dict__[key], specmd.package.__dict__[key])
|
||||||
|
|
||||||
suite = unittest.makeSuite(MetaDataTestCase)
|
suite = unittest.makeSuite(MetaDataTestCase)
|
||||||
|
|||||||
@@ -13,10 +13,9 @@ import os
|
|||||||
|
|
||||||
import pisi.context as ctx
|
import pisi.context as ctx
|
||||||
import pisi.api
|
import pisi.api
|
||||||
|
from pisi.packagedb import PackageDB
|
||||||
from pisi import util
|
from pisi import util
|
||||||
from pisi.specfile import SpecFile
|
from pisi.specfile import SpecFile
|
||||||
import pisi.db.repodb
|
|
||||||
import pisi.db.packagedb
|
|
||||||
|
|
||||||
import testcase
|
import testcase
|
||||||
class PackageDBTestCase(testcase.TestCase):
|
class PackageDBTestCase(testcase.TestCase):
|
||||||
@@ -29,7 +28,7 @@ class PackageDBTestCase(testcase.TestCase):
|
|||||||
|
|
||||||
def testAdd(self):
|
def testAdd(self):
|
||||||
if not ctx.repodb.has_repo('test'):
|
if not ctx.repodb.has_repo('test'):
|
||||||
ctx.repodb.add_repo('test', pisi.db.repodb.Repo(pisi.uri.URI('fakerepo.xml')) )
|
ctx.repodb.add_repo('test', pisi.repodb.Repo(pisi.uri.URI('fakerepo.xml')) )
|
||||||
ctx.packagedb.add_package(self.spec.packages[1], 'test')
|
ctx.packagedb.add_package(self.spec.packages[1], 'test')
|
||||||
self.assert_(ctx.packagedb.has_package('popt-libs'))
|
self.assert_(ctx.packagedb.has_package('popt-libs'))
|
||||||
# close the database and remove lock
|
# close the database and remove lock
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ import os
|
|||||||
|
|
||||||
from pisi import util
|
from pisi import util
|
||||||
import pisi.context as ctx
|
import pisi.context as ctx
|
||||||
import pisi.db.packagedb
|
|
||||||
import pisi.package
|
import pisi.package
|
||||||
|
|
||||||
import testcase
|
import testcase
|
||||||
|
|||||||
+34
-70
@@ -1,87 +1,51 @@
|
|||||||
<?xml version="1.0" ?>
|
|
||||||
<PISI>
|
<PISI>
|
||||||
<Source>
|
<Source>
|
||||||
<Name>
|
<Name>popt</Name>
|
||||||
popt
|
<Homepage>http://www.rpm.org/</Homepage>
|
||||||
</Name>
|
|
||||||
<Packager>
|
<Packager>
|
||||||
<Name>
|
<Name>Kırmızı kafalar</Name>
|
||||||
Kırmızı kafalar
|
<Email>hotmail@redhat.com</Email>
|
||||||
</Name>
|
|
||||||
<Email>
|
|
||||||
hotmail@redhat.com
|
|
||||||
</Email>
|
|
||||||
</Packager>
|
</Packager>
|
||||||
</Source>
|
</Source>
|
||||||
<Package>
|
<Package>
|
||||||
<Name>
|
<Name>popt</Name>
|
||||||
popt-libs
|
<Summary xml:lang="en">Command line option parsing library</Summary>
|
||||||
</Name>
|
<Summary xml:lang="tr">Komut satırı seçenekleri işleme kütüphanesi</Summary>
|
||||||
<Summary>
|
<Description xml:lang="en">library files for popt</Description>
|
||||||
Command line option parsing library
|
<IsA>app:console</IsA>
|
||||||
</Summary>
|
<PartOf>system.base</PartOf>
|
||||||
<Description>
|
<License>as-is</License>
|
||||||
library files for popt
|
|
||||||
</Description>
|
|
||||||
<License>
|
|
||||||
As-Is
|
|
||||||
</License>
|
|
||||||
<IsA>
|
|
||||||
library:util:optparser
|
|
||||||
</IsA>
|
|
||||||
<PartOf>
|
|
||||||
rpm:archive
|
|
||||||
</PartOf>
|
|
||||||
<RuntimeDependencies>
|
<RuntimeDependencies>
|
||||||
<Dependency>
|
<Dependency>gettext</Dependency>
|
||||||
gettext
|
|
||||||
</Dependency>
|
|
||||||
</RuntimeDependencies>
|
</RuntimeDependencies>
|
||||||
<Files>
|
<Files>
|
||||||
<Path fileType="sharedLib">
|
<Path fileType="library">/usr/lib</Path>
|
||||||
/usr/lib
|
<Path fileType="doc">/usr/share/doc</Path>
|
||||||
</Path>
|
<Path fileType="man">/usr/share/man</Path>
|
||||||
<Path fileType="doc">
|
<Path fileType="localedata">/usr/share/locale</Path>
|
||||||
/usr/share/doc
|
<Path fileType="header">/usr/include/popt.h</Path>
|
||||||
</Path>
|
|
||||||
<Path fileType="doc">
|
|
||||||
/usr/share/man
|
|
||||||
</Path>
|
|
||||||
<Path fileType="localedata">
|
|
||||||
/usr/share/locale
|
|
||||||
</Path>
|
|
||||||
<Path fileType="header">
|
|
||||||
/usr/include/popt.h
|
|
||||||
</Path>
|
|
||||||
</Files>
|
</Files>
|
||||||
<History>
|
<History>
|
||||||
<Update release="3">
|
<Update release="1">
|
||||||
<Date>2005-06-14</Date>
|
<Date>2005-06-14</Date>
|
||||||
<Version>1.7</Version>
|
<Version>1.7</Version>
|
||||||
</Update>
|
<Comment>First release.</Comment>
|
||||||
<Update release="2">
|
<Name>Kırmızı kafalar</Name>
|
||||||
<Date>2005-06-10</Date>
|
<Email>hotmail@redhat.com</Email>
|
||||||
<Version>1.7</Version>
|
|
||||||
</Update>
|
|
||||||
<Update release="3">
|
|
||||||
<Date>2005-05-05</Date>
|
|
||||||
<Version>1.7</Version>
|
|
||||||
</Update>
|
</Update>
|
||||||
</History>
|
</History>
|
||||||
<Build>
|
<Distribution>Pardus</Distribution>
|
||||||
0
|
<DistributionRelease>2007</DistributionRelease>
|
||||||
</Build>
|
<Architecture>Any</Architecture>
|
||||||
<Distribution>
|
<InstalledSize>15982</InstalledSize>
|
||||||
Pardus
|
<PackageFormat>1.1</PackageFormat>
|
||||||
</Distribution>
|
<Source>
|
||||||
<DistributionRelease>
|
<Name>popt</Name>
|
||||||
0.1
|
<Homepage>http://www.rpm.org/</Homepage>
|
||||||
</DistributionRelease>
|
<Packager>
|
||||||
<Architecture>
|
<Name>Kırmızı kafalar</Name>
|
||||||
Any
|
<Email>hotmail@redhat.com</Email>
|
||||||
</Architecture>
|
</Packager>
|
||||||
<InstalledSize>
|
</Source>
|
||||||
149691
|
|
||||||
</InstalledSize>
|
|
||||||
</Package>
|
</Package>
|
||||||
</PISI>
|
</PISI>
|
||||||
@@ -13,7 +13,7 @@ import os
|
|||||||
|
|
||||||
import pisi.context as ctx
|
import pisi.context as ctx
|
||||||
import pisi.api
|
import pisi.api
|
||||||
import pisi.db.installdb
|
import pisi.installdb
|
||||||
from pisi import util
|
from pisi import util
|
||||||
|
|
||||||
import testcase
|
import testcase
|
||||||
@@ -24,7 +24,7 @@ class RepoDBTestCase(testcase.TestCase):
|
|||||||
|
|
||||||
for i in range(2):
|
for i in range(2):
|
||||||
print '\nTest %d\n' % (i)
|
print '\nTest %d\n' % (i)
|
||||||
pisi.api.add_repository("foo","bar")
|
pisi.api.add_repo("foo","bar")
|
||||||
pisi.api.remove_repository("foo")
|
pisi.api.remove_repo("foo")
|
||||||
|
|
||||||
suite = unittest.makeSuite(RepoDBTestCase)
|
suite = unittest.makeSuite(RepoDBTestCase)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import os
|
|||||||
|
|
||||||
import pisi.context as ctx
|
import pisi.context as ctx
|
||||||
import pisi.api
|
import pisi.api
|
||||||
import pisi.db.sourcedb as sourcedb
|
import pisi.sourcedb
|
||||||
from pisi import util
|
from pisi import util
|
||||||
from pisi.specfile import SpecFile
|
from pisi.specfile import SpecFile
|
||||||
|
|
||||||
@@ -23,11 +23,11 @@ class SourceDBTestCase(testcase.TestCase):
|
|||||||
def setUp(self):
|
def setUp(self):
|
||||||
testcase.TestCase.setUp(self)
|
testcase.TestCase.setUp(self)
|
||||||
|
|
||||||
self.sourcedb = sourcedb.init()
|
self.sourcedb = pisi.sourcedb.init()
|
||||||
self.spec = SpecFile()
|
self.spec = SpecFile()
|
||||||
self.spec.read("tests/popt/pspec.xml")
|
self.spec.read("tests/popt/pspec.xml")
|
||||||
if not ctx.repodb.has_repo('test'):
|
if not ctx.repodb.has_repo('test'):
|
||||||
ctx.repodb.add_repo('test', pisi.db.repodb.Repo(pisi.uri.URI('fakerepo.xml')) )
|
ctx.repodb.add_repo('test', pisi.repodb.Repo(pisi.uri.URI('fakerepo.xml')) )
|
||||||
|
|
||||||
def testAddRemove(self):
|
def testAddRemove(self):
|
||||||
self.sourcedb.add_spec(self.spec, 'test')
|
self.sourcedb.add_spec(self.spec, 'test')
|
||||||
|
|||||||
+3
-3
@@ -29,10 +29,10 @@ def get_svn_paths(path):
|
|||||||
return svn_paths
|
return svn_paths
|
||||||
|
|
||||||
def move_svn_paths(paths):
|
def move_svn_paths(paths):
|
||||||
[shutil.move(d, '/tmp/' + os.path.dirname(d).replace('/', '_')) for d in paths]
|
[shutil.move(d, 'tmp/' + os.path.dirname(d).replace('/', '_')) for d in paths]
|
||||||
|
|
||||||
def restore_svn_paths(paths):
|
def restore_svn_paths(paths):
|
||||||
[shutil.move('/tmp/' + os.path.dirname(d).replace('/', '_'), d) for d in paths]
|
[shutil.move('tmp/' + os.path.dirname(d).replace('/', '_'), d) for d in paths]
|
||||||
|
|
||||||
|
|
||||||
class UtilTestCase(testcase.TestCase):
|
class UtilTestCase(testcase.TestCase):
|
||||||
@@ -69,7 +69,7 @@ class UtilTestCase(testcase.TestCase):
|
|||||||
self.assertEqual(dir_size('tests/utilfiles/linktonowhere'), 23)
|
self.assertEqual(dir_size('tests/utilfiles/linktonowhere'), 23)
|
||||||
self.assertEqual(dir_size('tests/utilfiles/directory'), 74536)
|
self.assertEqual(dir_size('tests/utilfiles/directory'), 74536)
|
||||||
self.assertEqual(dir_size('tests/utilfiles/linktoarfile'), 22)
|
self.assertEqual(dir_size('tests/utilfiles/linktoarfile'), 22)
|
||||||
self.assertEqual(dir_size('tests/utilfiles/'), 149117)
|
self.assertEqual(dir_size('tests/utilfiles/'), 149072)
|
||||||
restore_svn_paths(svn_paths)
|
restore_svn_paths(svn_paths)
|
||||||
|
|
||||||
def testGetFileHashes(self):
|
def testGetFileHashes(self):
|
||||||
|
|||||||
+1
-1
@@ -23,7 +23,7 @@ if os.path.exists('svndist/pisi-%s' % ver):
|
|||||||
shutil.rmtree('svndist/pisi-%s' % ver)
|
shutil.rmtree('svndist/pisi-%s' % ver)
|
||||||
|
|
||||||
print 'Exporting svn directory'
|
print 'Exporting svn directory'
|
||||||
run('svn export http://svn.uludag.org.tr/uludag/trunk/pisi svndist/pisi-%s' % ver)
|
run('svn export http://svn.uludag.org.tr/uludag/branches/pisi-1.1 svndist/pisi-%s' % ver)
|
||||||
|
|
||||||
os.chdir('svndist')
|
os.chdir('svndist')
|
||||||
run('tar cjvf pisi-%s.tar.bz2 pisi-%s' % (ver, ver))
|
run('tar cjvf pisi-%s.tar.bz2 pisi-%s' % (ver, ver))
|
||||||
|
|||||||
Reference in New Issue
Block a user