Node attributes get deep-merged with the environment ones
 Node run_list overrides the environment one
 Environment before hooks override global ones
15546
def build_node(node_name, env_hash, node_hash)
      node_config = {
        'server'     => node_hash.slice('host', 'port', 'user', 'password', 'platform', 'vagrant'),
        'attributes' => (node_hash['attributes'] || {}).deep_merge(env_hash['attributes'] || {}),
        'run_list'   => node_hash['run_list']   || env_hash['run_list'],
        'before'     => env_hash['before']      || @config['before'],
        'after'      => env_hash['after']       || @config['after']
      }
      node_config['server'].delete 'attributes'
      Gusteau::Node.new(node_name, node_config)
    end
680609
def _node_errors(builder, env, tlist, slist):
    

    # First, figure out if there are any errors in the way the targets
    # were specified.
    for t in tlist:
        if t.side_effect:
            raise UserError("Multiple ways to build the same target were specified for: %s" % t)
        if t.has_explicit_builder():
            # Check for errors when the environments are different
            # No error if environments are the same Environment instance
            if (not t.env is None and not t.env is env and
                    # Check OverrideEnvironment case - no error if wrapped Environments
                    # are the same instance, and overrides lists match
                    not (getattr(t.env, '__subject', 0) is getattr(env, '__subject', 1) and
                         getattr(t.env, 'overrides', 0) == getattr(env, 'overrides', 1) and
                         not builder.multi)):
                action = t.builder.action
                t_contents = t.builder.action.get_contents(tlist, slist, t.env)
                contents = builder.action.get_contents(tlist, slist, env)

                if t_contents == contents:
                    msg = "Two different environments were specified for target %s,\n\tbut they appear to have the same action: %s" % (t, action.genstring(tlist, slist, t.env))
                    SCons.Warnings.warn(SCons.Warnings.DuplicateEnvironmentWarning, msg)
                else:
                    try:
                        msg = "Two environments with different actions were specified for the same target: %s\n(action 1: %s)\n(action 2: %s)" % (t,t_contents.decode('utf-8'),contents.decode('utf-8'))
                    except UnicodeDecodeError as e:
                        msg = "Two environments with different actions were specified for the same target: %s"%t
                    raise UserError(msg)
            if builder.multi:
                if t.builder != builder:
                    msg = "Two different builders (%s and %s) were specified for the same target: %s" % (t.builder.get_name(env), builder.get_name(env), t)
                    raise UserError(msg)
                # TODO(batch):  list constructed each time!
                if t.get_executor().get_all_targets() != tlist:
                    msg = "Two different target lists have a target in common: %s  (from %s and from %s)" % (t, list(map(str, t.get_executor().get_all_targets())), list(map(str, tlist)))
                    raise UserError(msg)
            elif t.sources != slist:
                msg = "Multiple ways to build the same target were specified for: %s  (from %s and from %s)" % (t, list(map(str, t.sources)), list(map(str, slist)))
                raise UserError(msg)

    if builder.single_source:
        if len(slist) > 1:
            raise UserError("More than one source given for single-source builder: targets=%s sources=%s" % (list(map(str,tlist)), list(map(str,slist))))
916585
def node_branch(self, al_keys, al_values):
            
            if len(al_keys) != len(al_values):
                self.error_exit("adding branch nodes", "#keys != #values", 1)
            ldict = dict(zip(al_keys, al_values))
            self.node_dictBranch(ldict)
651921
def replace_nodes(root, old, new):

    '''
     
    '''

    rep = Replacer(old, new)
    rep.visit(root)
    return
