# 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 . 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 """ # BUILDPROTO is a subdirectory of BUILDROOT/pkgname path = self.env_pkg['BUILDPROTO'] if os.path.exists(path): shutil.rmtree(path) os.makedirs(path, 0755) 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 + '.mog'), '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))