<commit_before>package coursier.launcher

import java.io.{ByteArrayInputStream, ByteArrayOutputStream, FileNotFoundException}
import java.nio.charset.StandardCharsets
import java.nio.file.{Files, Path}
import java.util.zip.{CRC32, ZipEntry, ZipInputStream, ZipOutputStream}

import coursier.launcher.internal.{FileUtil, Zip}

object BootstrapGenerator extends Generator[Parameters.Bootstrap] {

  def generate(parameters: Parameters.Bootstrap, output: Path): Unit = {

    val bootstrapResourcePath0 = parameters.bootstrapResourcePathOpt.getOrElse {
      bootstrapResourcePath(parameters.hasResources, parameters.proguarded)
    }

    FileUtil.withOutputStream(output) { os =>

      for (p <- parameters.finalPreambleOpt.map(_.value))
        os.write(p)

      val zos = new ZipOutputStream(os)

      val content0 =
        if (parameters.hybridAssembly)
          parameters.content.headOption match {
            case None =>
              // shouldn't happen
              parameters.content
            case Some(c) =>
              val resources = c.entries.collect { case r: ClassPathEntry.Resource => r }

              if (resources.isEmpty)
                parameters.content
              else {
                val files = resources.map(r => () => new ZipInputStream(new ByteArrayInputStream(r.content)))

                AssemblyGenerator.writeEntries(files.map(Left(_)), zos, MergeRule.default)

                val remaining = c.entries.collect { case u: ClassPathEntry.Url => u }
                if (remaining.isEmpty)
                  parameters.content.drop(1)
                else {
                  val c0 = c.withEntries(remaining)
                  c0 +: parameters.content.drop(1)
                }
              }
          }
        else
          parameters.content

      writeZip(
        zos,
        content0,
        parameters.mainClass,
        bootstrapResourcePath0,
        parameters.deterministic,
        parameters.extraZipEntries,
        parameters.javaProperties
      )

      zos.close()
    }

    FileUtil.tryMakeExecutable(output)
  }

  private def writeZip(
    outputZip: ZipOutputStream,
    content: Seq[ClassLoaderContent],
    mainClass: String,
    bootstrapResourcePath: String,
    deterministic: Boolean,
    extraZipEntries: Seq[(ZipEntry, Array[Byte])],
    properties: Seq[(String, String)]
  ): Unit = {

    val content0 = ClassLoaderContent.withUniqueFileNames(content)

    val bootstrapJar =
      FileUtil.readFully {
        val is = Thread.currentThread().getContextClassLoader.getResourceAsStream(bootstrapResourcePath)
        if (is == null)
          throw new FileNotFoundException(s"Resource $bootstrapResourcePath")
        is
      }

    val bootstrapZip = new ZipInputStream(new ByteArrayInputStream(bootstrapJar))

    for ((ent, content) <- extraZipEntries) {
      outputZip.putNextEntry(ent)
      outputZip.write(content)
      outputZip.closeEntry()
    }

    for ((ent, data) <- Zip.zipEntries(bootstrapZip)) {
      outputZip.putNextEntry(ent)
      outputZip.write(data)
      outputZip.closeEntry()
    }

    val time =
      if (deterministic)
        0
      else
        System.currentTimeMillis()<commit_msg>Make finding resource more robust (#1608)<commit_after>package coursier.launcher

import java.io.{ByteArrayInputStream, ByteArrayOutputStream, FileNotFoundException}
import java.nio.charset.StandardCharsets
import java.nio.file.{Files, Path}
import java.util.zip.{CRC32, ZipEntry, ZipInputStream, ZipOutputStream}

import coursier.launcher.internal.{FileUtil, Zip}

object BootstrapGenerator extends Generator[Parameters.Bootstrap] {

  def generate(parameters: Parameters.Bootstrap, output: Path): Unit = {

    val bootstrapResourcePath0 = parameters.bootstrapResourcePathOpt.getOrElse {
      bootstrapResourcePath(parameters.hasResources, parameters.proguarded)
    }

    FileUtil.withOutputStream(output) { os =>

      for (p <- parameters.finalPreambleOpt.map(_.value))
        os.write(p)

      val zos = new ZipOutputStream(os)

      val content0 =
        if (parameters.hybridAssembly)
          parameters.content.headOption match {
            case None =>
              // shouldn't happen
              parameters.content
            case Some(c) =>
              val resources = c.entries.collect { case r: ClassPathEntry.Resource => r }

              if (resources.isEmpty)
                parameters.content
              else {
                val files = resources.map(r => () => new ZipInputStream(new ByteArrayInputStream(r.content)))

                AssemblyGenerator.writeEntries(files.map(Left(_)), zos, MergeRule.default)

                val remaining = c.entries.collect { case u: ClassPathEntry.Url => u }
                if (remaining.isEmpty)
                  parameters.content.drop(1)
                else {
                  val c0 = c.withEntries(remaining)
                  c0 +: parameters.content.drop(1)
                }
              }
          }
        else
          parameters.content

      writeZip(
        zos,
        content0,
        parameters.mainClass,
        bootstrapResourcePath0,
        parameters.deterministic,
        parameters.extraZipEntries,
        parameters.javaProperties
      )

      zos.close()
    }

    FileUtil.tryMakeExecutable(output)
  }

  private def writeZip(
    outputZip: ZipOutputStream,
    content: Seq[ClassLoaderContent],
    mainClass: String,
    bootstrapResourcePath: String,
    deterministic: Boolean,
    extraZipEntries: Seq[(ZipEntry, Array[Byte])],
    properties: Seq[(String, String)]
  ): Unit = {

    val content0 = ClassLoaderContent.withUniqueFileNames(content)

    val bootstrapJar =
      FileUtil.readFully {
        val is = Thread.currentThread().getContextClassLoader.getResourceAsStream(bootstrapResourcePath)
        if (is == null) {
          val is0 = BootstrapGenerator.getClass.getClassLoader.getResourceAsStream(bootstrapResourcePath)
          if (is0 == null)
            throw new FileNotFoundException(s"Resource $bootstrapResourcePath")
          else
            is0
        } else
          is
      }

    val bootstrapZip = new ZipInputStream(new ByteArrayInputStream(bootstrapJar))

    for ((ent, content) <- extraZipEntries) {
      outputZip.putNextEntry(ent)
      outputZip.write(content)
      outputZip.closeEntry()
    }

    for ((ent, data) <- Zip.zipEntries(bootstrapZip)) {
      outputZip.putNextEntry(ent)
      outputZip.write(data)
      outputZip.closeEntry()
    }

    val time =
      if (deterministic)
        0
      else
        System.currentTimeMillis()
{'fraction_non_alphanumeric': 0.09030604552992613, 'fraction_numerical': 0.004673601688527062, 'mean_word_length': 2.3881511746680286, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 17, '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': '6274389', 'n_tokens_mistral': 1875, 'n_tokens_neox': 1731, 'n_words': 349}