Beispiel #1
0
    def __call__(dataset=None, sensitive=None, clipboard=None):
        from datalad.distribution.dataset import require_dataset
        from datalad.support.exceptions import NoDatasetArgumentFound
        from datalad.interface.results import get_status_dict

        ds = None
        try:
            ds = require_dataset(dataset, check_installed=False, purpose='reporting')
        except NoDatasetArgumentFound:
            # failure is already logged
            pass
        if ds and not ds.is_installed():
            # we don't deal with absent datasets
            ds = None
        if sensitive:
            if ds is None:
                from datalad import cfg
            else:
                cfg = ds.config
        else:
            cfg = None

        from datalad.ui import ui
        from datalad.support.external_versions import external_versions

        infos = {}
        res = get_status_dict(
            action='wtf',
            path=ds.path if ds else op.abspath(op.curdir),
            type='dataset' if ds else 'directory',
            status='ok',
            logger=lgr,
            infos=infos,
        )
        infos['datalad'] = _describe_datalad()
        infos['git-annex'] = _describe_annex()
        infos['system'] = _describe_system()
        infos['environment'] = _describe_environment()
        infos['configuration'] = _describe_configuration(cfg, sensitive)
        infos['extentions'] = _describe_extensions()
        infos['metadata_extractors'] = _describe_metadata_extractors()
        infos['dependencies'] = _describe_dependencies()
        if ds:
            try:
                infos['dataset'] = _describe_dataset(ds, sensitive)
            except InvalidGitRepositoryError as e:
                infos['dataset'] = {"invalid": exc_str(e)}

        if clipboard:
            external_versions.check(
                'pyperclip', msg="It is needed to be able to use clipboard")
            import pyperclip
            report = _render_report(res)
            pyperclip.copy(report)
            ui.message("WTF information of length %s copied to clipboard"
                       % len(report))
        yield res
        return
Beispiel #2
0
    def __call__(dataset=None, sensitive=None, clipboard=None):
        from datalad.distribution.dataset import require_dataset
        from datalad.support.exceptions import NoDatasetArgumentFound
        from datalad.interface.results import get_status_dict

        ds = None
        try:
            ds = require_dataset(dataset, check_installed=False, purpose='reporting')
        except NoDatasetArgumentFound:
            # failure is already logged
            pass
        if ds and not ds.is_installed():
            # we don't deal with absent datasets
            ds = None
        if sensitive:
            if ds is None:
                from datalad import cfg
            else:
                cfg = ds.config
        else:
            cfg = None

        from datalad.ui import ui
        from datalad.support.external_versions import external_versions

        infos = {}
        res = get_status_dict(
            action='wtf',
            path=ds.path if ds else op.abspath(op.curdir),
            type='dataset' if ds else 'directory',
            status='ok',
            logger=lgr,
            infos=infos,
        )
        infos['datalad'] = _describe_datalad()
        infos['git-annex'] = _describe_annex()
        infos['system'] = _describe_system()
        infos['environment'] = _describe_environment()
        infos['configuration'] = _describe_configuration(cfg, sensitive)
        infos['extentions'] = _describe_extensions()
        infos['metadata_extractors'] = _describe_metadata_extractors()
        infos['dependencies'] = _describe_dependencies()
        if ds:
            infos['dataset'] = _describe_dataset(ds, sensitive)

        if clipboard:
            external_versions.check(
                'pyperclip', msg="It is needed to be able to use clipboard")
            import pyperclip
            report = _render_report(res)
            pyperclip.copy(report)
            ui.message("WTF information of length %s copied to clipboard"
                       % len(report))
        yield res
        return