505165
function mergeConf(env, conf, key, ENV, fn) {
  fetch(conf, key, function(err, layout) {
    if (err) return fn(err);

    fetch(layout, 'default', function(err, defaults) {
      if (err) return fn(err);

      debug('  default', defaults);
      merge(ENV, defaults);
      debug('    ', ENV);

      fetch(layout, env, function(err, envs) {
        if (err) return fn(err);

        debug('  ' + env, envs);
        merge(ENV, envs);
        debug('    ', ENV);

        fn();
      });
    });
  });
}
513714
function evaluateNthRootForChildren(node) {
  const newNode = clone(node);

  const substeps = [];
  for (let i = 0; i < newNode.args.length; i++) {
    const child = newNode.args[i];
    const childNodeStatus = nthRoot(child);
    if (childNodeStatus.hasChanged()) {
      newNode.args[i] = childNodeStatus.newNode;
      substeps.push(Node.Status.childChanged(newNode, childNodeStatus, i));
    }
  }

  if (substeps.length === 0) {
    return Node.Status.noChange(node);
  }
  else if (substeps.length === 1) {
    return substeps[0];
  }
  else {
    return Node.Status.nodeChanged(
      ChangeTypes.EVALUATE_DISTRIBUTED_NTH_ROOT, node, newNode, true, substeps);
  }
}
720063
function mergeSubResource(attrNode, subResourceConfig, context) {
    // Merge options from sub-resource to parent (order is irrelevant here):
    Object.keys(subResourceConfig).forEach(optionName => {
        if (optionName === 'attributes') {
            if (!attrNode.attributes) attrNode.attributes = {};
        } else if (optionName === 'dataSources') {
            const newDataSources = Object.assign({}, subResourceConfig.dataSources);

            if (attrNode.dataSources) {
                Object.keys(attrNode.dataSources).forEach(dataSourceName => {
                    if (newDataSources[dataSourceName]) {
                        if (attrNode.dataSources[dataSourceName].inherit) {
                            if (attrNode.dataSources[dataSourceName].inherit === 'inherit') {
                                newDataSources[dataSourceName] = Object.assign(
                                    {},
                                    newDataSources[dataSourceName],
                                    attrNode.dataSources[dataSourceName]
                                );
                            } else if (attrNode.dataSources[dataSourceName].inherit === 'replace') {
                                newDataSources[dataSourceName] = attrNode.dataSources[dataSourceName];
                            }
                        } else {
                            throw new ImplementationError(
                                `Cannot overwrite DataSource "${dataSourceName}"` +
                                    ` in "${context.attrPath.join('.')}" (maybe use "inherit"?)`
                            );
                        }
                    } else {
                        newDataSources[dataSourceName] = attrNode.dataSources[dataSourceName];
                    }
                });
            }

            attrNode.dataSources = newDataSources;
        } else if (typeof subResourceConfig[optionName] === 'object') {
            attrNode[optionName] = cloneDeep(subResourceConfig[optionName]);
        } else if (!(optionName in attrNode)) {
            attrNode[optionName] = subResourceConfig[optionName];
        }
    });

    attrNode._origNodes = attrNode._origNodes || [];
    attrNode._origNodes.push(subResourceConfig);
}
200011
def process_needlist(app, doctree, fromdocname):
    
    env = app.builder.env

    for node in doctree.traverse(Needlist):
        if not app.config.needs_include_needs:
            # Ok, this is really dirty.
            # If we replace a node, docutils checks, if it will not lose any attributes.
            # But this is here the case, because we are using the attribute "ids" of a node.
            # However, I do not understand, why losing an attribute is such a big deal, so we delete everything
            # before docutils claims about it.
            for att in ('ids', 'names', 'classes', 'dupnames'):
                node[att] = []
            node.replace_self([])
            continue

        id = node.attributes["ids"][0]
        current_needfilter = env.need_all_needlists[id]
        all_needs = env.needs_all_needs
        content = []
        all_needs = list(all_needs.values())

        if current_needfilter["sort_by"] is not None:
            if current_needfilter["sort_by"] == "id":
                all_needs = sorted(all_needs, key=lambda node: node["id"])
            elif current_needfilter["sort_by"] == "status":
                all_needs = sorted(all_needs, key=status_sorter)

        found_needs = procces_filters(all_needs, current_needfilter)

        line_block = nodes.line_block()
        for need_info in found_needs:
            para = nodes.line()
            description = "%s: %s" % (need_info["id"], need_info["title"])

            if current_needfilter["show_status"] and need_info["status"] is not None:
                description += " (%s)" % need_info["status"]

            if current_needfilter["show_tags"] and need_info["tags"] is not None:
                description += " [%s]" % "; ".join(need_info["tags"])

            title = nodes.Text(description, description)

            # Create a reference
            if not need_info["hide"]:
                ref = nodes.reference('', '')
                ref['refdocname'] = need_info['docname']
                ref['refuri'] = app.builder.get_relative_uri(
                    fromdocname, need_info['docname'])
                ref['refuri'] += '#' + need_info['target_node']['refid']
                ref.append(title)
                para += ref
            else:
                para += title
            line_block.append(para)
        content.append(line_block)

        if len(content) == 0:
            content.append(no_needs_found_paragraph())

        if current_needfilter["show_filters"]:
            content.append(used_filter_paragraph(current_needfilter))

        node.replace_self(content)
