<commit_before>defmodule Mix.Releases.Assembler do
  @moduledoc """
  This module is responsible for assembling a release based on a `Mix.Releases.Config`
  struct. It creates the release directory, copies applications, and generates release-specific
  files required by `:systools` and `:release_handler`.
  """
  alias Mix.Releases.{Config, Release, Environment, Profile, App}
  alias Mix.Releases.{Utils, Logger, Appup, Plugin, Overlays}

  require Record
  Record.defrecordp :file_info, Record.extract(:file_info, from_lib: "kernel/include/file.hrl")

  @doc """
  This function takes a Config struct and assembles the release.

  **Note: This operation has side-effects!** It creates files, directories,
  copies files from other filesystem locations. If failures occur, no cleanup
  of files/directories is performed. However, all files/directories created by
  this function are scoped to the current project's `rel` directory, and cannot
  impact the filesystem outside of this directory.
  """
  @spec assemble(Config.t) :: {:ok, Config.t} | {:error, term}
  def assemble(%Config{} = config) do
    with {:ok, environment} <- Release.select_environment(config),
         {:ok, release}     <- Release.select_release(config),
         release            <- apply_environment(release, environment),
         :ok                <- validate_configuration(release),
         {:ok, release}     <- Release.apply_configuration(release, config, true),
         :ok                <- File.mkdir_p(release.profile.output_dir),
         {:ok, release}     <- Plugin.before_assembly(release),
         {:ok, release}     <- generate_overlay_vars(release),
         {:ok, release}     <- copy_applications(release),
         :ok                <- create_release_info(release),
         {:ok, release}     <- apply_overlays(release),
         {:ok, release}     <- Plugin.after_assembly(release),
      do: {:ok, release}
  end

  # Applies the environment profile to the release profile.
  @spec apply_environment(Release.t, Environment.t) :: {:ok, Release.t} | {:error, term}
  def apply_environment(%Release{} = r, %Environment{} = e) do
    Logger.info "Building release #{r.name}:#{r.version} using environment #{e.name}"
    Release.apply_environment(r, e)
  end

  @spec validate_configuration(Release.t) :: :ok | {:error, term}
  def validate_configuration(%Release{} = release) do
    case Release.validate_configuration(release) do
      {:ok, warning} ->
        Logger.notice(warning)
        :ok
      other ->
        other
    end
  end

  # Copies application beams to the output directory
  defp copy_applications(%Release{profile: %Profile{output_dir: output_dir}} = release) do
    Logger.debug "Copying applications to #{output_dir}"
    try do
      File.mkdir_p!(Path.join(output_dir, "lib"))
      for app <- release.applications do
        copy_app(app, release)
      end
      # Copy consolidated .beams
      build_path = Mix.Project.build_path(Mix.Project.config)
      consolidated_dest = Path.join([output_dir, "lib", "#{release.name}-#{release.version}", "consolidated"])
      File.mkdir_p!(consolidated_dest)
      consolidated_src = Path.join(build_path, "consolidated")
      if File.exists?(consolidated_src) do
        {:ok, _} = File.cp_r(consolidated_src, consolidated_dest)
      end<commit_msg>Fix consolidation path (#307)<commit_after>defmodule Mix.Releases.Assembler do
  @moduledoc """
  This module is responsible for assembling a release based on a `Mix.Releases.Config`
  struct. It creates the release directory, copies applications, and generates release-specific
  files required by `:systools` and `:release_handler`.
  """
  alias Mix.Releases.{Config, Release, Environment, Profile, App}
  alias Mix.Releases.{Utils, Logger, Appup, Plugin, Overlays}

  require Record
  Record.defrecordp :file_info, Record.extract(:file_info, from_lib: "kernel/include/file.hrl")

  @doc """
  This function takes a Config struct and assembles the release.

  **Note: This operation has side-effects!** It creates files, directories,
  copies files from other filesystem locations. If failures occur, no cleanup
  of files/directories is performed. However, all files/directories created by
  this function are scoped to the current project's `rel` directory, and cannot
  impact the filesystem outside of this directory.
  """
  @spec assemble(Config.t) :: {:ok, Config.t} | {:error, term}
  def assemble(%Config{} = config) do
    with {:ok, environment} <- Release.select_environment(config),
         {:ok, release}     <- Release.select_release(config),
         release            <- apply_environment(release, environment),
         :ok                <- validate_configuration(release),
         {:ok, release}     <- Release.apply_configuration(release, config, true),
         :ok                <- File.mkdir_p(release.profile.output_dir),
         {:ok, release}     <- Plugin.before_assembly(release),
         {:ok, release}     <- generate_overlay_vars(release),
         {:ok, release}     <- copy_applications(release),
         :ok                <- create_release_info(release),
         {:ok, release}     <- apply_overlays(release),
         {:ok, release}     <- Plugin.after_assembly(release),
      do: {:ok, release}
  end

  # Applies the environment profile to the release profile.
  @spec apply_environment(Release.t, Environment.t) :: {:ok, Release.t} | {:error, term}
  def apply_environment(%Release{} = r, %Environment{} = e) do
    Logger.info "Building release #{r.name}:#{r.version} using environment #{e.name}"
    Release.apply_environment(r, e)
  end

  @spec validate_configuration(Release.t) :: :ok | {:error, term}
  def validate_configuration(%Release{} = release) do
    case Release.validate_configuration(release) do
      {:ok, warning} ->
        Logger.notice(warning)
        :ok
      other ->
        other
    end
  end

  # Copies application beams to the output directory
  defp copy_applications(%Release{profile: %Profile{output_dir: output_dir}} = release) do
    Logger.debug "Copying applications to #{output_dir}"
    try do
      File.mkdir_p!(Path.join(output_dir, "lib"))
      for app <- release.applications do
        copy_app(app, release)
      end
      # Copy consolidated .beams
      consolidated_src = Mix.Project.consolidation_path
      consolidated_dest = Path.join([output_dir, "lib", "#{release.name}-#{release.version}", "consolidated"])
      File.mkdir_p!(consolidated_dest)
      if File.exists?(consolidated_src) do
        {:ok, _} = File.cp_r(consolidated_src, consolidated_dest)
      end
{'fraction_non_alphanumeric': 0.11775389738156501, 'fraction_numerical': 0.0004540638716512789, 'mean_word_length': 3.3217789404839766, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 7, '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': '226236', 'n_tokens_mistral': 1968, 'n_tokens_neox': 1861, 'n_words': 525}