/**
   * Times the execution of a closure, which can include a target. For example,
   *
   * <p>profile("compile", compile)
   *
   * <p>where 'compile' is the target.
   */
  public void profile(String name, Closure<?> callable) {
    if (enableProfile) {
      long now = System.currentTimeMillis();
      GrailsConsole console = GrailsConsole.getInstance();
      console.addStatus("Profiling [" + name + "] start");

      callable.call();
      long then = System.currentTimeMillis() - now;
      console.addStatus("Profiling [" + name + "] finish. Took " + then + " ms");
    } else {
      callable.call();
    }
  }
  /** Exits the build immediately with a given exit code. */
  public void exit(int code) {
    if (buildEventListener != null) {
      buildEventListener.triggerEvent("Exiting", code);
    }

    // Prevent system.exit during unit/integration testing
    if (System.getProperty("grails.cli.testing") != null
        || System.getProperty("grails.disable.exit") != null) {
      throw new ScriptExitException(code);
    }
    GrailsConsole.getInstance().flush();
    System.exit(code);
  }
  /**
   * Resolves the value for a given property name. It first looks for a system property, then in the
   * BuildSettings configuration, and finally uses the given default value if other options are
   * exhausted.
   */
  public Object getPropertyValue(String propName, Object defaultValue) {
    // First check whether we have a system property with the given name.
    Object value = System.getProperty(propName);
    if (value != null) return value;

    // Now try the BuildSettings settings.
    value = buildProps.get(propName);

    // Return the BuildSettings value if there is one, otherwise use the default.
    return value != null ? value : defaultValue;
  }