def _InstallFiles(self, force): dest = util.GetInstallRoot(self.config) dest_tmp = os.path.join(dest, 'install_tmp') if os.path.exists(dest_tmp): shutil.rmtree(dest_tmp) if self.IsAnyVersionInstalled(): raise error.Error('package already installed: %s' % self.InfoString()) self.LogStatus('Installing') util.LogVerbose('installing from: %s' % self.filename) util.Makedirs(dest_tmp) names = [] try: with tarfile.open(self.filename) as tar: for info in tar: if info.isdir(): continue name = posixpath.normpath(info.name) if name == 'pkg_info': continue if not name.startswith(PAYLOAD_DIR + '/'): raise error.PkgFormatError( 'invalid file in package: %s' % name) name = name[len(PAYLOAD_DIR) + 1:] names.append(name) if not force: for name in names: full_name = os.path.join(dest, name) if os.path.exists(full_name): raise error.Error('file already exists: %s' % full_name) tar.extractall(dest_tmp) payload_tree = os.path.join(dest_tmp, PAYLOAD_DIR) names = FilterOutExecutables(names, payload_tree) for name in names: InstallFile(name, payload_tree, dest) finally: shutil.rmtree(dest_tmp) for name in names: RelocateFile(name, dest) self.WriteFileList(names)
def GetEmscriptenRoot(): emscripten = os.environ.get('EMSCRIPTEN') if emscripten is None: local_root = os.path.join(paths.OUT_DIR, 'emsdk_portable', 'emscripten', 'master') if os.path.exists(local_root): emscripten = local_root else: raise error.Error('$EMSCRIPTEN not set') if not os.path.isdir(emscripten): raise error.Error('$EMSCRIPTEN environment variable does not point' ' to a directory: %s' % emscripten) return emscripten
def VerifyArchiveFormat(self): if not os.path.exists(self.filename): raise error.Error('package archive not found: %s' % self.filename) basename, extension = os.path.splitext(os.path.basename(self.filename)) basename = os.path.splitext(basename)[0] if extension != '.bz2': raise error.Error('invalid file extension: %s' % extension) try: with tarfile.open(self.filename) as tar: if './pkg_info' not in tar.getnames(): raise error.PkgFormatError( 'package does not contain pkg_info file') except tarfile.TarError as e: raise error.PkgFormatError(e)
def RemoveTree(directory): """Recursively remove a directory and its contents.""" if not os.path.exists(directory): return if not os.path.isdir(directory): raise error.Error('RemoveTree: not a directory: %s', directory) shutil.rmtree(directory)
def __enter__(self): try: fcntl.flock(self.fd, fcntl.LOCK_EX | fcntl.LOCK_NB) except Exception: raise error.Error( "Unable to acquire lock (%s): Is naclports already " "running?" % self.file_name)
def DownloadFile(filename, url): """Download a file from a given URL. Args: filename: the name of the file to download the URL to. url: then URL to fetch. """ temp_filename = filename + '.partial' # Ensure curl is in user's PATH FindInPath('curl') curl_cmd = [ 'curl', '--fail', '--location', '--stderr', '-', '-o', temp_filename ] if hasattr(sys.stdout, 'fileno') and os.isatty(sys.stdout.fileno()): # Add --progress-bar but only if stdout is a TTY device. curl_cmd.append('--progress-bar') else: # otherwise suppress status output, since curl always assumes its # talking to a TTY and writes \r and \b characters. But add # --show-error so that when curl fails it at least prints something. curl_cmd += ['--silent', '--show-error'] curl_cmd.append(url) if log_level > LOG_WARN: Log('Downloading: %s [%s]' % (url, filename)) else: Log('Downloading: %s' % url.replace(GS_URL, '')) try: subprocess.check_call(curl_cmd) except subprocess.CalledProcessError as e: raise error.Error('Error downloading file: %s' % str(e)) os.rename(temp_filename, filename)
def Makedirs(directory): if os.path.isdir(directory): return if os.path.exists(directory): raise error.Error('mkdir: File exists and is not a directory: %s' % directory) Trace("mkdir: %s" % directory) os.makedirs(directory)
def CheckDeps(pkg_name, required_by): if pkg_name in checked: return checked.add(pkg_name) pkg = installed_map.get(pkg_name) if not pkg: raise error.Error("missing package '%s' required by '%s'" % (pkg_name, required_by)) for dep in pkg.DEPENDS: CheckDeps(dep, pkg.NAME)
def CheckSDKRoot(): """Check validity of NACL_SDK_ROOT.""" root = GetSDKRoot() if not os.path.isdir(root): raise error.Error('$NACL_SDK_ROOT does not exist: %s' % root) landmark = os.path.join(root, 'tools', 'getos.py') if not os.path.exists(landmark): raise error.Error("$NACL_SDK_ROOT (%s) doesn't look right. " "Couldn't find landmark file (%s)" % (root, landmark)) if not CheckSDKVersion(MIN_SDK_VERSION): raise error.Error( 'This version of naclports requires at least version %s of\n' 'the NaCl SDK. The version in $NACL_SDK_ROOT is %s. If you want\n' 'to use naclports with an older version of the SDK please checkout\n' 'one of the pepper_XX branches (or run with\n' '--skip-sdk-version-check).' % (MIN_SDK_VERSION, GetSDKVersion()))
def CmdInfo(config, options, args): """Print infomation on installed package(s)""" if len(args) != 1: raise error.Error('info command takes a single package name') package_name = args[0] pkg = installed_package.CreateInstalledPackage(package_name, config) info_file = pkg.GetInstallStamp() print('Install receipt: %s' % info_file) with open(info_file) as f: sys.stdout.write(f.read())
def __init__(self, arch=None, toolchain=None, debug=None): self.debug = None self.libc = None self.config_name = None self.SetConfig(debug) if arch is None: arch = os.environ.get('NACL_ARCH') if toolchain is None: toolchain = os.environ.get('TOOLCHAIN') if not toolchain: if arch == 'pnacl': toolchain = 'pnacl' elif arch == 'emscripten': toolchain = 'emscripten' else: toolchain = self.default_toolchain self.toolchain = toolchain if self.toolchain not in VALID_TOOLCHAINS: raise error.Error("Invalid toolchain: %s" % self.toolchain) if not arch: if self.toolchain == 'pnacl': arch = 'pnacl' elif self.toolchain == 'emscripten': arch = 'emscripten' elif self.toolchain == 'bionic': arch = 'arm' elif platform.machine() == 'i686': arch = 'i686' else: arch = 'x86_64' self.arch = arch if self.arch not in util.arch_to_pkgarch: raise error.Error("Invalid arch: %s" % arch) self.SetLibc()
def CmdPkgUninstall(package, options): """Uninstall package(s)""" for dep in package.ReverseDependencies(): if options.force or options.all: PerformUninstall(dep) else: raise error.Error("unable to uninstall '%s'. another package is " "installed which depends on it: '%s'" % (package.NAME, dep.NAME)) package.Uninstall()
def GetSDKRoot(): """Returns the root of the currently configured Native Client SDK.""" root = os.environ.get('NACL_SDK_ROOT') if root is None: local_sdk_root = os.path.join(paths.OUT_DIR, 'nacl_sdk') if os.path.exists(local_sdk_root): root = local_sdk_root else: raise error.Error('$NACL_SDK_ROOT not set') if sys.platform == "cygwin": root = root.replace('\\', '/') return root
def CmdList(config, options, args): """List installed packages""" if len(args): raise error.Error('list command takes no arguments') if options.all: iterator = source_package.SourcePackageIterator() else: iterator = installed_package.InstalledPackageIterator(config) for package in iterator: if options.verbosity: sys.stdout.write('%-15s %s\n' % (package.NAME, package.VERSION)) else: sys.stdout.write(package.NAME + '\n') return 0
def ParseIndex(self, index_data): if not index_data: return for info_files in index_data.split('\n\n'): info = pkg_info.ParsePkgInfo(info_files, self.filename, self.valid_keys, self.required_keys) debug = info['BUILD_CONFIG'] == 'debug' config = configuration.Configuration(info['BUILD_ARCH'], info['BUILD_TOOLCHAIN'], debug) key = (info['NAME'], config) if key in self.packages: error.Error('package index contains duplicate: %s' % str(key)) self.packages[key] = info
def FindInPath(command_name): """Search user's PATH for a given executable. Returns: Full path to executable. """ extensions = ('', ) if not os.path.splitext(command_name)[1] and os.name == 'nt': extensions = ('.bat', '.com', '.exe') for path in os.environ.get('PATH', '').split(os.pathsep): for ext in extensions: full_name = os.path.join(path, command_name + ext) if os.path.exists(full_name) and os.path.isfile(full_name): return full_name raise error.Error('command not found: %s' % command_name)
def SetupEmscripten(): if 'EMSCRIPTEN' in os.environ: return local_root = GetEmscriptenRoot() os.environ['EMSCRIPTEN'] = local_root os.environ['EM_CONFIG'] = os.path.join(os.path.dirname(local_root), '.emscripten') try: FindInPath('node') except error.Error: node_bin = os.path.join(paths.OUT_DIR, 'node', 'bin') if not os.path.isdir(node_bin): raise error.Error('node not found in path and default path not found: %s' % node_bin) os.environ['PATH'] += ':' + node_bin FindInPath('node')
class TestMain(common.NaclportsTest): def setUp(self): super(TestMain, self).setUp() self.AddPatch(patch('naclports.util.CheckSDKRoot')) @patch('naclports.util.Log', Mock()) @patch('naclports.util.RemoveTree') def testCleanAll(self, mock_rmtree): config = Configuration() naclports.__main__.CleanAll(config) mock_rmtree.assert_any_call('/package/install/path') @patch('naclports.__main__.RunMain', Mock(side_effect=error.Error('oops'))) def testErrorReport(self): # Verify that exceptions of the type error.Error are printed # to stderr and result in a return code of 1 with patch('sys.stderr', new_callable=StringIO.StringIO) as stderr: self.assertEqual(naclports.__main__.main(None), 1) self.assertRegexpMatches(stderr.getvalue(), '^naclports: oops') @patch('naclports.__main__.CmdPkgClean') def testMainCommandDispatch(self, cmd_pkg_clean): mock_pkg = Mock() with patch('naclports.source_package.CreatePackage', Mock(return_value=mock_pkg)): naclports.__main__.RunMain(['clean', 'foo']) cmd_pkg_clean.assert_called_once_with(mock_pkg, mock.ANY) @patch('naclports.__main__.CmdPkgClean', Mock(side_effect=error.DisabledError())) def testMainHandlePackageDisabled(self): mock_pkg = Mock() with patch('naclports.source_package.CreatePackage', Mock(return_value=mock_pkg)): with self.assertRaises(error.DisabledError): naclports.__main__.RunMain(['clean', 'foo']) @patch('naclports.__main__.CleanAll') def testMainCleanAll(self, clean_all_mock): naclports.__main__.RunMain(['clean', '--all']) clean_all_mock.assert_called_once_with(Configuration())
def DoUninstall(self, force): with util.InstallLock(self.config): if not force: for pkg in InstalledPackageIterator(self.config): if self.NAME in pkg.DEPENDS: raise error.Error("Unable to uninstall '%s' (depended on by '%s')" % (self.NAME, pkg.NAME)) RemoveFile(self.GetInstallStamp()) root = util.GetInstallRoot(self.config) for filename in self.Files(): fullname = os.path.join(root, filename) if not os.path.lexists(fullname): util.Warn('File not found while uninstalling: %s' % fullname) continue util.LogVerbose('uninstall: %s' % filename) RemoveFile(fullname) if os.path.exists(self.GetListFile()): RemoveFile(self.GetListFile())
def CmdCheck(config, options, args): """Verify the dependecies of all install packages are also installed.""" if len(args): raise error.Error('check command takes no arguments') installed_packages = installed_package.InstalledPackageIterator(config) installed_map = {pkg.NAME: pkg for pkg in installed_packages} checked = set() def CheckDeps(pkg_name, required_by): if pkg_name in checked: return checked.add(pkg_name) pkg = installed_map.get(pkg_name) if not pkg: raise error.Error("missing package '%s' required by '%s'" % (pkg_name, required_by)) for dep in pkg.DEPENDS: CheckDeps(dep, pkg.NAME) for pkg in installed_map.itervalues(): CheckDeps(pkg.NAME, None)
def CreateInstalledPackage(package_name, config=None): stamp_root = util.GetInstallStampRoot(config) info_file = os.path.join(stamp_root, package_name + '.info') if not os.path.exists(info_file): raise error.Error('package not installed: %s [%s]' % (package_name, config)) return InstalledPackage(info_file)