示例#1
0
    def exec_with_wrapper(exec_with, install_dir, cmd_list):
        '''Wrapper function for inserting the execution wrapper, e.g., 'cabal exec' or 'stack exec'

        :returns: Process object from ProcHelper.
        '''

        proc_args = {}
        if exec_with is not None:
            if exec_with == 'cabal':
                cmd_list = ['cabal', 'exec'] + cmd_list
                cmd_list.insert(3, '--')
            elif exec_with == 'stack':
                cmd_list = ['stack', 'exec'] + cmd_list
                cmd_list.insert(3, '--')
            else:
                errmsg = 'HsDevBackend.exec_with_wrapper: Unknown execution prefix \'{0}\''.format(
                    exec_with)
                raise RuntimeError(errmsg)

            if install_dir is not None:
                proc_args['cwd'] = Utils.normalize_path(install_dir)
        else:
            cmd = Which.which(cmd_list[0],
                              ProcHelper.ProcHelper.get_extended_path())
            if cmd is not None:
                cmd_list[0] = cmd

        Logging.log('HsDevBackend.exec_with_wrapper: {0}'.format(cmd_list),
                    Logging.LOG_DEBUG)
        return ProcHelper.ProcHelper(cmd_list, **proc_args)
示例#2
0
def cabal_new_clean(project_dir):
    '''Internal command that does the "cabal new-"-style 'clean' command (until it is actually implemented.)
    '''
    def remove_subdir_recursively(subdir):
        subdir = Utils.normalize_path(os.path.join(project_dir, subdir))
        if os.path.exists(subdir):
            if os.path.isdir(subdir):
                for dirpath, _dirnames, filenames in os.walk(subdir, topdown=False):
                    try:
                        for fname in filenames:
                            os.remove(os.path.join(dirpath, fname))
                        os.rmdir(dirpath)
                    except OSError as ex:
                        diag_feedback.append(str(ex))
                        print(ex)
            else:
                os.remove(subdir)

    cabal_project_local = Utils.normalize_path(os.path.join(project_dir, 'cabal.project.local'))

    diag_feedback = []

    for subd in ['dist-newstyle', 'dist']:
        remove_subdir_recursively(subd)
    if os.path.exists(cabal_project_local):
        os.remove(cabal_project_local)

    return (0 if not diag_feedback else 1, '\n'.join(diag_feedback))
示例#3
0
def cabal_new_clean(project_dir):
    '''Internal command that does the "cabal new-"-style 'clean' command (until it is actually implemented.)
    '''
    def remove_subdir_recursively(subdir):
        subdir = Utils.normalize_path(os.path.join(project_dir, subdir))
        if os.path.exists(subdir):
            if os.path.isdir(subdir):
                for dirpath, _dirnames, filenames in os.walk(subdir, topdown=False):
                    try:
                        for fname in filenames:
                            os.remove(os.path.join(dirpath, fname))
                        os.rmdir(dirpath)
                    except OSError as ex:
                        diag_feedback.append(str(ex))
                        print(ex)
            else:
                os.remove(subdir)

    cabal_project_local = Utils.normalize_path(os.path.join(project_dir, 'cabal.project.local'))

    diag_feedback = []

    for subd in ['dist-newstyle', 'dist']:
        remove_subdir_recursively(subd)
    if os.path.exists(cabal_project_local):
        os.remove(cabal_project_local)

    return (0 if not diag_feedback else 1, '\n'.join(diag_feedback))
示例#4
0
    def make_augmented_path():
        ''' Generate the augmented PATH for subprocesses: adds the appropriate cabal/stack local install directory
        ($HOME/.local/bin for *nix, %APPDATA%/local/bin for Windows) and updates PATH with `add_to_PATH` extras.
        '''
        std_places = []
        if Settings.PLUGIN.add_standard_dirs:
            std_places.append("$HOME/.local/bin" if not Utils.is_windows() else
                              "%APPDATA%/local/bin")
            if Utils.is_macosx():
                std_places.append('$HOME/Library/Haskell/bin')
            std_places += CabalConfigRdr.cabal_config()
            std_places = [
                dir
                for dir in [Utils.normalize_path(path) for path in std_places]
                if os.path.isdir(dir)
            ]

        add_to_path = list(
            filter(os.path.isdir,
                   map(Utils.normalize_path, Settings.PLUGIN.add_to_path)))

        Logging.log("std_places = {0}".format(std_places), Logging.LOG_INFO)
        Logging.log("add_to_PATH = {0}".format(add_to_path), Logging.LOG_INFO)

        return os.pathsep.join(add_to_path + std_places)
