<commit_before>#
# Copyright (c) SAS Institute Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import itertools
import logging
import multiprocessing
import optparse
import pprint
import os
import sys
import tempfile
from bob import config
from bob import main as bobmain
from conary.build import groupsetrecipe
from conary.lib import log as cny_log
from conary.lib import util

log = logging.getLogger('showdeps')


def analyze_plan(root, pluginMgr, recipeDir, relpath):
    cfg = config.BobConfig()
    path = os.path.join(root, relpath)
    cfg.read(path)
    cfg.recipeDir = recipeDir

    # Provide each source that this plan would build
    label = cfg.getTargetLabel()
    provides = {}
    for target in cfg.target:
        provide = '%s=%s' % (target, label)
        provides.setdefault(provide, set()).add(relpath)

    # Require anything mentioned in a resolveTrove
    requires = {}
    for bucket in cfg.resolveTroves:
        for item in bucket:
            item %= cfg.getMacros()
            requires.setdefault(item, set()).add(relpath)

    # Analyze recipe for provides, and in the case of groups, requires
    log.info("Loading recipes for plan %s", relpath)
    bob = bobmain.BobMain(pluginMgr)
    bob.setPlan(cfg)
    targets, batch = bob.runDeps()
    for package, (_, recipeObj) in zip(batch.packages, batch.recipes):
        if package.name.startswith('group-'):
            if hasattr(recipeObj, 'g'):
                group_req, group_prov = analyze_groupset(recipeObj)
            else:
                group_req, group_prov = analyze_group(recipeObj)
            for require in group_req:
                requires.setdefault(require, set()).add(relpath)
            for name in group_prov:
                provide = '%s=%s' % (name, label)
                provides.setdefault(provide, set()).add(relpath)

        elif hasattr(recipeObj, 'packages'):
            for name in recipeObj.packages:
                provide = '%s=%s' % (name, label)
                provides.setdefault(provide, set()).add(relpath)

    return requires, provides


def analyze_group(recipeObj):
    if not hasattr(recipeObj, 'getAdditionalSearchPath'):
        log.warning("Recipe for %s does not have a "
                "getAdditionalSearchPath method; cannot analyze "
                "requirements.", recipeObj.name)
        return [], []
    path = recipeObj.getAdditionalSearchPath()
    if not path:
        log.warning("Recipe for %s does not have a "
                "getAdditionalSearchPath method; cannot analyze "
                "requirements.", recipeObj.name)
        return [], []
    requires = []
    for item in itertools.chain(*path):
        item = item.split('[')[0]
        requires.append(item)
    provides = []
    for name in recipeObj.groups:
        provides.append(name)
    return requires, provides


def analyze_groupset(recipeObj):
    g = recipeObj.g
    requires = []
    for source in g.getRoots():
        if isinstance(source, groupsetrecipe.GroupSearchSourceTroveSet):
            label = source.searchSource.installLabelPath[0]
            for child in g.getChildren(source):
                if isinstance(child, groupsetrecipe.GroupSearchPathTroveSet):
                    log.warning("Bare label %s is used as a search path. "
                            "Troves found there will not be marked as "
                            "requirements.", label)
                    continue
                if not hasattr(child, 'action'):
                    log.warning("Don't know how to handle node of type '%s'",
                            type(child).__name__)
                    continue
                if isinstance(child.action, groupsetrecipe.GroupFindAction):
                    names = child.action.troveSpecs
                else:
                    log.warning("Don't know how to handle action of type '%s'",
                            type(child.action).__name__)
                    continue
                for name in names:
                    name = name.split('[')[0]
                    if '=' not in name:
                        name = '%s=%s' % (name, label)
                    requires.append(name)
        else:
            log.warning("Don't know how to handle source of type '%s'",
                    type(source).__name__)
    provides = []
    for node in g.iterNodes():
        if isinstance(getattr(node, 'action', None),
                groupsetrecipe.CreateGroupAction):
            provides.append(node.action.name)
    return requires, provides


def dump_recipes((root, pluginMgr, recipeDir, relpath)):
    try:
        log.info("Dumping recipes for %s", relpath)
        cfg = config.BobConfig()
        path = os.path.join(root, relpath)
        cfg.read(path)
        cfg.dumpRecipes = True
        cfg.recipeDir = recipeDir
        bob = bobmain.BobMain(pluginMgr)
        bob.setPlan(cfg)
        bob.runDeps()
        return True
    except:
        log.exception("Error parsing file %s:", relpath)
        return False


def _analyze_plan((root, pluginMgr, recipeDir, relpath)):
    try:
        return analyze_plan(root, pluginMgr, recipeDir, relpath)
    except:
        log.exception("Error parsing file %s:", relpath)
        return None<commit_msg>showdeps: use config.openPlan so creds get picked up correctly<commit_after>#
