<commit_before>defmodule Mix.Tasks.Phoenix.Digest do
  use Mix.Task
  @default_input_path "priv/static"

  @shortdoc "Digests and compress static files"

  @moduledoc """
  Digests and compress static files.

      mix phoenix.digest
      mix phoenix.digest priv/static -o /www/public

  The first argument is the path where the static files are located. The
  `-o` option indicates the path that will be used to save the digested and
  compressed files.

  If no path is given, it will use `priv/static` as the input and output path.

  The output folder will contain:

    * the original file
    * a compressed file with gzip
    * a file containing the original file name and its digest
    * a compressed file containing the file name and its digest
    * a manifest file

  Example of generated files:

    * application.js.erb
    * application.js.erb.gz
    * application.js-eb0a5b9302e8d32828d8a73f137cc8f0.erb
    * application.js-eb0a5b9302e8d32828d8a73f137cc8f0.erb.gz
    * manifest.json
  """

  def run(args) do
    {opts, args, _} = OptionParser.parse(args, aliases: [o: :output])
    input_path  = List.first(args) || @default_input_path
    output_path = opts[:output] || input_path

    case Phoenix.Digester.compile(input_path, output_path) do
      :ok -> Mix.shell.info [:green, "Check your digested files at '#{output_path}'."]
      {:error, :invalid_path} -> Mix.raise "The input path '#{input_path}' does not exist."
    end
  end
end<commit_msg>Ensure we rebuild the sructure after digesting, closes #893<commit_after>defmodule Mix.Tasks.Phoenix.Digest do
  use Mix.Task
  @default_input_path "priv/static"

  @shortdoc "Digests and compress static files"

  @moduledoc """
  Digests and compress static files.

      mix phoenix.digest
      mix phoenix.digest priv/static -o /www/public

  The first argument is the path where the static files are located. The
  `-o` option indicates the path that will be used to save the digested and
  compressed files.

  If no path is given, it will use `priv/static` as the input and output path.

  The output folder will contain:

    * the original file
    * a compressed file with gzip
    * a file containing the original file name and its digest
    * a compressed file containing the file name and its digest
    * a manifest file

  Example of generated files:

    * application.js.erb
    * application.js.erb.gz
    * application.js-eb0a5b9302e8d32828d8a73f137cc8f0.erb
    * application.js-eb0a5b9302e8d32828d8a73f137cc8f0.erb.gz
    * manifest.json
  """

  def run(args) do
    {opts, args, _} = OptionParser.parse(args, aliases: [o: :output])
    input_path  = List.first(args) || @default_input_path
    output_path = opts[:output] || input_path

    case Phoenix.Digester.compile(input_path, output_path) do
      :ok ->
        # We need to call build structure so everything we have
        # generated into priv is copied to _build in case we have
        # build_embedded set to true. In case if it not true,
        # build structure is mostly a no-op, so we are fine.
        Mix.Project.build_structure()
        Mix.shell.info [:green, "Check your digested files at '#{output_path}'."]
      {:error, :invalid_path} ->
        Mix.raise "The input path '#{input_path}' does not exist."
    end
  end
end
{'fraction_non_alphanumeric': 0.08335859351318581, 'fraction_numerical': 0.025159139133070628, 'mean_word_length': 3.1457286432160805, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 7, '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': '6791842', 'n_tokens_mistral': 1094, 'n_tokens_neox': 1024, 'n_words': 361}