Replace external sources in spec file copy during build.

This commit is contained in:
Devan Goodwin 2014-01-03 14:28:26 -04:00
parent 199f332d4d
commit 381debd36b
3 changed files with 73 additions and 15 deletions

View file

@ -1116,12 +1116,17 @@ class ExternalSourceBuilder(ConfigObject, BuilderBase):
user_config=user_config, args=args, **kwargs)
# Project directory where we started this build:
self.pkg_dir = os.getcwd()
self.start_dir = os.getcwd()
self.build_tag = '%s-%s' % (self.project_name,
get_spec_version_and_release(self.pkg_dir,
get_spec_version_and_release(self.start_dir,
'%s.spec' % self.project_name))
# Assuming we're still in the start directory, get the absolute path
# to all sources specified:
self.manual_sources = [os.path.abspath(s) for s in kwargs['sources']]
debug("Got sources: %s" % self.manual_sources)
def tgz(self):
self.ran_tgz = True
self._create_build_dirs()
@ -1133,24 +1138,66 @@ class ExternalSourceBuilder(ConfigObject, BuilderBase):
self.spec_file = os.path.join(self.rpmbuild_sourcedir,
'%s.spec' % self.project_name)
shutil.copyfile(
os.path.join(self.pkg_dir, '%s.spec' % self.project_name),
os.path.join(self.start_dir, '%s.spec' % self.project_name),
self.spec_file)
print(" %s.spec" % self.project_name)
# TODO: Make this a configurable strategy:
files_in_src_dir = [f for f in os.listdir(self.pkg_dir) \
if os.path.isfile(os.path.join(self.pkg_dir, f)) ]
print files_in_src_dir
for f in files_in_src_dir:
shutil.copyfile(os.path.join(self.pkg_dir, f),
os.path.join(self.rpmbuild_sourcedir, f))
i = 0
replacements = []
for s in self.manual_sources:
base_name = os.path.basename(s)
dest_filepath = os.path.join(self.rpmbuild_sourcedir, base_name)
shutil.copyfile(s, dest_filepath)
self.sources.append(dest_filepath)
# Add a line to replace in the spec for each source:
source_regex = re.compile("^(source%s:\s*)(.+)$" % i, re.IGNORECASE)
new_line = "Source%s: %s" % (i, base_name)
replacements.append((source_regex, new_line))
# Replace version and release in spec:
version_regex = re.compile("^(version:\s*)(.+)$", re.IGNORECASE)
release_regex = re.compile("^(release:\s*)(.+)$", re.IGNORECASE)
self.replace_in_spec(replacements)
# Copy every normal file in the directory we ran tito from. This
# will pick up any sources that were sitting around locally.
# TODO: how to copy only sources?
cmd = "/usr/bin/spectool --list-files '%s' | awk '{print $2}' |xargs -l1 --no-run-if-empty basename " % self.spec_file
result = run_command(cmd)
self.sources = map(lambda x: os.path.join(self.rpmbuild_sourcedir, x), result.split("\n"))
print(" Sources: %s" % self.sources)
#files_in_src_dir = [f for f in os.listdir(self.start_dir) \
# if os.path.isfile(os.path.join(self.start_dir, f)) ]
#print files_in_src_dir
#for f in files_in_src_dir:
# shutil.copyfile(os.path.join(self.start_dir, f),
# os.path.join(self.rpmbuild_sourcedir, f))
# TODO: extract version/release from filename?
# TODO: what filename?
#cmd = "/usr/bin/spectool --list-files '%s' | awk '{print $2}' |xargs -l1 --no-run-if-empty basename " % self.spec_file
#result = run_command(cmd)
#self.sources = map(lambda x: os.path.join(self.rpmbuild_sourcedir, x), result.split("\n"))
def replace_in_spec(self, replacements):
"""
Replace lines in the spec file using the given replacements.
Replacements are a tuple of a regex to look for, and a new line to
substitute in when the regex matches.
Replaces all lines with one pass through the file.
"""
in_f = open(self.spec_file, 'r')
out_f = open(self.spec_file + ".new", 'w')
for line in in_f.readlines():
for line_regex, new_line in replacements:
match = re.match(line_regex, line)
if match:
line = new_line
out_f.write(line)
in_f.close()
out_f.close()
shutil.move(self.spec_file + ".new", self.spec_file)
def _get_rpmbuild_dir_options(self):
return ('--define "_sourcedir %s" --define "_builddir %s" '

View file

@ -362,6 +362,12 @@ class BuildModule(BaseCliModule):
default='',
metavar="COLLECTION", help="Build package for software collection.")
# TODO: this is specific to the external source builder, implement a way for builders
# to inject additional cli options if they are configured.
self.parser.add_option("--source", dest="sources",
action="append", metavar="SOURCE_FILE",
help="Manually specified source file to be replaced in spec during build.")
def main(self, argv):
BaseCliModule.main(self, argv)
@ -384,6 +390,7 @@ class BuildModule(BaseCliModule):
'auto_install': self.options.auto_install,
'rpmbuild_options': self.options.rpmbuild_options,
'scl': self.options.scl,
'sources': self.options.sources,
}
builder = create_builder(package_name, build_tag,

View file

@ -70,9 +70,12 @@ class ExternalSourceBuilderTests(TitoGitTestFixture):
self.create_project_from_spec(EXT_SRC_PKG, pkg_dir=self.pkg_dir,
spec=spec,
builder='tito.builder.ExternalSourceBuilder')
run_command('touch %s/extsrc-0.0.1.tar.gz' % self.pkg_dir)
self.source_filename = 'extsrc-0.0.2.tar.gz'
os.chdir(self.pkg_dir)
# Make a fake source file, do we need something more real?
run_command('touch %s' % self.source_filename)
self.output_dir = tempfile.mkdtemp("-titotestoutput")
def tearDown(self):
@ -83,7 +86,8 @@ class ExternalSourceBuilderTests(TitoGitTestFixture):
# We have not tagged here. Build --rpm should just work:
self.assertFalse(os.path.exists(
os.path.join(self.pkg_dir, 'rel-eng/packages/extsrc')))
tito('build --rpm --output=%s --no-cleanup' % self.output_dir)
tito('build --rpm --output=%s --no-cleanup --source=%s --debug' %
(self.output_dir, self.source_filename))
self.assertTrue(os.path.exists(
os.path.join(self.output_dir, 'extsrc-0.0.1-1.fc20.src.rpm')))
self.assertTrue(os.path.exists(