466248
def substitute_vars(oldList, runSet=None, sourcefile=None):
    
    keyValueList = []
    if runSet:
        benchmark = runSet.benchmark

        # list with tuples (key, value): 'key' is replaced by 'value'
        keyValueList = [
            ('benchmark_name',     benchmark.name),
            ('benchmark_date',     benchmark.instance),
            ('benchmark_path',     benchmark.base_dir or '.'),
            ('benchmark_path_abs', os.path.abspath(benchmark.base_dir)),
            ('benchmark_file',     os.path.basename(benchmark.benchmark_file)),
            ('benchmark_file_abs', os.path.abspath(os.path.basename(benchmark.benchmark_file))),
            ('logfile_path',       os.path.dirname(runSet.log_folder) or '.'),
            ('logfile_path_abs',   os.path.abspath(runSet.log_folder)),
            ('rundefinition_name', runSet.real_name if runSet.real_name else ''),
            ('test_name',          runSet.real_name if runSet.real_name else ''),
        ]

    if sourcefile:
        keyValueList.append(('inputfile_name', os.path.basename(sourcefile)))
        keyValueList.append(('inputfile_path', os.path.dirname(sourcefile) or '.'))
        keyValueList.append(('inputfile_path_abs', os.path.dirname(os.path.abspath(sourcefile))))
        # The following are deprecated: do not use anymore.
        keyValueList.append(('sourcefile_name', os.path.basename(sourcefile)))
        keyValueList.append(('sourcefile_path', os.path.dirname(sourcefile) or '.'))
        keyValueList.append(('sourcefile_path_abs', os.path.dirname(os.path.abspath(sourcefile))))
    if sourcefile and sourcefile.endswith(".yml"):
        keyValueList.append(('taskdef_name', os.path.basename(sourcefile)))
        keyValueList.append(('taskdef_path', os.path.dirname(sourcefile) or '.'))
        keyValueList.append(('taskdef_path_abs', os.path.dirname(os.path.abspath(sourcefile))))

    # do not use keys twice
    assert len(set((key for (key, value) in keyValueList))) == len(keyValueList)

    return [util.substitute_vars(s, keyValueList) for s in oldList]
77231
def list_env(saltenv='base'):
    '''
    
    '''
    ret = {}
    if saltenv not in __opts__['pillar_roots']:
        return ret
    for f_root in __opts__['pillar_roots'][saltenv]:
        ret[f_root] = {}
        for root, dirs, files in salt.utils.path.os_walk(f_root):
            sub = ret[f_root]
            if root != f_root:
                # grab subroot ref
                sroot = root
                above = []
                # Populate the above dict
                while not os.path.samefile(sroot, f_root):
                    base = os.path.basename(sroot)
                    if base:
                        above.insert(0, base)
                    sroot = os.path.dirname(sroot)
                for aroot in above:
                    sub = sub[aroot]
            for dir_ in dirs:
                sub[dir_] = {}
            for fn_ in files:
                sub[fn_] = 'f'
    return ret
411843
def enumerate_scope(ast_rootpath, root_env=None, include_default_builtins=False):
  
  with util.LogTime('enumerate_scope'):
    scope = {}
    for node in reversed(ast_rootpath):
      if is_tuple_node(node):
        for member in node.members:
          if member.name not in scope:
            scope[member.name] = Completion(member.name, False, member.comment.as_string(), member.location)

    if include_default_builtins:  # Backwards compat flag
      root_env = gcl.default_env

    if root_env:
      for k in root_env.keys():
        if k not in scope and not hide_from_autocomplete(root_env[k]):
          v = root_env[k]
          scope[k] = Completion(k, True, dedent(v.__doc__ or ''), None)

    return scope
944837
def post_exec_hook(hook):
    
    #post_setupnode hook
    module_name = '.'.join([env.project_package_name,'deploy'])
    funcs_run = []
    try:
        imported = import_module(module_name)
        func = vars(imported).get(hook)
        if func:
            func()
            funcs_run.append(func)
    except ImportError:
        return

   #run per app
    for app in env.INSTALLED_APPS:
        if app == 'woven': continue
        module_name = '.'.join([app,'deploy'])
        try:
            imported = import_module(module_name)
            func = vars(imported).get(hook)
            if func and func not in funcs_run:
                func()
                funcs_run.append(func)
        except ImportError:
            pass
    import woven.deploy
    func = vars(woven.deploy).get(hook)
    if func and func not in funcs_run: func()
192303
def tagAttributes_while(fdef_master_list,root):
    ''' '''
    depth = 0
    current = root
    untagged_nodes = [root]
    while untagged_nodes:
        current = untagged_nodes.pop()
        for x in fdef_master_list:
            if jsName(x.path,x.name) == current['name']:
                current['path'] = x.path
        if children in current:
            for child in children:
                child["depth"] = depth
                untagged_nodes.append(child)
        if depth not in current:
            current["depth"] = depth
            depth += 1
    return root
