<commit_before>package sbt2nix

import sbt.Keys._
import sbt._

import scala.io.Source
import scalaz.NonEmptyList
import scalaz.Scalaz._

object NixPlugin extends Plugin {

  val commandName = SettingKey[String]("nix-command-name", "The name of the command.")

  override def settings: Seq[Setting[_]] = {
    Seq(
      commandName := "nix",
      commands <+= commandName(nixCommand)
    )
  }

  import sbt.complete.DefaultParsers._

  def nixCommand(commandName: String): Command =
    Command(commandName)(_ => EOF)((state, args) => {

      val structure = Project.extract(state).structure
      val base = baseDirectory(structure.rootProject(structure.root), state).getOrElse(???)
      val alldeps = collection.mutable.ListBuffer[Lib]()
      for {
        ref <- structure.allProjectRefs
        project <- Project.getProject(ref, structure).toSeq
        config <- Seq(Compile)
      } yield {
        // TODO Remove this!
        val bd = baseDirectory(ref, state).getOrElse(???)
        val projs = project.dependencies.collect {
          case dependency if isInConfiguration(config, ref, dependency, state) =>
            for {
              name <- Keys.name.in(dependency.project).get(structure.data).orElse(Some(dependency.project.project))
              base <- Keys.baseDirectory.in(dependency.project).get(structure.data)
            } yield (name, FileUtils.relativize(bd, base))
        }.flatten

        val deps = externalDependencies(ref, state)(config)
        deps.foreach(alldeps += _)
        val name = setting(Keys.name in ref, state).getOrElse("Unknown")
        // TODO Use \/
        val version = setting(Keys.version in ref, state).getOrElse("1.0-SNAPSHOT")
        val desc = setting(Keys.description in ref, state)

        def proj(name: String, base: File): String = {
          s"$name = import $base { inherit sbt deps; };"
        }

        val depsPath = FileUtils.relativize(bd, base).getPath
        val s = if (project.aggregate.isEmpty) {
          // Nix can only handle source directories that exist
          val src = setting(Keys.unmanagedSourceDirectories in (ref, config), state).getOrElse(Nil)
            .filter(_.exists()).map(FileUtils.relativize(bd, _).getPath)
          // TODO We need to handle test files + dependencies as well
          // Is there a way not to have to inherit sbt manually here?
          val scalacOpts = evaluateTask(Keys.scalacOptions, ref, state).mkString(" ")
          s"""{ sbt ? import $depsPath/sbt.nix {}, deps ? import $depsPath/deps.nix { inherit sbt; } }:
            |let
            |${projs.map(x => proj(x._1, x._2)).mkString("\n")}
            |
            |in sbt.mkDerivation {
            |  pname = "$name";
            |  version = "$version";
            |  src = ./.;
            |  sources = [ ${src.mkString(" ")} ];
            |  modules = [ ${projs.map(_._1).mkString(" ")} ];
            |  scalacOptions = "$scalacOpts";
            |  buildDepends = [
            |    ${deps.map(x => toName(x.artifact)).map("deps." +).mkString(" ")}
            |  ];
            |  meta = {
            |    ${desc.map(d => "description = " + "\"" + d + "\";").getOrElse("")}
            |  };
            |}""".stripMargin
        } else {
          val aggs = project.aggregate.map {
            subref => subref.project -> FileUtils.relativize(base, baseDirectory(subref, state).getOrElse(???)).getPath
          }
          s"""{ sbt ? import $depsPath/sbt.nix {}, deps ? import $depsPath/deps.nix { inherit sbt; } }:
            |{
            |${aggs.map { case (name, a) => name + " = sbt.callPackage " + a + " {};" }.mkString("\n")}
            |}""".stripMargin
        }
        FileUtils.save(bd / "default.nix", s).unsafePerformIO()
      }<commit_msg>Pass sbt and deps to aggregate dependencies<commit_after>package sbt2nix

import sbt.Keys._
import sbt._

import scala.io.Source
import scalaz.NonEmptyList
import scalaz.Scalaz._

object NixPlugin extends Plugin {

  val commandName = SettingKey[String]("nix-command-name", "The name of the command.")

  override def settings: Seq[Setting[_]] = {
    Seq(
      commandName := "nix",
      commands <+= commandName(nixCommand)
    )
  }

  import sbt.complete.DefaultParsers._

  def nixCommand(commandName: String): Command =
    Command(commandName)(_ => EOF)((state, args) => {

      val structure = Project.extract(state).structure
      val base = baseDirectory(structure.rootProject(structure.root), state).getOrElse(???)
      val alldeps = collection.mutable.ListBuffer[Lib]()
      for {
        ref <- structure.allProjectRefs
        project <- Project.getProject(ref, structure).toSeq
        config <- Seq(Compile)
      } yield {
        // TODO Remove this!
        val bd = baseDirectory(ref, state).getOrElse(???)
        val projs = project.dependencies.collect {
          case dependency if isInConfiguration(config, ref, dependency, state) =>
            for {
              name <- Keys.name.in(dependency.project).get(structure.data).orElse(Some(dependency.project.project))
              base <- Keys.baseDirectory.in(dependency.project).get(structure.data)
            } yield (name, FileUtils.relativize(bd, base))
        }.flatten

        val deps = externalDependencies(ref, state)(config)
        deps.foreach(alldeps += _)
        val name = setting(Keys.name in ref, state).getOrElse("Unknown")
        // TODO Use \/
        val version = setting(Keys.version in ref, state).getOrElse("1.0-SNAPSHOT")
        val desc = setting(Keys.description in ref, state)

        def proj(name: String, base: File): String = {
          s"$name = import $base { inherit sbt deps; };"
        }

        val depsPath = FileUtils.relativize(bd, base).getPath
        val s = if (project.aggregate.isEmpty) {
          // Nix can only handle source directories that exist
          val src = setting(Keys.unmanagedSourceDirectories in (ref, config), state).getOrElse(Nil)
            .filter(_.exists()).map(FileUtils.relativize(bd, _).getPath)
          // TODO We need to handle test files + dependencies as well
          // Is there a way not to have to inherit sbt manually here?
          val scalacOpts = evaluateTask(Keys.scalacOptions, ref, state).mkString(" ")
          s"""{ sbt ? import $depsPath/sbt.nix {}, deps ? import $depsPath/deps.nix { inherit sbt; } }:
            |let
            |${projs.map(x => proj(x._1, x._2)).mkString("\n")}
            |
            |in sbt.mkDerivation {
            |  pname = "$name";
            |  version = "$version";
            |  src = ./.;
            |  sources = [ ${src.mkString(" ")} ];
            |  modules = [ ${projs.map(_._1).mkString(" ")} ];
            |  scalacOptions = "$scalacOpts";
            |  buildDepends = [
            |    ${deps.map(x => toName(x.artifact)).map("deps." +).mkString(" ")}
            |  ];
            |  meta = {
            |    ${desc.map(d => "description = " + "\"" + d + "\";").getOrElse("")}
            |  };
            |}""".stripMargin
        } else {
          val aggs = project.aggregate.map {
            subref => subref.project -> FileUtils.relativize(base, baseDirectory(subref, state).getOrElse(???)).getPath
          }
          s"""{ sbt ? import $depsPath/sbt.nix {}, deps ? import $depsPath/deps.nix { inherit sbt; } }:
            |{
            |${aggs.map { case (name, a) => name + " = sbt.callPackage " + a + " { inherit sbt deps; };" }.mkString("\n")}
            |}""".stripMargin
        }
        FileUtils.save(bd / "default.nix", s).unsafePerformIO()
      }
{'fraction_non_alphanumeric': 0.14665963895111345, 'fraction_numerical': 0.0015812359994729214, 'mean_word_length': 2.1957894736842105, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 21, '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': '665846', 'n_tokens_mistral': 2374, 'n_tokens_neox': 2284, 'n_words': 495}