Beispiel #3
0
    def __call__(dataset=None,
                 sensitive=None,
                 sections=None,
                 flavor="full",
                 decor=None,
                 clipboard=None):
        from datalad.distribution.dataset import require_dataset
        from datalad.support.exceptions import NoDatasetFound
        from datalad.interface.results import get_status_dict

        ds = None
        try:
            ds = require_dataset(dataset,
                                 check_installed=False,
                                 purpose='reporting')
        except NoDatasetFound:
            # failure is already logged
            pass
        if ds and not ds.is_installed():
            # warn that the dataset is bogus
            yield dict(
                action='wtf',
                path=ds.path,
                status='impossible',
                message=('No dataset found at %s. Reporting on the dataset is '
                         'not attempted.', ds.path),
                logger=lgr)
            # we don't deal with absent datasets
            ds = None
        if sensitive:
            if ds is None:
                from datalad import cfg
            else:
                cfg = ds.config
        else:
            cfg = None

        from datalad.ui import ui
        from datalad.support.external_versions import external_versions

        infos = OrderedDict()
        res = get_status_dict(
            action='wtf',
            path=ds.path if ds else ensure_unicode(op.abspath(op.curdir)),
            type='dataset' if ds else 'directory',
            status='ok',
            logger=lgr,
            decor=decor,
            infos=infos,
            flavor=flavor,
        )

        # Define section callables which require variables.
        # so there is no side-effect on module level original
        section_callables = SECTION_CALLABLES.copy()
        section_callables['location'] = partial(_describe_location, res)
        section_callables['configuration'] = \
            partial(_describe_configuration, cfg, sensitive)
        if ds:
            section_callables['dataset'] = \
                partial(_describe_dataset, ds, sensitive)
        else:
            section_callables.pop('dataset')
        assert all(section_callables.values())  # check if none was missed

        asked_for_all_sections = sections is not None and any(
            s == '*' for s in sections)
        if sections is None or asked_for_all_sections:
            if flavor == 'full' or asked_for_all_sections:
                sections = sorted(list(section_callables))
            elif flavor == 'short':
                sections = ['datalad', 'dependencies']
            else:
                raise ValueError(flavor)

        for s in sections:
            infos[s] = section_callables[s]()

        if clipboard:
            external_versions.check(
                'pyperclip', msg="It is needed to be able to use clipboard")
            import pyperclip
            report = _render_report(res)
            pyperclip.copy(report)
            ui.message("WTF information of length %s copied to clipboard" %
                       len(report))
        yield res
        return
Beispiel #4
0
    def __call__(dataset=None,
                 sensitive=None,
                 sections=None,
                 decor=None,
                 clipboard=None):
        from datalad.distribution.dataset import require_dataset
        from datalad.support.exceptions import NoDatasetArgumentFound
        from datalad.interface.results import get_status_dict

        ds = None
        try:
            ds = require_dataset(dataset,
                                 check_installed=False,
                                 purpose='reporting')
        except NoDatasetArgumentFound:
            # failure is already logged
            pass
        if ds and not ds.is_installed():
            # we don't deal with absent datasets
            ds = None
        if sensitive:
            if ds is None:
                from datalad import cfg
            else:
                cfg = ds.config
        else:
            cfg = None

        from datalad.ui import ui
        from datalad.support.external_versions import external_versions

        infos = OrderedDict()
        res = get_status_dict(
            action='wtf',
            path=ds.path if ds else op.abspath(op.curdir),
            type='dataset' if ds else 'directory',
            status='ok',
            logger=lgr,
            decor=decor,
            infos=infos,
        )

        # Define section callables which require variables.
        # so there is no side-effect on module level original
        section_callables = SECTION_CALLABLES.copy()
        section_callables['location'] = partial(_describe_location, res)
        section_callables['configuration'] = \
            partial(_describe_configuration, cfg, sensitive)
        if ds:
            section_callables['dataset'] = \
                partial(_describe_dataset, ds, sensitive)
        else:
            section_callables.pop('dataset')
        assert all(section_callables.values())  # check if none was missed

        if sections is None:
            sections = sorted(list(section_callables))

        for s in sections:
            infos[s] = section_callables[s]()

        if clipboard:
            external_versions.check(
                'pyperclip', msg="It is needed to be able to use clipboard")
            import pyperclip
            report = _render_report(res)
            pyperclip.copy(assure_bytes(report))
            ui.message("WTF information of length %s copied to clipboard" %
                       len(report))
        yield res
        return