# Copyright (c) SAS Institute Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import itertools
import logging
import multiprocessing
import optparse
import pprint
import os
import sys
import tempfile
from bob import config
from bob import main as bobmain
from conary.build import groupsetrecipe
from conary.lib import log as cny_log
from conary.lib import util

log = logging.getLogger('showdeps')


def analyze_plan(root, pluginMgr, recipeDir, relpath):
    cfg = config.openPlan(os.path.join(root, relpath))
    cfg.recipeDir = recipeDir

    # Provide each source that this plan would build
    label = cfg.getTargetLabel()
    provides = {}
    for target in cfg.target:
        provide = '%s=%s' % (target, label)
        provides.setdefault(provide, set()).add(relpath)

    # Require anything mentioned in a resolveTrove
    requires = {}
    for bucket in cfg.resolveTroves:
        for item in bucket:
            item %= cfg.getMacros()
            requires.setdefault(item, set()).add(relpath)

    # Analyze recipe for provides, and in the case of groups, requires
    log.info("Loading recipes for plan %s", relpath)
    bob = bobmain.BobMain(pluginMgr)
    bob.setPlan(cfg)
    targets, batch = bob.runDeps()
    for package, (_, recipeObj) in zip(batch.packages, batch.recipes):
        if package.name.startswith('group-'):
            if hasattr(recipeObj, 'g'):
                group_req, group_prov = analyze_groupset(recipeObj)
            else:
                group_req, group_prov = analyze_group(recipeObj)
            for require in group_req:
                requires.setdefault(require, set()).add(relpath)
            for name in group_prov:
                provide = '%s=%s' % (name, label)
                provides.setdefault(provide, set()).add(relpath)

        elif hasattr(recipeObj, 'packages'):
            for name in recipeObj.packages:
                provide = '%s=%s' % (name, label)
                provides.setdefault(provide, set()).add(relpath)

    return requires, provides


def analyze_group(recipeObj):
    if not hasattr(recipeObj, 'getAdditionalSearchPath'):
        log.warning("Recipe for %s does not have a "
                "getAdditionalSearchPath method; cannot analyze "
                "requirements.", recipeObj.name)
        return [], []
    path = recipeObj.getAdditionalSearchPath()
    if not path:
        log.warning("Recipe for %s does not have a "
                "getAdditionalSearchPath method; cannot analyze "
                "requirements.", recipeObj.name)
        return [], []
    requires = []
    for item in itertools.chain(*path):
        item = item.split('[')[0]
        requires.append(item)
    provides = []
    for name in recipeObj.groups:
        provides.append(name)
    return requires, provides


def analyze_groupset(recipeObj):
    g = recipeObj.g
    requires = []
    for source in g.getRoots():
        if isinstance(source, groupsetrecipe.GroupSearchSourceTroveSet):
            label = source.searchSource.installLabelPath[0]
            for child in g.getChildren(source):
                if isinstance(child, groupsetrecipe.GroupSearchPathTroveSet):
                    log.warning("Bare label %s is used as a search path. "
                            "Troves found there will not be marked as "
                            "requirements.", label)
                    continue
                if not hasattr(child, 'action'):
                    log.warning("Don't know how to handle node of type '%s'",
                            type(child).__name__)
                    continue
                if isinstance(child.action, groupsetrecipe.GroupFindAction):
                    names = child.action.troveSpecs
                else:
                    log.warning("Don't know how to handle action of type '%s'",
                            type(child.action).__name__)
                    continue
                for name in names:
                    name = name.split('[')[0]
                    if '=' not in name:
                        name = '%s=%s' % (name, label)
                    requires.append(name)
        else:
            log.warning("Don't know how to handle source of type '%s'",
                    type(source).__name__)
    provides = []
    for node in g.iterNodes():
        if isinstance(getattr(node, 'action', None),
                groupsetrecipe.CreateGroupAction):
            provides.append(node.action.name)
    return requires, provides


def dump_recipes((root, pluginMgr, recipeDir, relpath)):
    try:
        log.info("Dumping recipes for %s", relpath)
        cfg = config.openPlan(os.path.join(root, relpath))
        cfg.dumpRecipes = True
        cfg.recipeDir = recipeDir
        bob = bobmain.BobMain(pluginMgr)
        bob.setPlan(cfg)
        bob.runDeps()
        return True
    except:
        log.exception("Error parsing file %s:", relpath)
        return False


def _analyze_plan((root, pluginMgr, recipeDir, relpath)):
    try:
        return analyze_plan(root, pluginMgr, recipeDir, relpath)
    except:
        log.exception("Error parsing file %s:", relpath)
        return None
{'fraction_non_alphanumeric': 0.09460754421116822, 'fraction_numerical': 0.0012196184336614687, 'mean_word_length': 2.1977715877437327, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1495046', 'n_tokens_mistral': 3164, 'n_tokens_neox': 3079, 'n_words': 955}