def cabal_config():
    cconfig = os.environ.get('CABAL_CONFIG') or \
        ('~/.cabal' if not Utils.is_windows() else r'%APPDATA%/cabal') + \
        "/config"

    # Various patterns to match...
    re_user_dirs = re.compile(r'^install-dirs\s+user')
    re_global_dirs = re.compile(r'^install-dirs\s+global')
    re_section = re.compile(r'^\w+')
    re_prefix = re.compile(r'prefix:\s+(.*)$')
    re_bindir = re.compile(r'bindir:\s+(.*)$')

    # Things to collect
    user_prefix = "$HOME/.cabal" if not Utils.is_windows() else r'%APPDATA%/cabal'
    # FIXME: Need to interrogate Shel32 for the Windows PROGRAMFILES known
    # folder path:
    global_prefix = "/usr/local" if not Utils.is_windows() else r'%PROGRAMFILES%/Haskell'
    user_bindir = "bin"
    global_bindir = "bin"
    p_state = 0

    try:
        with open(Utils.normalize_path(cconfig), 'rU') as f_cconfig:
            # You would think that the Cabal maintainers would use a
            # well known file format... But now, they didn't. And they
            # had to go with an indentation-specific format.
            #
            # This is a "cheap and dirty" scanner to pick up
            for line in f_cconfig:
                line = line.rstrip()
                # One of the sections?
                if re_user_dirs.match(line):
                    p_state = 1
                elif re_global_dirs.match(line):
                    p_state = 2
                elif re.match(r'^\s+\w', line):
                    # prefix attribute?
                    m_prefix = re_prefix.search(line)
                    if m_prefix:
                        if p_state == 1:
                            user_prefix = m_prefix.group(1)
                        elif p_state == 2:
                            global_prefix = m_prefix.group(1)
                    # bindir attribute?
                    m_bindir = re_bindir.search(line)
                    if m_bindir:
                        if p_state == 1:
                            user_bindir = m_bindir.group(1)
                        elif p_state == 2:
                            global_bindir = m_bindir.group(1)
                elif re_section.match(line):
                    p_state = 0

    except IOError:
        # Silently fail.
        pass

    return [os.path.join(user_prefix, user_bindir)
            , os.path.join(global_prefix, global_bindir)
           ]
示例#6
0
    def __init__(self,
                 backend_mgr,
                 local=True,
                 port=HSDEV_DEFAULT_PORT,
                 host=HSDEV_DEFAULT_HOST,
                 local_base_dir=None,
                 remote_base_dir=None,
                 **kwargs):
        super().__init__(backend_mgr)
        Logging.log(
            '{0}.__init__({1}, {2})'.format(type(self).__name__, host, port),
            Logging.LOG_INFO)

        # Sanity checking:
        exec_with = kwargs.get('exec-with')
        install_dir = kwargs.get('install-dir')
        if exec_with is not None and install_dir is None:
            sublime.error_message('\n'.join([
                '\'exec_with\' requires an \'install_dir\'.', '',
                'Please check your \'backends\' configuration and retry.'
            ]))
            raise RuntimeError('\'exec_with\' requires an \'install_dir\'.')
        elif exec_with is not None and exec_with not in ['stack', 'cabal']:
            sublime.error_message('\n'.join([
                'Invalid backend \'exec_with\': {0}'.format(exec_with), '',
                'Valid values are "cabal" or "stack".',
                'Please check your \'backends\' configuration and retry.'
            ]))
            raise RuntimeError(
                'Invalid backend \'exec_with\': {0}'.format(exec_with))

        # Local hsdev server process and params
        self.is_local_hsdev = local
        self.hsdev_process = None
        self.cache = os.path.join(Common.sublime_haskell_cache_path(), 'hsdev')
        self.log_file = os.path.join(Common.sublime_haskell_cache_path(),
                                     'hsdev', 'hsdev.log')
        self.exec_with = exec_with
        self.install_dir = Utils.normalize_path(
            install_dir) if install_dir is not None else None
        # Keep track of the hsdev version early. Needed to patch command line arguments later.
        self.version = HsDevBackend.hsdev_version(self.exec_with,
                                                  self.install_dir)

        self.drain_stdout = None
        self.drain_stderr = None
        # Connection params
        self.port = port
        self.hostname = host
        self.local_base_dir = local_base_dir
        self.remote_base_dir = remote_base_dir
        if self.is_local_hsdev:
            self.hostname = self.HSDEV_DEFAULT_HOST
        self.client = None
