summaryrefslogtreecommitdiff
blob: 6442ab0aade469c899f821880bfa3fdfcdfec117 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
# Copyright John N. Laliberte <allanonjl@gentoo.org>
# LICENSE - GPL2

# gnome module
import urllib2, package_module, string, simple_cache_module
import clioptions_module
# import ftp_module



DEBUG=False
class GNOME:
    def __init__(self, nextrev=False):
        options = clioptions_module.Options()
        args = options.get_arguments()
        
        self.nextrev = nextrev;
        self.major_release = ".".join( args.release_number.split(".")[:2] )
        self.full_release = args.release_number

        # gnome_release is the major release number the development is leading up to or is part of. E.g, 2.21.5 will turn to 2.22 and 2.22.2 becomes 2.22
        # This is used in latest versions list fetching URL construction
        gnome_release_list = args.release_number.split(".")
        if int(gnome_release_list[1]) % 2 != 0:
            gnome_release_list[1] = str(int(gnome_release_list[1]) + 1)
        self.gnome_release = ".".join(gnome_release_list[:2])

        self.ftpserver = "ftp.gnome.org"
        self.release_directories = ["pub/GNOME/admin/" + self.major_release + "/" + self.full_release + "/",
                               "pub/GNOME/platform/" + self.major_release + "/" + self.full_release + "/",
                               "pub/GNOME/desktop/" + self.major_release + "/" + self.full_release + "/",
                               "pub/GNOME/bindings/" + self.major_release + "/" + self.full_release + "/"]
        self.latest_versions_file_path = 'http://www.gnome.org/~vuntz/tmp/versions/'
        self.latest_versions_url = self.latest_versions_file_path + 'versions-' + self.gnome_release
        self.release_versions_file_path = 'http://ftp.gnome.org/pub/GNOME/teams/releng/'

    def generate_data_from_versions_markup(self, url):
        try:
            f = urllib2.urlopen(url)
        except:
            raise ValueError("Couldn't open %s" % url)

        ret = []
        for line in f.readlines():
            components = str.strip(line).split(':')
            if len(components) == 4 and len(components[2]) > 0:
                # Ignore perl packages that don't have versions known in version-stable due to different infrastructure for hosting
                # We have a workaround in compare_packages now, but we don't have a proper mapping to ruby-g* stuff yet, so ignore them for now
                if (components[0] == 'bindings' and components[3] == 'perl'):
                    continue
                # Skip mobile stuff, because we don't care. And they are mostly dupes anyway
                if components[0] == 'mobile':
                    continue
                pkg = package_module.Package(components[1] + "-" + components[2])
                if (pkg.name and pkg.version):
                    ret.append(pkg)
                else:
                    print "Warning: Ignoring package %s because parsing of its name or version string '%s' failed" % (components[1], components[2])

        f.close()
        return ret

    def generate_data_individual(self):
        return self.generate_data_from_versions_markup(self.latest_versions_url)

    def generate_data_release(self):
        return self.generate_data_from_versions_markup(self.release_versions_file_path + self.full_release + '/versions')

    """ We might want to modify this later to an extra fallback and/or for non-official modules whose tarballs are hosted on GNOME or compatible FTP
    def generate_data_ftp(self):
        # Deprecated: connect to ftp and get the list of all the packages in the release directories
        walker = ftp_module.FTPWalker(self.ftpserver,"anonymous","test@test.com")
        
        files = []
        for directory in self.release_directories:
            f_files = ftp_module.find_files(walker, directory,"","")
            files.extend(f_files)
        
        # filter out bad files
        files = self.filter_files(files)
        
        # create package objects for the files
        release_packages = [] # the packages that are required for a release
        for package_name in files:
            release_package = package_module.Package(package_name)
            release_packages.append(release_package)
            
        # while connected, find out the latest version of the packages that we found in the
        # release directories
        latest_packages = [] # the latest versions of packages on the gnome ftp.
        for package in release_packages:
            file_list = ftp_module.find_files(walker, "pub/GNOME/sources" + "/" + package.raw_name + "/" + package.major_minor,"","")

            # if maintainers release tarballs late, they will not get picked up
            # therefore, if the tarball is 1 less than the y of the x.y you
            # specify, lets also check to see if there are any files for
            # the actual release number.
            major = package.major_minor.split(".")[0]
            minor = package.major_minor.split(".")[1]
            options = clioptions_module.Options()
            args = options.get_arguments()
            release_minor = args.release_number.split(".")[1]

            if int(minor) == (int(release_minor) -1):
                file_list_future = ftp_module.find_files(walker, "pub/GNOME/sources" + "/" + package.raw_name + "/" + major + "." + str(int(minor)+1),"","")

                # if there are results, replace the old list.
                if len(file_list_future) > 0:
                    file_list = file_list_future
            elif self.nextrev == True:
                # Try to find minor+1
                file_list_future = ftp_module.find_files(walker, "pub/GNOME/sources" + "/" + package.raw_name + "/" + major + "." + str(int(minor)+1),"","")

                # if there are results, replace the old list.
                if len(file_list_future) > 0:
                    file_list = file_list_future

            # make sure we don't try to do this on directories with no files,
            # or on directories that don't exist
            
            # create package objects for the files
            if len(file_list) > 0:
                latest = self.filter_latest_only(file_list)
                latest_package = package_module.Package(package.name + "-" + latest)
                latest_packages.append(latest_package)
                
        # disconnect from the ftp
        
        # cache the results
        cache = simple_cache_module.SimpleCache()
        for release_package in release_packages:
            latest_package = portage_module.findpackage(release_package.name, latest_packages)
            if latest_package != None:
                cache.write_to_queue(release_package.name_plus_version_plus_revision, latest_package.name_plus_version_plus_revision)
            else:
                print "No matching latest package!" + str(release_package.name)
        cache.flush_queue()
        
        return (release_packages, latest_packages)
    """

    def filter_files(self, files):
        # we want to filter out all the bad files.
        newfiles = []
        for file in files:
            # only keep files with .tar.bz2 ending.
            if ( 0 < file.find(".tar.") and 0 < file.find(".bz2") ):
                file = string.replace(file,".tar.bz2","")
                newfiles.append(file)
        
        return newfiles
    
    # this needs to be fixed so that if a directory doesn't have LATEST-IS-, it returns an error
    def filter_latest_only(self, lines):
        latest_string = "LATEST-IS-"
        latest = ""
        for item in lines:
            if 0 <= string.rfind(item,latest_string):
                latest = item
        
        try:
            return_latest = latest[10:]
        except:
            return_latest = ""
            
        return return_latest
    
