def rewrite_python_shebangs(root_dir): """Recursively change #!/usr/bin/pythonX shebangs to #!/usr/bin/env pythonX :param str root_dir: Directory that will be crawled for shebangs. """ file_pattern = re.compile(r"") argless_shebang_pattern = re.compile(r"\A#!.*(python\S*)$", re.MULTILINE) shebang_pattern_with_args = re.compile( r"\A#!.*(python\S*)[ \t\f\v]+(\S+)$", re.MULTILINE ) file_utils.replace_in_file( root_dir, file_pattern, argless_shebang_pattern, r"#!/usr/bin/env \1" ) # The above rewrite will barf if the shebang includes any args to python. # For example, if the shebang was `#!/usr/bin/python3 -Es`, just replacing # that with `#!/usr/bin/env python3 -Es` isn't going to work as `env` # doesn't support arguments like that. # # The solution is to replace the shebang with one pointing to /bin/sh, and # then exec the original shebang with included arguments. This requires # some quoting hacks to ensure the file can be interpreted by both sh as # well as python, but it's better than shipping our own `env`. file_utils.replace_in_file( root_dir, file_pattern, shebang_pattern_with_args, r"""#!/bin/sh\n''''exec \1 \2 -- "$0" "$@" # '''""", )
def _use_in_snap_python(self): # Fix all shebangs to use the in-snap python. mangling.rewrite_python_shebangs(self.installdir) # Also replace all the /usr/bin/python calls in etc/catkin/profile.d/ # files with the in-snap python profile_d_path = os.path.join(self.rosdir, "etc", "catkin", "profile.d") file_utils.replace_in_file(profile_d_path, re.compile(r""), re.compile(r"/usr/bin/python"), r"python")
def _ruby_install(self, builddir): self._ruby_tar.provision(builddir, clean_target=False, keep_tarball=True) self._run(["./configure", "--disable-install-rdoc", "--prefix=/"], cwd=builddir) self._run(["make", "-j{}".format(self.parallel_build_count)], cwd=builddir) self._run(["make", "install", "DESTDIR={}".format(self.installdir)], cwd=builddir) # Fix all shebangs to use the in-snap ruby file_utils.replace_in_file( self.installdir, re.compile(r""), re.compile(r"^#!.*ruby"), r"#!/usr/bin/env ruby", )
def _rewrite_cmake_paths(self, new_path_callable): def _rewrite_paths(match): paths = match.group(1).strip().split(";") for i, path in enumerate(paths): # Offer the opportunity to rewrite this path if it's absolute. if os.path.isabs(path): paths[i] = new_path_callable(path) return '"' + ";".join(paths) + '"' # Looking for any path-like string file_utils.replace_in_file( self.rosdir, re.compile(r".*Config.cmake$"), re.compile(r'"(.*?/.*?)"'), _rewrite_paths, )
def _prepare_build(self): self._use_in_snap_python() # Each Catkin package distributes .cmake files so they can be found via # find_package(). However, the Ubuntu packages pulled down as # dependencies contain .cmake files pointing to system paths (e.g. # /usr/lib, /usr/include, etc.). They need to be rewritten to point to # the install directory. def _new_path(path): if not path.startswith(self.installdir): # Not using os.path.join here as `path` is absolute. return self.installdir + path return path self._rewrite_cmake_paths(_new_path) # Also rewrite any occurrence of $SNAPCRAFT_STAGE to be our install # directory (this may be the case if stage-snaps were used). file_utils.replace_in_file( self.rosdir, re.compile(r".*Config.cmake$"), re.compile(r"\$ENV{SNAPCRAFT_STAGE}"), self.installdir, )