def _build(self, component, manifest): """ Worker method for building a single component. """ # Store the major / minor / release values major = manifest['major'] minor = manifest['minor'] release = manifest['release'] print('Preparing to package component: %s' % component) print('Generating new release: %s.%s-%s -> %s.%s-%s' % (major, minor, release, major, minor, (release + 1))) # Update the manifest release value manifest['release'] = release + 1 # Construct the package build root build_root = 'tmp/%s_%s.%s-%s' % (component, major, minor, manifest['release']) self._build_pkg_root(build_root, manifest['source']) # Generate the control file self._create_control_file(component, build_root, manifest) # Copy any extra scripts self._copy_scripts(component, build_root) # Build the package build_package(build_root, copy_files=False, repository='output') print('Successfully built component "%s" package: %s_%s.%s-%s.deb' % (component, component, major, minor, manifest['release'])) # Update the manifest print('Updating release in manifest') with open('manifest/%s' % component, 'w') as handle: json.dump(manifest, handle)
def build(self): """ Ref: https://linuxconfig.org/easy-way-to-create-a-debian-package-and-local-package-repository """ configdir = join(self.config.config_dir(), self.pkgtype) makedirs(configdir + '/DEBIAN', exist_ok=True) self.control(configdir) self.layout(configdir) return build_package(configdir)
def build(self): """ Ref: https://linuxconfig.org/easy-way-to-create-a-debian-package-and-local-package-repository """ configdir = self.config.config_dir() makedirs(configdir + '/DEBIAN', exist_ok=True) with open(configdir + '/DEBIAN/control', 'w') as f: content = [ 'Package: %s\n' % self.config.name, 'Version: %s\n' % self.config.version, 'Section: Custom\n', 'Priority: optional\n', 'Architecture: all\n', 'Essential: no\n', 'Maintainer: %s\n' % self.config.maintainers, 'Description: %s\n' % self.config.description ] f.writelines(content) return build_package(configdir)
def _build_deb(self, temp_dir, outputdir, *args, **kwargs): os.makedirs(outputdir, exist_ok=True) build_package(temp_dir, outputdir)
def convert(self): """ Convert current package from Python package to Debian package. :returns: The pathname of the generated ``*.deb`` archive. """ with TemporaryDirectory(prefix='py2deb-build-') as build_directory: # Prepare the absolute pathname of the Python interpreter on the # target system. This pathname will be embedded in the first line # of executable scripts (including the post-installation and # pre-removal scripts). python_executable = '/usr/bin/%s' % python_version() # Unpack the binary distribution archive provided by pip-accel inside our build directory. build_install_prefix = os.path.join( build_directory, self.converter.install_prefix.lstrip('/')) self.converter.pip_accel.bdists.install_binary_dist( members=self.transform_binary_dist(python_executable), prefix=build_install_prefix, python=python_executable, virtualenv_compatible=False, ) # Determine the directory (at build time) where the *.py files for # Python modules are located (the site-packages equivalent). if self.has_custom_install_prefix: build_modules_directory = os.path.join(build_install_prefix, 'lib') else: # The /py*/ pattern below is intended to match both /pythonX.Y/ and /pypyX.Y/. dist_packages_directories = glob.glob( os.path.join(build_install_prefix, 'lib/py*/dist-packages')) if len(dist_packages_directories) != 1: msg = "Expected to find a single 'dist-packages' directory inside converted package!" raise Exception(msg) build_modules_directory = dist_packages_directories[0] # Determine the directory (at installation time) where the *.py # files for Python modules are located. install_modules_directory = os.path.join( '/', os.path.relpath(build_modules_directory, build_directory)) # Execute a user defined command inside the directory where the Python modules are installed. command = self.converter.scripts.get(self.python_name.lower()) if command: execute(command, directory=build_modules_directory, logger=logger) # Determine the package's dependencies, starting with the currently # running version of Python and the Python requirements converted # to Debian packages. dependencies = [python_version()] + self.debian_dependencies # Check if the converted package contains any compiled *.so files. object_files = find_object_files(build_directory) if object_files: # Strip debugging symbols from the object files. strip_object_files(object_files) # Determine system dependencies by analyzing the linkage of the # *.so file(s) found in the converted package. dependencies += find_system_dependencies(object_files) # Make up some control file fields ... :-) architecture = self.determine_package_architecture(object_files) control_fields = unparse_control_fields( dict(package=self.debian_name, version=self.debian_version, maintainer=self.debian_maintainer, description=self.debian_description, architecture=architecture, depends=dependencies, priority='optional', section='python')) # Automatically add the Mercurial global revision id when available. if self.vcs_revision: control_fields['Vcs-Hg'] = self.vcs_revision # Apply user defined control field overrides from `stdeb.cfg'. control_fields = self.load_control_field_overrides(control_fields) # Create the DEBIAN directory. debian_directory = os.path.join(build_directory, 'DEBIAN') os.mkdir(debian_directory) # Generate the DEBIAN/control file. control_file = os.path.join(debian_directory, 'control') logger.debug("Saving control file fields to %s: %s", control_file, control_fields) with open(control_file, 'wb') as handle: control_fields.dump(handle) # Lintian is a useful tool to find mistakes in Debian binary # packages however Lintian checks from the perspective of a package # included in the official Debian repositories. Because py2deb # doesn't and probably never will generate such packages some # messages emitted by Lintian are useless (they merely point out # how the internals of py2deb work). Because of this we silence # `known to be irrelevant' messages from Lintian using overrides. if self.converter.lintian_ignore: overrides_directory = os.path.join( build_directory, 'usr', 'share', 'lintian', 'overrides', ) overrides_file = os.path.join(overrides_directory, self.debian_name) os.makedirs(overrides_directory) with open(overrides_file, 'w') as handle: for tag in self.converter.lintian_ignore: handle.write('%s: %s\n' % (self.debian_name, tag)) # Find the alternatives relevant to the package we're building. alternatives = set( (link, path) for link, path in self.converter.alternatives if os.path.isfile( os.path.join(build_directory, path.lstrip('/')))) # Generate post-installation and pre-removal maintainer scripts. self.generate_maintainer_script( filename=os.path.join(debian_directory, 'postinst'), python_executable=python_executable, function='post_installation_hook', package_name=self.debian_name, alternatives=alternatives, modules_directory=install_modules_directory, namespaces=self.namespaces) self.generate_maintainer_script( filename=os.path.join(debian_directory, 'prerm'), python_executable=python_executable, function='pre_removal_hook', package_name=self.debian_name, alternatives=alternatives, modules_directory=install_modules_directory, namespaces=self.namespaces) # Enable a user defined Python callback to manipulate the resulting # binary package before it's turned into a *.deb archive (e.g. # manipulate the contents or change the package metadata). if self.converter.python_callback: logger.debug("Invoking user defined Python callback ..") self.converter.python_callback(self.converter, self, build_directory) logger.debug("User defined Python callback finished!") return build_package(directory=build_directory, check_package=self.converter.lintian_enabled, copy_files=False)
def convert(self): """ Convert current package from Python package to Debian package. :returns: The pathname of the generated ``*.deb`` archive. """ with TemporaryDirectory(prefix='py2deb-build-') as build_directory: # Prepare the absolute pathname of the Python interpreter on the # target system. This pathname will be embedded in the first line # of executable scripts (including the post-installation and # pre-removal scripts). python_executable = '/usr/bin/%s' % python_version() # Unpack the binary distribution archive provided by pip-accel inside our build directory. build_install_prefix = os.path.join(build_directory, self.converter.install_prefix.lstrip('/')) self.converter.pip_accel.bdists.install_binary_dist( members=self.transform_binary_dist(), prefix=build_install_prefix, python=python_executable, virtualenv_compatible=False, ) # Determine the directory (at build time) where the *.py files for # Python modules are located (the site-packages equivalent). if self.has_custom_install_prefix: build_modules_directory = os.path.join(build_install_prefix, 'lib') else: dist_packages_directories = glob.glob(os.path.join(build_install_prefix, 'lib/python*/dist-packages')) if len(dist_packages_directories) != 1: msg = "Expected to find a single 'dist-packages' directory inside converted package!" raise Exception(msg) build_modules_directory = dist_packages_directories[0] # Determine the directory (at installation time) where the *.py # files for Python modules are located. install_modules_directory = os.path.join('/', os.path.relpath(build_modules_directory, build_directory)) # Execute a user defined command inside the directory where the Python modules are installed. command = self.converter.scripts.get(self.python_name.lower()) if command: execute(command, directory=build_modules_directory, logger=logger) # Determine the package's dependencies, starting with the currently # running version of Python and the Python requirements converted # to Debian packages. dependencies = [python_version()] + self.debian_dependencies # Check if the converted package contains any compiled *.so files. shared_object_files = self.find_shared_object_files(build_directory) if shared_object_files: # Determine system dependencies by analyzing the linkage of the # *.so file(s) found in the converted package. dependencies += self.find_system_dependencies(shared_object_files) # Make up some control file fields ... :-) architecture = self.determine_package_architecture(shared_object_files) control_fields = unparse_control_fields(dict(package=self.debian_name, version=self.debian_version, maintainer=self.debian_maintainer, description=self.debian_description, architecture=architecture, depends=dependencies, priority='optional', section='python')) # Automatically add the Mercurial global revision id when available. if self.vcs_revision: control_fields['Vcs-Hg'] = self.vcs_revision # Apply user defined control field overrides from `stdeb.cfg'. control_fields = self.load_control_field_overrides(control_fields) # Create the DEBIAN directory. debian_directory = os.path.join(build_directory, 'DEBIAN') os.mkdir(debian_directory) # Generate the DEBIAN/control file. control_file = os.path.join(debian_directory, 'control') logger.debug("Saving control file fields to %s: %s", control_file, control_fields) with open(control_file, 'wb') as handle: control_fields.dump(handle) # Lintian is a useful tool to find mistakes in Debian binary # packages however Lintian checks from the perspective of a package # included in the official Debian repositories. Because py2deb # doesn't and probably never will generate such packages some # messages emitted by Lintian are useless (they merely point out # how the internals of py2deb work). Because of this we silence # `known to be irrelevant' messages from Lintian using overrides. overrides_directory = os.path.join(build_directory, 'usr', 'share', 'lintian', 'overrides') overrides_file = os.path.join(overrides_directory, self.debian_name) os.makedirs(overrides_directory) with open(overrides_file, 'w') as handle: for tag in ['debian-changelog-file-missing', 'embedded-javascript-library', 'extra-license-file', 'unknown-control-interpreter', 'vcs-field-uses-unknown-uri-format']: handle.write('%s: %s\n' % (self.debian_name, tag)) # Find the alternatives relevant to the package we're building. alternatives = set((link, path) for link, path in self.converter.alternatives if os.path.isfile(os.path.join(build_directory, path.lstrip('/')))) # Generate post-installation and pre-removal maintainer scripts. self.generate_maintainer_script(filename=os.path.join(debian_directory, 'postinst'), python_executable=python_executable, function='post_installation_hook', package_name=self.debian_name, alternatives=alternatives, modules_directory=install_modules_directory, namespaces=self.namespaces) self.generate_maintainer_script(filename=os.path.join(debian_directory, 'prerm'), python_executable=python_executable, function='pre_removal_hook', package_name=self.debian_name, alternatives=alternatives, modules_directory=install_modules_directory, namespaces=self.namespaces) # Enable a user defined Python callback to manipulate the resulting # binary package before it's turned into a *.deb archive (e.g. # manipulate the contents or change the package metadata). if self.converter.python_callback: logger.debug("Invoking user defined Python callback ..") self.converter.python_callback(self.converter, self, build_directory) logger.debug("User defined Python callback finished!") return build_package(directory=build_directory, check_package=self.converter.lintian_enabled, copy_files=False)