Beispiel #5
0
    def __call__(dataset=None, sensitive=None, clipboard=None):
        from datalad import get_encoding_info
        from datalad import get_envvars_info

        from datalad.distribution.dataset import require_dataset
        from datalad.support.exceptions import NoDatasetArgumentFound
        ds = None
        try:
            ds = require_dataset(dataset, check_installed=False, purpose='reporting')
        except NoDatasetArgumentFound:
            # failure is already logged
            pass
        if ds and not ds.is_installed():
            # we don't deal with absent datasets
            ds = None
        if sensitive:
            if ds is None:
                from datalad import cfg
            else:
                cfg = ds.config
        else:
            cfg = None

        from pkg_resources import iter_entry_points
        from datalad.ui import ui
        from datalad.api import metadata
        from datalad.support.external_versions import external_versions
        from datalad.dochelpers import exc_str
        from datalad.interface.results import success_status_map
        import os
        import platform as pl
        import json

        extractors={}
        for ep in iter_entry_points('datalad.metadata.extractors'):
            try:
                ep.load()
                status = 'OK'
            except Exception as e:
                status = 'BROKEN ({})'.format(exc_str(e))
            extractors[ep.name] = status

        # formatting helper
        def _t2s(t):
            res = []
            for e in t:
                if isinstance(e, tuple):
                    es = _t2s(e)
                    if es != '':
                        res += ['(%s)' % es]
                elif e != '':
                    res += [e]
            return '/'.join(res)


        report_template = """\
DataLad
=======
{datalad}

System
======
{system}

Locale/Encoding
===============
{loc}

Environment
===========
{env}

Externals
=========
{externals}
Installed extensions
====================
{extensions}

Known metadata extractors
=========================
{metaextractors}

Configuration
=============
{cfg}
{dataset}
"""

        dataset_template = """\

Dataset information
===================
{basic}

Metadata
--------
{meta}
"""
        ds_meta = None
        if not sensitive:
            ds_meta = _HIDDEN
        elif ds and ds.is_installed() and ds.id:
            ds_meta = metadata(
                dataset=ds, reporton='datasets', return_type='list',
                result_filter=lambda x: x['action'] == 'metadata' and success_status_map[x['status']] == 'success',
                result_renderer='disabled', on_failure='ignore')
            if ds_meta:
                ds_meta = [dm['metadata'] for dm in ds_meta]
                if len(ds_meta) == 1:
                    ds_meta = ds_meta.pop()

        if cfg is not None:
            # make it into a dict to be able to reassign
            cfg = dict(cfg.items())

        if sensitive != 'all' and cfg:
            # filter out some of the entries which known to be highly sensitive
            for k in cfg.keys():
                if 'user' in k or 'token' in k or 'passwd' in k:
                    cfg[k] = _HIDDEN

        from datalad.version import __version__, __full_version__
        text = report_template.format(
            datalad=_format_dict([
                ('Version', __version__),
                ('Full version', __full_version__)
            ], indent=True),
            system=_format_dict([
                ('OS', ' '.join([
                    os.name,
                    pl.system(),
                    pl.release(),
                    pl.version()]).rstrip()),
                ('Distribution',
                 ' '.join([_t2s(pl.dist()),
                           _t2s(pl.mac_ver()),
                           _t2s(pl.win32_ver())]).rstrip())
            ], indent=True),
            loc=_format_dict(get_encoding_info(), indent=True),  # , fmt="{}={!r}"),
            env=_format_dict(get_envvars_info(), fmt="{}={!r}"),
            dataset='' if not ds else dataset_template.format(
                basic=_format_dict([
                    ('path', ds.path),
                    ('repo', ds.repo.__class__.__name__ if ds.repo else '[NONE]'),
                ]),
                meta=_HIDDEN if not sensitive
                     else json.dumps(ds_meta, indent=1)
                     if ds_meta else '[no metadata]'
            ),
            externals=external_versions.dumps(preamble=None, indent='', query=True),
            extensions='\n'.join(ep.name for ep in iter_entry_points('datalad.extensions')),
            metaextractors=_format_dict(extractors),
            cfg=_format_dict(sorted(cfg.items(), key=lambda x: x[0]))
                if cfg else _HIDDEN,
        )
        if clipboard:
            from datalad.support.external_versions import external_versions
            external_versions.check(
                'pyperclip', msg="It is needed to be able to use clipboard")
            import pyperclip
            pyperclip.copy(text)
            ui.message("WTF information of length %s copied to clipboard"
                       % len(text))
        else:
            ui.message(text)
        yield