示例#7
0
 def remove_subdir_recursively(subdir):
     subdir = Utils.normalize_path(os.path.join(project_dir, subdir))
     if os.path.exists(subdir):
         if os.path.isdir(subdir):
             for dirpath, _dirnames, filenames in os.walk(subdir, topdown=False):
                 try:
                     for fname in filenames:
                         os.remove(os.path.join(dirpath, fname))
                     os.rmdir(dirpath)
                 except OSError as ex:
                     diag_feedback.append(str(ex))
                     print(ex)
         else:
             os.remove(subdir)
示例#8
0
 def remove_subdir_recursively(subdir):
     subdir = Utils.normalize_path(os.path.join(project_dir, subdir))
     if os.path.exists(subdir):
         if os.path.isdir(subdir):
             for dirpath, _dirnames, filenames in os.walk(subdir, topdown=False):
                 try:
                     for fname in filenames:
                         os.remove(os.path.join(dirpath, fname))
                     os.rmdir(dirpath)
                 except OSError as ex:
                     diag_feedback.append(str(ex))
                     print(ex)
         else:
             os.remove(subdir)
示例#9
0
    def __init__(self, backend_mgr, local=True, port=HSDEV_DEFAULT_PORT, host=HSDEV_DEFAULT_HOST, **kwargs):
        super().__init__(backend_mgr)
        Logging.log('{0}.__init__({1}, {2})'.format(type(self).__name__, host, port), Logging.LOG_INFO)

        # Sanity checking:
        exec_with = kwargs.get('exec-with')
        install_dir = kwargs.get('install-dir')
        if bool(exec_with) ^ bool(install_dir):
            if install_dir is None:
                sublime.error_message('\n'.join(['\'exec_with\' requires an \'install_dir\'.',
                                                 '',
                                                 'Please check your \'backends\' configuration and retry.']))
                raise RuntimeError('\'exec_with\' requires an \'install_dir\'.')
            else:
                sublime.error_message('\n'.join(['\'install_dir\' requires an \'exec_with\'.',
                                                 '',
                                                 'Please check your \'backends\' configuration and retry.']))
                raise RuntimeError('\'install_dir\' requires an \'exec_with\'.')
        elif exec_with and exec_with not in ['stack', 'cabal', 'cabal-new-build']:
            sublime.error_message('\n'.join(['Invalid backend \'exec_with\': {0}'.format(exec_with),
                                             '',
                                             'Valid values are "cabal", "cabal-new-build" or "stack".',
                                             'Please check your \'backends\' configuration and retry.']))
            raise RuntimeError('Invalid backend \'exec_with\': {0}'.format(exec_with))

        # Local hsdev server process and params
        self.is_local_hsdev = local
        self.hsdev_process = None
        self.cache = os.path.join(Common.sublime_haskell_cache_path(), 'hsdev')
        self.log_file = os.path.join(Common.sublime_haskell_cache_path(), 'hsdev', 'hsdev.log')
        self.exec_with = exec_with
        self.install_dir = Utils.normalize_path(install_dir) if install_dir is not None else None
        # Keep track of the hsdev version early. Needed to patch command line arguments later.
        self.version = HsDevBackend.hsdev_version(self.exec_with, self.install_dir)

        self.drain_stdout = None
        self.drain_stderr = None
        # Connection params
        self.port = port
        self.hostname = host
        if self.is_local_hsdev:
            self.hostname = self.HSDEV_DEFAULT_HOST
        self.client = None
        self.serial_lock = threading.RLock()
        self.request_serial = 1
    def make_augmented_path():
        ''' Generate the augmented PATH for subprocesses: adds the appropriate cabal/stack local install directory
        ($HOME/.local/bin for *nix, %APPDATA%/local/bin for Windows) and updates PATH with `add_to_PATH` extras.
        '''
        std_places = []
        if Settings.PLUGIN.add_standard_dirs:
            std_places.append("$HOME/.local/bin" if not Utils.is_windows() else "%APPDATA%/local/bin")
            if Utils.is_macosx():
                std_places.append('$HOME/Library/Haskell/bin')
            std_places += CabalConfigRdr.cabal_config()
            std_places = [dir for dir in [Utils.normalize_path(path) for path in std_places] if os.path.isdir(dir)]

        add_to_path = list(filter(os.path.isdir, map(Utils.normalize_path, Settings.PLUGIN.add_to_path)))

        Logging.log("std_places = {0}".format(std_places), Logging.LOG_INFO)
        Logging.log("add_to_PATH = {0}".format(add_to_path), Logging.LOG_INFO)

        return os.pathsep.join(add_to_path + std_places)
