]>
git.ipfire.org Git - pakfire.git/blob - python/pakfire/packages/make.py
2 ###############################################################################
4 # Pakfire - The IPFire package management system #
5 # Copyright (C) 2011 Pakfire development team #
7 # This program is free software: you can redistribute it and/or modify #
8 # it under the terms of the GNU General Public License as published by #
9 # the Free Software Foundation, either version 3 of the License, or #
10 # (at your option) any later version. #
12 # This program is distributed in the hope that it will be useful, #
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15 # GNU General Public License for more details. #
17 # You should have received a copy of the GNU General Public License #
18 # along with this program. If not, see <http://www.gnu.org/licenses/>. #
20 ###############################################################################
29 from urlgrabber
.grabber
import URLGrabber
, URLGrabError
30 from urlgrabber
.progress
import TextMeter
36 log
= logging
.getLogger("pakfire")
38 import pakfire
.chroot
as chroot
39 import pakfire
.downloader
as downloader
40 import pakfire
.util
as util
42 from base
import Package
43 from file import SourcePackage
45 from pakfire
.constants
import *
46 from pakfire
.i18n
import _
48 class MakefileBase(Package
):
49 def __init__(self
, pakfire
, filename
):
50 Package
.__init
__(self
, pakfire
)
52 # Save the filename of the makefile.
53 self
.filename
= os
.path
.abspath(filename
)
56 environ
= self
.pakfire
.environ
58 "BASEDIR" : os
.path
.dirname(self
.filename
),
59 "PARALLELISMFLAGS" : "-j%s" % util
.calc_parallelism(),
62 # Open and parse the makefile.
63 self
.lexer
= lexer
.RootLexer
.open(self
.filename
, environ
=environ
)
66 def package_filename(self
):
67 return PACKAGE_FILENAME_FMT
% {
69 "ext" : PACKAGE_EXTENSION
,
71 "release" : self
.release
,
72 "version" : self
.version
,
79 errors
.append(_("Package name is undefined."))
82 errors
.append(_("Package version is undefined."))
90 return self
.lexer
.get_var("name")
94 epoch
= self
.lexer
.get_var("epoch")
102 return self
.lexer
.get_var("version")
106 release
= self
.lexer
.get_var("release")
109 tag
= self
.lexer
.get_var("DISTRO_DISTTAG")
112 return ".".join((release
, tag
))
116 return self
.lexer
.get_var("summary")
119 def description(self
):
120 description
= self
.lexer
.get_var("description")
122 # Replace all backslashes at the end of a line.
123 return description
.replace("\\\n", "\n")
127 groups
= self
.lexer
.get_var("groups").split()
129 return sorted(groups
)
133 return self
.lexer
.get_var("url")
137 return self
.lexer
.get_var("license")
140 def maintainer(self
):
141 maintainer
= self
.lexer
.get_var("maintainer")
144 maintainer
= self
.lexer
.get_var("DISTRO_MAINTAINER")
150 return self
.lexer
.get_var("DISTRO_VENDOR")
154 return self
.lexer
.get_var("BUILDROOT")
158 return self
.lexer
.get_var("DIR_SRC")
161 def build_host(self
):
162 return socket
.gethostname()
164 # XXX build_id and build_time are used to create a source package
169 # Not existant for Makefiles
173 def build_time(self
):
175 # Not existant for Makefiles
179 def supported_arches(self
):
181 These are the supported arches. Which means, packages of these
182 architectures can be built out of this source package.
184 # If the package architecture is "noarch", the package
185 # needs only to be built for that.
186 if self
.arch
== "noarch":
189 return self
.lexer
.get_var("sup_arches", "all")
192 class Makefile(MakefileBase
):
195 hash1
= util
.calc_hash1(self
.filename
)
197 # Return UUID version 5 (SHA1 hash)
198 return "%8s-%4s-5%3s-%4s-%11s" % \
199 (hash1
[0:8], hash1
[9:13], hash1
[14:17], hash1
[18:22], hash1
[23:34])
203 return os
.path
.dirname(self
.filename
)
213 for lexer
in self
.lexer
.packages
:
214 name
= lexer
.get_var("_name")
216 pkg
= MakefilePackage(self
.pakfire
, name
, lexer
)
225 if self
.pakfire
.distro
.source_dl
:
226 dls
.append(self
.pakfire
.distro
.source_dl
)
228 dl
= self
.lexer
.get_var("source_dl")
236 Download all external sources and return a list with the local
239 # Download source files.
240 grabber
= downloader
.SourceDownloader(self
.pakfire
,
241 mirrors
=self
.source_dl
)
243 return grabber
.download(self
.sources
)
245 def dist(self
, resultdirs
):
247 Create a source package.
249 # Download all files we need for this package.
252 p
= packager
.SourcePackager(self
.pakfire
, self
)
255 def dump(self
, *args
, **kwargs
):
256 dump
= MakefileBase
.dump(self
, *args
, **kwargs
)
257 dump
= dump
.splitlines()
259 #dump += ["", _("Containing the following binary packages:"),]
261 #for pkg in self.packages:
262 # _dump = pkg.dump(*args, **kwargs)
264 # for line in _dump.splitlines():
265 # dump.append(" %s" % line)
268 return "\n".join(dump
)
270 def get_buildscript(self
, stage
):
271 return self
.lexer
.build
.get_var("_%s" % stage
)
274 def prerequires(self
):
281 for line
in self
.lexer
.build
.get_var("requires", "").splitlines():
282 reqs
+= [r
.strip() for r
in line
.split(",")]
284 return self
.filter_deps(reqs
)
301 basedir
= os
.path
.dirname(self
.filename
)
303 for dirs
, subdirs
, _files
in os
.walk(basedir
):
305 files
.append(os
.path
.join(dirs
, f
))
311 return self
.lexer
.get_var("sources").split()
317 # Include quality agent exports.
318 exports
.update(self
.lexer
.quality_agent
.exports
)
320 for export
in self
.lexer
.build
.exports
:
321 exports
[export
] = self
.lexer
.build
.get_var(export
)
325 def extract(self
, message
=None, prefix
=None):
326 # XXX neeed to make this waaaaaaaaaay better.
333 message
= "%-10s : %s" % (message
, self
.friendly_name
)
334 pb
= util
.make_progress(message
, len(files
), eta
=False)
336 dir_len
= len(os
.path
.dirname(self
.filename
))
338 # Copy all files that belong to the package
346 log
.debug("%s/%s" % (prefix
, _f
))
348 path
= "%s/%s" % (prefix
, _f
)
350 path_dir
= os
.path
.dirname(path
)
351 if not os
.path
.exists(path_dir
):
352 os
.makedirs(path_dir
)
354 shutil
.copy2(f
, path
)
359 # Download source files.
360 for _filename
in self
.download():
361 filename
= "%s/files/%s" % (prefix
, os
.path
.basename(_filename
))
362 dirname
= os
.path
.dirname(filename
)
364 if not os
.path
.exists(dirname
):
367 shutil
.copy2(_filename
, filename
)
370 class MakefilePackage(MakefileBase
):
371 def __init__(self
, pakfire
, name
, lexer
):
372 Package
.__init
__(self
, pakfire
)
377 # Store additional dependencies in here.
378 self
._dependencies
= {}
380 # Generate a random identifier.
381 self
._uuid
= "%s" % uuid
.uuid4()
389 return self
.lexer
.get_var("arch", "%{DISTRO_ARCH}")
392 def configfiles(self
):
393 return self
.lexer
.get_var("configfiles").split()
397 return self
.lexer
.get_var("files").split()
403 def track_dependencies(self
, builder
, path
):
404 # Build filelist with all files that have been installed.
405 filelist
= builder
.mktemp()
408 f
= open(filelist
, "w")
409 for dir, subdirs
, files
in os
.walk(path
):
410 f
.write("%s\n" % dir)
413 f
.write("%s\n" % os
.path
.join(dir, file))
416 log
.info(_("Searching for automatic dependencies for %s...") % self
.friendly_name
)
418 # Search for provides.
419 res
= builder
.do("/usr/lib/pakfire/find-provides %s %s" \
420 % (path
, filelist
), returnOutput
=True)
421 provides
= set(res
.splitlines())
423 # Search for requires.
424 res
= builder
.do("/usr/lib/pakfire/find-requires %s %s" \
425 % (path
, filelist
), returnOutput
=True)
426 requires
= set(res
.splitlines()) - provides
429 if os
.path
.exists(filelist
):
432 self
._dependencies
["provides"] = provides
433 self
._dependencies
["requires"] = requires
435 # Filter dependencies.
436 for key
in ("prerequires", "requires", "provides", "conflicts", "obsoletes"):
437 # Make sure this is a list.
439 self
._dependencies
[key
] = list(self
._dependencies
[key
])
441 self
._dependencies
[key
] = []
443 # Filter out unwanted elements.
444 self
._dependencies
[key
] = self
.filter_deps(
445 self
._dependencies
[key
], self
.lexer
.get_var("filter_%s" % key
)
449 def filter_deps(deps
, filters
):
456 # Compile all filters.
457 for filter in filters
.splitlines():
458 # Convert to raw string to make escaping characters
461 _filter
= re
.compile("%r" % filter)
463 log
.warning(_("Regular experession is invalid and has been skipped: %s") % filter)
466 _filters
.append(_filter
)
472 for filter in filters
:
473 # Search for a match anywhere in the line.
474 m
= re
.search(filter, dep
)
478 # Let the user know what has been done.
479 log
.info(_("Filter %s filtered %s.") % (filter, dep
))
481 # Yes, we found a match.
486 filtered_deps
.append(dep
)
490 def get_deps(self
, key
):
491 # Collect all dependencies that were set in the makefile by the user.
492 deps
= self
.lexer
.get_var(key
).splitlines()
494 # Collect all dependencies that were discovered by the tracker.
495 deps
+= self
._dependencies
.get(key
, [])
498 if key
== "provides":
499 deps
.append("uuid(%s)" % self
.uuid
)
508 def prerequires(self
):
509 return self
.get_deps("prerequires")
513 # Make sure that no self-provides are in the list
515 provides
= self
.provides
517 return [r
for r
in self
.get_deps("requires") if not r
in provides
]
521 return self
.get_deps("provides")
525 return self
.get_deps("obsoletes")
529 return self
.get_deps("conflicts")
531 def get_scriptlet(self
, type):
532 return self
.lexer
.get_scriptlet(type)
536 # The size of this is unknown.