193058
def dump_tree(node, name=None, initial_indent='', indentation='    ',
              maxline=120, maxmerged=80,
              # Runtime optimization
              iter_node=iter_node, special=ast.AST,
              list=list, isinstance=isinstance, type=type, len=len):
    
    def dump(node, name=None, indent=''):
        level = indent + indentation
        name = name and name + '=' or ''
        values = list(iter_node(node))
        if isinstance(node, list):
            prefix, suffix = '%s[' % name, ']'
        elif values:
            prefix, suffix = '%s%s(' % (name, type(node).__name__), ')'
        elif isinstance(node, special):
            prefix, suffix = name + type(node).__name__, ''
        else:
            return '%s%s' % (name, repr(node))
        node = [dump(a, b, level) for a, b in values if b != 'ctx']
        oneline = '%s%s%s' % (prefix, ', '.join(node), suffix)
        if len(oneline) + len(indent) < maxline:
            return '%s' % oneline
        if node and len(prefix) + len(node[0]) < maxmerged:
            prefix = '%s%s,' % (prefix, node.pop(0))
        node = (',\n%s' % level).join(node).lstrip()
        return '%s\n%s%s%s' % (prefix, level, node, suffix)
    return dump(node, name, initial_indent)
1030059
def _handle_init_list(self, node, scope, ctxt, stream):
        
        self._dlog("handling init list")
        res = []
        for _,init_child in node.children():
            init_field = self._handle_node(init_child, scope, ctxt, stream)
            res.append(init_field)
        return res
890996
function processNode(attrNode, context) {
    const isMainResource = context.attrPath.length === 0;

    // identify/handle options-contexts: resource/sub-resource, nested-attribute, attribute:
    if (attrNode.dataSources || attrNode.resource || isMainResource) {
        context.errorContext = getErrorContext(isMainResource ? 'resource' : 'sub-resource', context);
        context.subAttrPath = [];
        context.dataSourceAttributes = {};

        if (isMainResource) {
            parseNode(
                attrNode,
                {
                    dataSources: null,
                    subFilters: parseSubFilters,
                    resource: checkResourceName,
                    primaryKey: parsePrimaryKey,
                    depends: parseDepends,
                    deprecated: parseBoolean,
                    permission: null,
                    attributes: null,
                    defaultLimit: parseInteger,
                    maxLimit: parseInteger,
                    defaultOrder: requestParser.order
                },
                context
            );
        } else {
            parseNode(
                attrNode,
                {
                    dataSources: null,
                    subFilters: parseSubFilters,
                    resource: checkResourceName,
                    primaryKey: parsePrimaryKey,
                    parentKey: parseRelationKey,
                    childKey: parseRelationKey,
                    many: parseBoolean,
                    depends: parseDepends,
                    hidden: parseBoolean,
                    deprecated: parseBoolean,
                    permission: null,
                    joinVia: checkIdentifier,
                    attributes: null,
                    defaultLimit: parseInteger,
                    maxLimit: parseInteger,
                    defaultOrder: requestParser.order
                },
                context
            );
        }

        handleResourceContext(attrNode, context);
    } else if (attrNode.attributes) {
        context.errorContext = getErrorContext('nested-attribute', context);

        parseNode(
            attrNode,
            {
                depends: parseDepends,
                hidden: parseBoolean,
                deprecated: parseBoolean,
                permission: null,
                attributes: null
            },
            context
        );

        // no context-specific special-cases for nested-attributes
    } else {
        context.errorContext = getErrorContext('attribute', context);

        // prepare standard-mapping - except for fixed values and inherited attributes:
        if (!attrNode.map && !('value' in attrNode) && attrNode.inherit !== 'inherit') {
            attrNode.map = null; // "null" means "set standard-mapping in parseMap()"
        }

        parseNode(
            attrNode,
            {
                type: parseType,
                multiValued: parseBoolean,
                storedType: parseStoredType,
                delimiter: null,
                map: parseMap,
                filter: parseFilter,
                order: parseOrder,
                value: parseStaticValue,
                depends: parseDepends,
                hidden: parseBoolean,
                deprecated: parseBoolean,
                permission: null,
                inherit: parseInherit
            },
            context
        );

        handleAttributeContext(attrNode, context);
    }

    // recursion:
    if (attrNode.attributes) {
        Object.keys(attrNode.attributes).forEach(subAttrName => {
            const subAttrNode = attrNode.attributes[subAttrName];

            const subContext = Object.assign({}, context);
            subContext.attrPath = context.attrPath.concat([subAttrName]);
            subContext.subAttrPath = context.subAttrPath.concat([subAttrName]);

            processNode(subAttrNode, subContext);
        });
    }

    if (attrNode.dataSources) {
        if (attrNode.primaryKey) resolvePrimaryKey(attrNode, context);
        prepareDataSources(attrNode, context);
    }
}
1232463
private void buildRuntimeTree() {
    updateRuntime();
    Runtime rootInfo = findRuntime();
    root = new RuntimeNode();
    root.setFrameName("_top");
    root.setRuntimeID(rootInfo.getRuntimeID());

    List<Runtime> runtimeInfos = Lists.newArrayList(runtimesList.values());
    runtimeInfos.remove(rootInfo);

    for (Runtime runtimeInfo : runtimeInfos) {
      addNode(runtimeInfo, root);
    }
  }