99 lines
3.3 KiB
Scala
99 lines
3.3 KiB
Scala
/** Adapted from student-build/project/StudentPlugin.scala in the moocs repo */
|
|
package ch.epfl.lara
|
|
|
|
import java.io.{File, FileInputStream, IOException}
|
|
|
|
import sbt.Keys._
|
|
import sbt._
|
|
|
|
/**
|
|
* Provides tasks for submitting the assignment
|
|
*/
|
|
object StudentPlugin extends AutoPlugin {
|
|
|
|
override lazy val projectSettings = Seq(
|
|
packageSubmissionSetting
|
|
) ++ packageSubmissionZipSettings
|
|
|
|
/** **********************************************************
|
|
* SUBMITTING A SOLUTION TO COURSERA
|
|
*/
|
|
|
|
val packageSourcesOnly = TaskKey[File]("packageSourcesOnly", "Package the sources of the project")
|
|
|
|
val packageSubmissionZip = TaskKey[File]("packageSubmissionZip")
|
|
|
|
val packageSubmissionZipSettings = Seq(
|
|
packageSubmissionZip := {
|
|
val submission = crossTarget.value / "submission.zip"
|
|
val sources = (packageSourcesOnly in Compile).value
|
|
val binaries = (packageBin in Compile).value
|
|
IO.zip(Seq(sources -> "sources.zip", binaries -> "binaries.jar"), submission)
|
|
submission
|
|
},
|
|
// Exclude resources from binaries
|
|
mappings in (Compile, packageBin) := {
|
|
val relativePaths =
|
|
(unmanagedResources in Compile).value.flatMap(Path.relativeTo((unmanagedResourceDirectories in Compile).value)(_))
|
|
(mappings in (Compile, packageBin)).value.filterNot { case (_, path) => relativePaths.contains(path) }
|
|
},
|
|
artifactClassifier in packageSourcesOnly := Some("sources")
|
|
) ++ inConfig(Compile)(Defaults.packageTaskSettings(packageSourcesOnly, Defaults.sourceMappings))
|
|
|
|
val maxSubmitFileSize = {
|
|
val mb = 1024 * 1024
|
|
10 * mb
|
|
}
|
|
|
|
/** Check that the jar exists, isn't empty, isn't crazy big, and can be read
|
|
*/
|
|
def checkJar(jar: File, s: TaskStreams): Unit = {
|
|
val errPrefix = "Error submitting assignment jar: "
|
|
val fileLength = jar.length()
|
|
if (!jar.exists()) {
|
|
s.log.error(errPrefix + "jar archive does not exist\n" + jar.getAbsolutePath)
|
|
failSubmit()
|
|
} else if (fileLength == 0L) {
|
|
s.log.error(errPrefix + "jar archive is empty\n" + jar.getAbsolutePath)
|
|
failSubmit()
|
|
} else if (fileLength > maxSubmitFileSize) {
|
|
s.log.error(errPrefix + "jar archive is too big. Allowed size: " +
|
|
maxSubmitFileSize + " bytes, found " + fileLength + " bytes.\n" +
|
|
jar.getAbsolutePath)
|
|
failSubmit()
|
|
} else {
|
|
val bytes = new Array[Byte](fileLength.toInt)
|
|
val sizeRead = try {
|
|
val is = new FileInputStream(jar)
|
|
val read = is.read(bytes)
|
|
is.close()
|
|
read
|
|
} catch {
|
|
case ex: IOException =>
|
|
s.log.error(errPrefix + "failed to read sources jar archive\n" + ex.toString)
|
|
failSubmit()
|
|
}
|
|
if (sizeRead != bytes.length) {
|
|
s.log.error(errPrefix + "failed to read the sources jar archive, size read: " + sizeRead)
|
|
failSubmit()
|
|
} else () // used to be: `encodeBase64(bytes)`
|
|
}
|
|
}
|
|
|
|
/** Task to package solution to a given file path */
|
|
val packageSubmission = inputKey[Unit]("package solution as an archive file")
|
|
lazy val packageSubmissionSetting = packageSubmission := {
|
|
val s: TaskStreams = streams.value // for logging
|
|
val jar = (packageSubmissionZip in Compile).value
|
|
|
|
checkJar(jar, s)
|
|
|
|
val path = baseDirectory.value / "submission.zip"
|
|
IO.copyFile(jar, path)
|
|
}
|
|
|
|
def failSubmit(): Nothing = {
|
|
sys.error("Packaging failed")
|
|
}
|
|
}
|