Example #1
0
 def test_expand(self):
     tests = (
             ('', ''),
             ('foo', 'foo'),
             ('foobutter', 'foo$CuPrUm_test'),
             ('foobutterb', 'foo${CuPrUm_test}b'),
             (os.environ['HOME'], '~'),
             )
     t = Environment()
     os.environ['CuPrUm_test'] = 'butter'
     for (expected, test) in tests:
         self.assertEqual(expected, t.expand(test))
     del os.environ['CuPrUm_test']
Example #2
0
 def test_basic(self):
     t = Environment()
     list(t)  # __iter__
     self.assertRaises(TypeError, hash, t)
     len(t)
     self.assertTrue('PATH' in t)
     self.assertFalse('FOOBAR72' in t)
     self.assertRaises(KeyError, lambda: t['FOOBAR72'])
     self.assertRaises(ProcessExecutionError, local.python, '-c', 'import os;os.environ["FOOBAR72"]')
     t['FOOBAR72'] = 'spAm'
     self.assertEqual(local.python('-c', 'import os;print (os.environ["FOOBAR72"])').splitlines(), ['spAm'])
     del t['FOOBAR72']
     t.keys()
     t.items()
     t.values()
     t.get('HOME')
Example #3
0
 def __init__(self):
     self.cwd = CWD()
     self.env = Environment()
     self.encoding = sys.getfilesystemencoding()
     self.python = Command(sys.executable, self.encoding)
Example #4
0
class LocalSystem(object):
    '''The *local machine* (a singleton object). It serves as an entry point to
    everything related to the local machine, such as working directory and
    environment manipulation, command creation, etc.

    Attributes:
      - ``env`` - Local environment <cu.env.Environment>
      - ``cwd`` - Local current working directory <cu.path.CWD>
      - ``python`` - Python interpreter (``sys.executable``) <cu.command.Command>
      - ``encoding`` - Local encoding (``sys.getfilesystemencoding()``)
      - ''session()'' - ShellSession <cu.session.ShellSession>
      - ''tempdir()'' - Temp directory context manager
      - ''tempfile()'' - Temp file context manager
    '''

    def __init__(self):
        self.cwd = CWD()
        self.env = Environment()
        self.encoding = sys.getfilesystemencoding()
        self.python = Command(sys.executable, self.encoding)

    def __getitem__(self, command):
        '''Returns a `Command` object representing the given program. ``command``
        can be a string or a :class:`Path <cu.path.Path>`; if it is a path, a
        command representing this path will be returned; otherwise, the program
        name will be looked up in the system's ``PATH`` (using ``which``).
        Usage::

            ls=local('ls')
        '''
        if isinstance(command, Path):
            return Command(command)
        elif isinstance(command, str):
            if '/' in command or '\\' in command:  # assume path
                return Command(Path(command))
            else:  # search for command
                return Command(self.which(command))
        else:
            raise TypeError('command must be a Path or a string: %r' % (command,))

    if os.name == 'nt':
        def _which(self, command, filelist):
            command = command.lower()
            for ext in [''] + self.env.get('PATHEXT', ':.exe:.bat').lower().split(os.path.pathsep):
                n = command + ext
                if n in filelist:
                    return filelist[n]
    else:
        def _which(self, command, filelist):
            if command in filelist:
                f = filelist[command]
                if f.stat().st_mode & stat.S_IXUSR:
                    return f

    def which(self, progname):
        '''Looks up a program in the ``PATH``. If the program is not found, raises
        :class:`CommandNotFound <cu.command.CommandNotFound>`

        :param progname: The program's name. Note that if underscores (``_``) are present
                         in the name, and the exact name is not found, they will be replaced
                         by hyphens (``-``) and the name will be looked up again

        :returns: A :class:`Path <cu.path.Path>`
        '''
        alternatives = [progname, ]
        if '_' in progname:
            alternatives.append(progname.replace('_', '-'))
        for command in alternatives:
            for path in self.env.path:
                try:
                    filelist = dict((n.basename, n) for n in path.list())
                    found = self._which(command, filelist)
                    if found:
                        return found
                except OSError:
                    continue
        raise CommandNotFound(progname, list(self.env.path))

    def session(self):
        '''Creates a new :class:`ShellSession <cu.session.ShellSession>` object;
        this invokes ``/bin/sh`` and executes commands on it over
        stdin/stdout/stderr
        '''
        return ShellSession(self['sh'].popen())

    @contextlib.contextmanager
    def tempdir(self, *args, **kwargs):
        '''Context manager that creates a temporary directory, which is
        removed when the context exits.
        :param suffix
        :yields: :class:`Path` object
        '''
        path = Path(tempfile.mkdtemp(*args, **kwargs))
        try:
            yield path
        finally:
            path.delete()

    @contextlib.contextmanager
    def tempfile(self, mode='w+b', bufsize=-1, suffix='', prefix='tmp', dir=None):
        '''Context manager that creates a named temporary file, which is
        removed when the context exits.

        Unteted and probably does not work in Python 2.5

        :yields: file handle object with attribut 'name', a :class:`Path` object
        '''
        # Explicitly named kwargs cause order changes in Python 3.x
        # Also, bufsize renamed buffering
        kwargs = dict(mode=mode, suffix=suffix, prefix=prefix, dir=dir, delete=False)
        if six.PY3:
            if bufsize >= 0:
                kwargs['buffering'] = bufsize
        else:
            kwargs['bufsize'] = bufsize
        fh = tempfile.NamedTemporaryFile(**kwargs)
        fh.name = Path(fh.name)
        try:
            yield fh
        finally:
            fh.name.delete()