import portage_module
def compare_packages(release_packages, latest_packages, packages_in_portage):
    # we care about 5 cases
    # 1.  portage version is less than the release version. (RED)
    # 2.  portage version is equal to the release version, but less than the latest version. (LIGHT GREEN)
    # 3.  portage version is equal to the release version and the latest version. (GREEN)
    # 4.  portage version is greater than the release version (GREEN)
    # 5.  package does not exist in portage (GREY)
    
    # again, we choose release_packages as the enumerator for the package names
    # since it will have ALL packages ( for example, if we used portage_packages, we
    # might miss the packages that do not exist in portage )
    status_packages = []
    for package in release_packages:
        color = None
        release_package = package
        latest_package = portage_module.findpackage(package.name, latest_packages)
        if latest_package == None:
            print "Warning: latest packages set does not have an entry for %s, using release set version %s." % (package.name, package.version)
            latest_package = package
        portage_package = portage_module.findpackage(package.name, packages_in_portage)
        
        if portage_package == None:
            status = package_module.Status.NotFound
            # we need to create a phony package since findpackage
            # returns None
            portage_package = package_module.Package(package.name)

        elif portage_module.best_version_test(portage_package.name_plus_version, \
                                     release_package.name_plus_version) == 2:
            status = package_module.Status.NeedUpdate
            
        elif portage_module.best_version_test(portage_package.name_plus_version, \
                                       latest_package.name_plus_version) == 2:
            status = package_module.Status.NewerVersion
            
        else:
            status = package_module.Status.Compliant

        #if portage_package != None:

        # FIXME: Reports release version as latest version to not have to deal with this right now
        if latest_package == None:
            print "No latest version known for %s, FIXME!" % release_package.name
            latest_package = release_package
            
        if DEBUG:
            print "package: " + str(release_package.name) + \
                 " | pp: " + str(portage_package.version) + \
                 " | rp: " + str(release_package.version) + \
                 " | lp: " + str(latest_package.version) + \
                 " | status: " + str(status)

        status_packages.append(package_module.PackageStatus(release_package.name, str(portage_package.version), str(release_package.version), str(latest_package.version), status))
    
    return status_packages