diff options
author | Joseph Hunkeler <jhunk@stsci.edu> | 2013-04-22 11:17:44 -0400 |
---|---|---|
committer | Joseph Hunkeler <jhunk@stsci.edu> | 2013-04-22 11:19:34 -0400 |
commit | f2288e48380a5557a49151fc95ee121baff65b56 (patch) | |
tree | 0592592bcb1f90ccc713c1c8ecf8d25ed93f1d15 /ipsutils/build.py | |
parent | 2027d81c8662e616f5255a83242dc62cae1cc50a (diff) | |
download | ipsutils-f2288e48380a5557a49151fc95ee121baff65b56.tar.gz |
Rename ips to ipsutils
Diffstat (limited to 'ipsutils/build.py')
-rw-r--r-- | ipsutils/build.py | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/ipsutils/build.py b/ipsutils/build.py new file mode 100644 index 0000000..f402019 --- /dev/null +++ b/ipsutils/build.py @@ -0,0 +1,156 @@ +# This file is part of ipsutils. + +# ipsutils 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 3 of the License, or +# (at your option) any later version. +# +# ipsutils is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with ipsutils. If not, see <http://www.gnu.org/licenses/>. + +from . import env, task +from pprint import pprint +import os +import shutil +import subprocess +import string +from . import tpl + + +class Build(env.Environment): + def __init__(self, ipsfile): + # Parent Config parses configuration data in .ips file + # Inherited members are used to populate package information + # as well as build tasks + super(Build, self).__init__(ipsfile) + + os.chdir(self.env['IPSBUILD']) + # Create list of build tasks + ordered_tasks = ['prep', 'build', 'install'] + self.controller = task.TaskController() + + # Assign built-in IPS tasks + self.controller.task(task.NamedTask('Extract source', self.source_unpack)) + self.controller.task(task.NamedTask('Create buildroot', self.create_buildroot)) + self.controller.task(task.NamedTask('Create metadata', self.create_metadata)) + + # Assign user defined .ips tasks in build order + for user_task in ordered_tasks: + self.controller.task(task.NamedTask(user_task, self.exec_scripted_process, self.script_dict[user_task])) + + def exec_scripted_process(self, *p): + """Execute script in .ips + This function needs to be rewritten BAD + + p: tuple of function arguments + """ + # All execution occurs from within the build directory. + # This includes all installation-like tasks + os.chdir(self.env_pkg['BUILD']) + for t in map(list, p): + for i in t: + if not i: + continue + for e in i: + # Variable expansion occurs here. Unfortunately, env_pkg is NOT available + # from within the configuration class + t = string.Template(string.join(e)) + e = t.safe_substitute(self.env_pkg) + print("+ {0:s}".format(e)) + # Using "shell" is dangerous, but we're in the business of danger... right? + output = subprocess.check_output(e, shell=True) + if output: + print("+ {0:s}".format(output).rstrip('\n')) + os.chdir(self.env['IPSBUILD']) + return True + + def source_unpack(self, *p): + path = os.path.relpath(self.env_pkg['SOURCES'], self.env['IPSBUILD']) + if not os.path.exists(path): + print("{0:s}: does not exist".format(path)) + return False + + ext = { + '.tar': '{0:s} xf {1:s} -C {2:s}'.format(self.tool['tar'], path, self.env['BUILD']), + '.tar.gz': '{0:s} xfz {1:s} -C {2:s}'.format(self.tool['tar'], path, self.env['BUILD']), + '.tar.bz2': '{0:s} xfj {1:s} -C {2:s}'.format(self.tool['tar'], path, self.env['BUILD']), + '.tar.xz': '{0:s} xfJ {1:s} -C {2:s}'.format(self.tool['tar'], path, self.env['BUILD']), + '.gz': self.tool['gunzip'], + '.bz2': self.tool['bunzip'], + '.zip': self.tool['unzip'] + } + cmd = [] + for k, v in ext.items(): + if k in path: + cmd = v.split() + print(string.join(cmd)) + subprocess.check_output(cmd) + break + return True + + def create_buildroot(self, *p): + """Destroy/Create BUILDROOT per execution to keep the envrionment stable + + p: tuple of function arguments + """ + path = self.env_pkg['BUILDROOT'] + if os.path.exists(path): + shutil.rmtree(path) + os.mkdir(path) + return True + + def create_metadata(self, *p): + output = [] + meta_map = { + 'pkg.fmri': self.key_dict['name'], + 'pkg.description': self.key_dict['description'], + 'pkg.summary': self.key_dict['summary'], + 'variant.arch': self.key_dict['arch'], + 'info.upstream_url': self.key_dict['upstream_url'], + 'info.source_url': self.key_dict['source_url'], + 'info.classification': self.key_dict['classification'] + } + + # Perform manifest template mapping and expansion + template = file(tpl.metadata, 'r') + for line in template.readlines(): + for k, v in meta_map.items(): + if k in line: + # pkg.fmri requires special attention to build the proper + # package name IPS wants + if k == 'pkg.fmri': + output.append(line.replace('{}', + self.key_dict['group'] + + "/" + + self.key_dict['name'] + + "@" + + self.key_dict['version'] + + "," + + self.key_dict['release'] + )) + continue + # The rest of the value replacements are rather simple + output.append(line.replace('{}', v)) + template.close() + + # Generate intial IPS manifest file in buildroot + manifest = file(os.path.join(self.env_pkg['BUILDROOT'], self.complete_name + '.p5m.1'), 'w+') + for line in output: + manifest.writelines(line) + print(manifest.name) + manifest.close() + return True + + def create_package_list(self, *p): + pass + + + def show_summary(self): + print("Summary of {0:s}".format(self.key_dict['name'])) + for k, v in sorted(self.key_dict.items()): + print("+ {0:s}: {1:s}".format(k, v)) |