def exec_with_wrapper(exec_with, install_dir, cmd_list):
    '''Wrapper function for inserting the execution wrapper, e.g., 'cabal exec' or 'stack exec'

    :returns: Process object from ProcHelper.
    '''

    proc_args = {}
    if exec_with is not None:
        cmd_list = exec_wrapper_cmd(exec_with, cmd_list)
        if install_dir is not None:
            proc_args['cwd'] = Utils.normalize_path(install_dir)
        else:
            raise RuntimeError('ProcHelper.exec_with_wrapper: invalid install_dir (None)')
    else:
        cmd = Which.which(cmd_list[0], ProcHelper.get_extended_path())
        if cmd is not None:
            cmd_list[0] = cmd

    Logging.log('ProcHelper.exec_with_wrapper: {0} in {1}'.format(cmd_list, proc_args.get('cwd')), Logging.LOG_DEBUG)
    return ProcHelper(cmd_list, **proc_args)
示例#12
0
def exec_with_wrapper(exec_with, install_dir, cmd_list):
    '''Wrapper function for inserting the execution wrapper, e.g., 'cabal exec' or 'stack exec'

    :returns: Process object from ProcHelper.
    '''

    proc_args = {}
    if exec_with is not None:
        cmd_list = exec_wrapper_cmd(exec_with, cmd_list)
        if install_dir is not None:
            proc_args['cwd'] = Utils.normalize_path(install_dir)
    else:
        cmd = Which.which(cmd_list[0], ProcHelper.get_extended_path())
        if cmd is not None:
            cmd_list[0] = cmd

    Logging.log(
        'ProcHelper.exec_with_wrapper: {0} in {1}'.format(
            cmd_list, proc_args.get('cwd')), Logging.LOG_DEBUG)
    return ProcHelper(cmd_list, **proc_args)
示例#13
0
 def childof(path, prefix):
     return Utils.normalize_path(path).startswith(Utils.normalize_path(prefix))
示例#14
0
 def childof(path, prefix):
     return Utils.normalize_path(path).startswith(Utils.normalize_path(prefix))
def cabal_config():
    cconfig = os.environ.get('CABAL_CONFIG') or \
        ('~/.cabal' if not Utils.is_windows() else r'%APPDATA%/cabal') + \
        "/config"

    # Various patterns to match...
    re_user_dirs = re.compile(r'^install-dirs\s+user')
    re_global_dirs = re.compile(r'^install-dirs\s+global')
    re_section = re.compile(r'^\w+')
    re_prefix = re.compile(r'prefix:\s+(.*)$')
    re_bindir = re.compile(r'bindir:\s+(.*)$')

    # Things to collect
    user_prefix = "$HOME/.cabal" if not Utils.is_windows(
    ) else r'%APPDATA%/cabal'
    # FIXME: Need to interrogate Shel32 for the Windows PROGRAMFILES known
    # folder path:
    global_prefix = "/usr/local" if not Utils.is_windows(
    ) else r'%PROGRAMFILES%/Haskell'
    user_bindir = "bin"
    global_bindir = "bin"
    p_state = 0

    try:
        with open(Utils.normalize_path(cconfig), 'rU') as f_cconfig:
            # You would think that the Cabal maintainers would use a
            # well known file format... But now, they didn't. And they
            # had to go with an indentation-specific format.
            #
            # This is a "cheap and dirty" scanner to pick up
            for line in f_cconfig:
                line = line.rstrip()
                # One of the sections?
                if re_user_dirs.match(line):
                    p_state = 1
                elif re_global_dirs.match(line):
                    p_state = 2
                elif re.match(r'^\s+\w', line):
                    # prefix attribute?
                    m_prefix = re_prefix.search(line)
                    if m_prefix:
                        if p_state == 1:
                            user_prefix = m_prefix.group(1)
                        elif p_state == 2:
                            global_prefix = m_prefix.group(1)
                    # bindir attribute?
                    m_bindir = re_bindir.search(line)
                    if m_bindir:
                        if p_state == 1:
                            user_bindir = m_bindir.group(1)
                        elif p_state == 2:
                            global_bindir = m_bindir.group(1)
                elif re_section.match(line):
                    p_state = 0

    except IOError:
        # Silently fail.
        pass

    return [
        os.path.join(user_prefix, user_bindir),
        os.path.join(global_prefix, global_bindir)
    ]