<commit_before>package com.google.copybara.config.skylark;

import static com.google.common.base.Preconditions.checkState;
import static com.google.copybara.config.ConfigValidationException.checkCondition;
import static com.google.copybara.config.ConfigValidationException.checkNotMissing;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableSet;
import com.google.copybara.Authoring;
import com.google.copybara.Core;
import com.google.copybara.EnvironmentException;
import com.google.copybara.GeneralOptions;
import com.google.copybara.Options;
import com.google.copybara.Workflow;
import com.google.copybara.WorkflowOptions;
import com.google.copybara.config.Config;
import com.google.copybara.config.ConfigValidationException;
import com.google.copybara.git.Git;
import com.google.copybara.util.console.Console;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
import com.google.devtools.build.lib.syntax.BuildFileAST;
import com.google.devtools.build.lib.syntax.Environment;
import com.google.devtools.build.lib.syntax.Environment.Frame;
import com.google.devtools.build.lib.syntax.Mutability;
import com.google.devtools.build.lib.syntax.Runtime;
import com.google.devtools.build.lib.syntax.SkylarkSignatureProcessor;
import com.google.devtools.build.lib.syntax.ValidationEnvironment;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.inmemoryfs.InMemoryFileSystem;

import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.annotation.Nullable;

/**
 * An experiment that loads Copybara configs from bzl files.
 */
public class SkylarkParser {

  private static final Logger logger = Logger.getLogger(SkylarkParser.class.getName());
  // For now all the modules are namespaces. We don't use variables except for 'core'.
  private final Iterable<Class<?>> modules;

  public SkylarkParser(Set<Class<?>> modules) {
    this.modules = ImmutableSet.<Class<?>>builder()
        .add(Authoring.Module.class)
        .add(Core.class)
        .add(Git.class)
        .addAll(modules).build();

    // Register module functions
    for (Class<?> module : this.modules) {
      logger.log(Level.INFO, "Registering module " + module.getName());
      // This method should be only called once for VM or at least not concurrently,
      // since it registers functions in an static HashMap.
      SkylarkSignatureProcessor.configureSkylarkFunctions(module);
    }
  }

  public Config loadConfig(String content, Options options)
      throws IOException, ConfigValidationException, EnvironmentException {
    Core core;
    try {
      Environment env = executeSkylark(content, options, /*environment*/ null);

      core = (Core) env.getGlobals().get(Core.CORE_VAR);
    } catch (InterruptedException e) {
      // This should not happen since we shouldn't have anything interruptable during loading.
      throw new RuntimeException("Internal error", e);
    }
    return createConfig(options, core.getWorkflows(), core.getProjectName());
  }

  @VisibleForTesting
  public Environment executeSkylark(
      String content, Options options, @Nullable Map<String, String> environment)
      throws IOException, ConfigValidationException, InterruptedException {
    Console console = options.get(GeneralOptions.class).console();
    EventHandler eventHandler = new ConsoleEventHandler(console);<commit_msg>Don't log to info before logger configured<commit_after>package com.google.copybara.config.skylark;

import static com.google.common.base.Preconditions.checkState;
import static com.google.copybara.config.ConfigValidationException.checkCondition;
import static com.google.copybara.config.ConfigValidationException.checkNotMissing;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableSet;
import com.google.copybara.Authoring;
import com.google.copybara.Core;
import com.google.copybara.EnvironmentException;
import com.google.copybara.GeneralOptions;
import com.google.copybara.Options;
import com.google.copybara.Workflow;
import com.google.copybara.WorkflowOptions;
import com.google.copybara.config.Config;
import com.google.copybara.config.ConfigValidationException;
import com.google.copybara.git.Git;
import com.google.copybara.util.console.Console;
import com.google.devtools.build.lib.events.Event;
import com.google.devtools.build.lib.events.EventHandler;
import com.google.devtools.build.lib.skylarkinterface.SkylarkModule;
import com.google.devtools.build.lib.syntax.BuildFileAST;
import com.google.devtools.build.lib.syntax.Environment;
import com.google.devtools.build.lib.syntax.Environment.Frame;
import com.google.devtools.build.lib.syntax.Mutability;
import com.google.devtools.build.lib.syntax.Runtime;
import com.google.devtools.build.lib.syntax.SkylarkSignatureProcessor;
import com.google.devtools.build.lib.syntax.ValidationEnvironment;
import com.google.devtools.build.lib.vfs.FileSystemUtils;
import com.google.devtools.build.lib.vfs.inmemoryfs.InMemoryFileSystem;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Nullable;

/**
 * An experiment that loads Copybara configs from bzl files.
 */
public class SkylarkParser {

  private static final Logger logger = Logger.getLogger(SkylarkParser.class.getName());
  // For now all the modules are namespaces. We don't use variables except for 'core'.
  private final Iterable<Class<?>> modules;

  public SkylarkParser(Set<Class<?>> modules) {
    this.modules = ImmutableSet.<Class<?>>builder()
        .add(Authoring.Module.class)
        .add(Core.class)
        .add(Git.class)
        .addAll(modules).build();

    // Register module functions
    for (Class<?> module : this.modules) {
      // This method should be only called once for VM or at least not concurrently,
      // since it registers functions in an static HashMap.
      try {
        SkylarkSignatureProcessor.configureSkylarkFunctions(module);
      } catch (Exception e) {
        throw new RuntimeException("Cannot register module " + module.getName(), e);
      }
    }
  }

  public Config loadConfig(String content, Options options)
      throws IOException, ConfigValidationException, EnvironmentException {
    Core core;
    try {
      Environment env = executeSkylark(content, options, /*environment*/ null);

      core = (Core) env.getGlobals().get(Core.CORE_VAR);
    } catch (InterruptedException e) {
      // This should not happen since we shouldn't have anything interruptable during loading.
      throw new RuntimeException("Internal error", e);
    }
    return createConfig(options, core.getWorkflows(), core.getProjectName());
  }

  @VisibleForTesting
  public Environment executeSkylark(
      String content, Options options, @Nullable Map<String, String> environment)
      throws IOException, ConfigValidationException, InterruptedException {
    Console console = options.get(GeneralOptions.class).console();
    EventHandler eventHandler = new ConsoleEventHandler(console);
{'fraction_non_alphanumeric': 0.10278460278460279, 'fraction_numerical': 0.0, 'mean_word_length': 4.733176838810642, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '3953308', 'n_tokens_mistral': 2053, 'n_tokens_neox': 2021, 'n_words': 454}