<commit_before>defmodule Mix.Tasks.New do
  use Mix.Task

  import Mix.Generator
  import Mix.Utils, only: [camelize: 1, underscore: 1]

  @shortdoc "Create a new Elixir project"

  @moduledoc """
  Creates a new Elixir project.
  It expects the path of the project as argument.

      mix new PATH [--bare] [--module MODULE] [--umbrella]

  A project at the given PATH  will be created. The
  application name and module name will be retrieved
  from the path, unless `--module` is given.

  A `--bare` option can be given to not generate an OTP
  application skeleton. Normally an app is generated with
  a supervisor and an application module that starts the
  supervisor.

  An `--umbrella` option can be given to generate an
  umbrella project.

  ## Examples

      mix new hello_world

  Is equivalent to:

      mix new hello_world --module HelloWorld

  To generate an app without supervisor and application behaviours:

      mix new hello_world --bare

  """
  def run(argv) do
    {opts, argv, _} = OptionParser.parse(argv, switches: [bare: :boolean, umbrella: :boolean])

    case argv do
      [] ->
        raise Mix.Error, message: "Expected PATH to be given, please use `mix new PATH`"
      [path|_] ->
        name = Path.basename(Path.expand(path))
        check_project_name!(name)
        File.mkdir_p!(path)

        File.cd! path, fn ->
          if opts[:umbrella] do
            do_generate_umbrella(name, path, opts)
          else
            do_generate(name, path, opts)
          end
        end
    end
  end

  defp do_generate(app, path, opts) do
    mod     = opts[:module] || camelize(app)
    assigns = [app: app, mod: mod, otp_app: otp_app(mod, !!opts[:bare])]

    create_file "README.md",  readme_template(assigns)
    create_file ".gitignore", gitignore_text

    if in_umbrella? do
      create_file "mix.exs", mixfile_apps_template(assigns)
    else
      create_file "mix.exs", mixfile_template(assigns)
    end

    create_directory "lib"

    if opts[:bare] do
      create_file "lib/#{app}.ex", lib_template(assigns)
    else
      create_file "lib/#{app}.ex", lib_app_template(assigns)
      create_directory "config"
      create_file "config/config.exs", config_template(assigns)
    end

    create_directory "test"
    create_file "test/test_helper.exs", test_helper_template(assigns)
    create_file "test/#{app}_test.exs", test_lib_template(assigns)

    Mix.shell.info """

    Your mix project was created successfully.
    You can use mix to compile it, test it, and more:

        cd #{path}
        mix test

    Run `mix help` for more commands.
    """
  end

  defp otp_app(_mod, true) do
    "    [applications: []]"
  end

  defp otp_app(mod, false) do
    "    [applications: [],\n     mod: {#{mod}, []}]"
  end

  defp do_generate_umbrella(app, path, _opts) do
    mod = camelize(app)
    assigns = [mod: mod]

    create_file ".gitignore", gitignore_text
    create_file "README.md", readme_template(assigns)
    create_file "mix.exs",   mixfile_umbrella_template(assigns)

    create_directory "apps"

    Mix.shell.info """

    Your umbrella project was created successfully.
    Inside your project, you will find an apps/ directory
    where you can create and host many apps:

        cd #{path}
        cd apps
        mix new my_app

    Commands like `mix compile` and `mix test` when executed
    in the umbrella project root will automatically run
    for each application in the apps/ directory.
    """
  end

  defp check_project_name!(name) do
    unless name =~ ~r/^[a-z][\w_]*$/ do
      raise Mix.Error, message: "Project path must start with a letter and have only lowercase letters, numbers and underscore"
    end
  end

  defp in_umbrella? do
    apps = Path.dirname(File.cwd!)

    try do
      Mix.Project.in_project(:umbrella_check, "../..", fn _ ->
        path = Mix.Project.config[:apps_path]
        path && Path.expand(path) == apps
      end)
    catch
      _, _ -> false
    end
  end

   embed_template :readme, """
   # <%= @mod %>

   ** TODO: Add description **
   """

   embed_text :gitignore, """
   /_build
   /deps<commit_msg>Make the title in the Readme generated by mix new more prominent<commit_after>defmodule Mix.Tasks.New do
  use Mix.Task

  import Mix.Generator
  import Mix.Utils, only: [camelize: 1, underscore: 1]

  @shortdoc "Create a new Elixir project"

  @moduledoc """
  Creates a new Elixir project.
  It expects the path of the project as argument.

      mix new PATH [--bare] [--module MODULE] [--umbrella]

  A project at the given PATH  will be created. The
  application name and module name will be retrieved
  from the path, unless `--module` is given.

  A `--bare` option can be given to not generate an OTP
  application skeleton. Normally an app is generated with
  a supervisor and an application module that starts the
  supervisor.

  An `--umbrella` option can be given to generate an
  umbrella project.

  ## Examples

      mix new hello_world

  Is equivalent to:

      mix new hello_world --module HelloWorld

  To generate an app without supervisor and application behaviours:

      mix new hello_world --bare

  """
  def run(argv) do
    {opts, argv, _} = OptionParser.parse(argv, switches: [bare: :boolean, umbrella: :boolean])

    case argv do
      [] ->
        raise Mix.Error, message: "Expected PATH to be given, please use `mix new PATH`"
      [path|_] ->
        name = Path.basename(Path.expand(path))
        check_project_name!(name)
        File.mkdir_p!(path)

        File.cd! path, fn ->
          if opts[:umbrella] do
            do_generate_umbrella(name, path, opts)
          else
            do_generate(name, path, opts)
          end
        end
    end
  end

  defp do_generate(app, path, opts) do
    mod     = opts[:module] || camelize(app)
    assigns = [app: app, mod: mod, otp_app: otp_app(mod, !!opts[:bare])]

    create_file "README.md",  readme_template(assigns)
    create_file ".gitignore", gitignore_text

    if in_umbrella? do
      create_file "mix.exs", mixfile_apps_template(assigns)
    else
      create_file "mix.exs", mixfile_template(assigns)
    end

    create_directory "lib"

    if opts[:bare] do
      create_file "lib/#{app}.ex", lib_template(assigns)
    else
      create_file "lib/#{app}.ex", lib_app_template(assigns)
      create_directory "config"
      create_file "config/config.exs", config_template(assigns)
    end

    create_directory "test"
    create_file "test/test_helper.exs", test_helper_template(assigns)
    create_file "test/#{app}_test.exs", test_lib_template(assigns)

    Mix.shell.info """

    Your mix project was created successfully.
    You can use mix to compile it, test it, and more:

        cd #{path}
        mix test

    Run `mix help` for more commands.
    """
  end

  defp otp_app(_mod, true) do
    "    [applications: []]"
  end

  defp otp_app(mod, false) do
    "    [applications: [],\n     mod: {#{mod}, []}]"
  end

  defp do_generate_umbrella(app, path, _opts) do
    mod = camelize(app)
    assigns = [mod: mod]

    create_file ".gitignore", gitignore_text
    create_file "README.md", readme_template(assigns)
    create_file "mix.exs",   mixfile_umbrella_template(assigns)

    create_directory "apps"

    Mix.shell.info """

    Your umbrella project was created successfully.
    Inside your project, you will find an apps/ directory
    where you can create and host many apps:

        cd #{path}
        cd apps
        mix new my_app

    Commands like `mix compile` and `mix test` when executed
    in the umbrella project root will automatically run
    for each application in the apps/ directory.
    """
  end

  defp check_project_name!(name) do
    unless name =~ ~r/^[a-z][\w_]*$/ do
      raise Mix.Error, message: "Project path must start with a letter and have only lowercase letters, numbers and underscore"
    end
  end

  defp in_umbrella? do
    apps = Path.dirname(File.cwd!)

    try do
      Mix.Project.in_project(:umbrella_check, "../..", fn _ ->
        path = Mix.Project.config[:apps_path]
        path && Path.expand(path) == apps
      end)
    catch
      _, _ -> false
    end
  end

   embed_template :readme, """
   <%= @mod %>
   <%= String.duplicate("=", String.length(@mod)) %>

   ** TODO: Add description **
   """

   embed_text :gitignore, """
   /_build
   /deps
{'fraction_non_alphanumeric': 0.1028428093645485, 'fraction_numerical': 0.00047778308647873863, 'mean_word_length': 2.698321554770318, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 16, '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': '2240178', 'n_tokens_mistral': 2762, 'n_tokens_neox': 2602, 'n_words': 846}