Beispiel #6
0
    def __call__(dataset=None, sensitive=None, sections=None, decor=None, clipboard=None):
        from datalad.distribution.dataset import require_dataset
        from datalad.support.exceptions import NoDatasetArgumentFound
        from datalad.interface.results import get_status_dict

        ds = None
        try:
            ds = require_dataset(dataset, check_installed=False, purpose='reporting')
        except NoDatasetArgumentFound:
            # failure is already logged
            pass
        if ds and not ds.is_installed():
            # we don't deal with absent datasets
            ds = None
        if sensitive:
            if ds is None:
                from datalad import cfg
            else:
                cfg = ds.config
        else:
            cfg = None

        from datalad.ui import ui
        from datalad.support.external_versions import external_versions

        infos = OrderedDict()
        res = get_status_dict(
            action='wtf',
            path=ds.path if ds else op.abspath(op.curdir),
            type='dataset' if ds else 'directory',
            status='ok',
            logger=lgr,
            decor=decor,
            infos=infos,
        )

        # Define section callables which require variables.
        # so there is no side-effect on module level original
        section_callables = SECTION_CALLABLES.copy()
        section_callables['location'] = partial(_describe_location, res)
        section_callables['configuration'] = \
            partial(_describe_configuration, cfg, sensitive)
        if ds:
            section_callables['dataset'] = \
                partial(_describe_dataset, ds, sensitive)
        else:
            section_callables.pop('dataset')
        assert all(section_callables.values())  # check if none was missed

        if sections is None:
            sections = sorted(list(section_callables))

        for s in sections:
            infos[s] = section_callables[s]()

        if clipboard:
            external_versions.check(
                'pyperclip', msg="It is needed to be able to use clipboard")
            import pyperclip
            report = _render_report(res)
            pyperclip.copy(assure_bytes(report))
            ui.message("WTF information of length %s copied to clipboard"
                       % len(report))
        yield res
        return
Beispiel #7
0
# emacs: -*- mode: python; py-indent-offset: 4; tab-width: 4; indent-tabs-mode: nil -*-
# ex: set sts=4 ts=4 sw=4 noet:
# ## ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##
#
#   See COPYING file distributed along with the datalad package for the
#   copyright and license terms.
#
# ## ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ##
"""7-zip based implementation for datalad.support.archives utilities"""

from datalad.support.external_versions import external_versions
external_versions.check(
    "cmd:7z",
    msg=
    'The 7z binary (7-Zip) is required for archive handling, but is missing. '
    "Setting the config flag 'datalad.runtime.use-patool' enables an "
    "alternative implementation that may not need 7z.")

from datalad.utils import (
    Path,
    join_cmdline,
    quote_cmdlinearg,
)

import logging
lgr = logging.getLogger('datalad.support.archive_utils_7z')

from datalad.cmd import (
    WitlessRunner as Runner,
    KillOutput,
)