Skip to content

Instantly share code, notes, and snippets.

@x7c1
Last active February 5, 2017 15:05
Show Gist options
  • Select an option

  • Save x7c1/2cf05ad8ee85b61978245fd7fa081d1c to your computer and use it in GitHub Desktop.

Select an option

Save x7c1/2cf05ad8ee85b61978245fd7fa081d1c to your computer and use it in GitHub Desktop.
Runs publishLocal on '-SNAPSHOT' version.
import sbt.State
object CommandRunner {
/**
* Convert the given command string to a release step action,
* preserving and invoking remaining commands
* Note: This was copied from https://github.com/sbt/sbt-release/blob/663cfd426361484228a21a1244b2e6b0f7656bdf/src/main/scala/ReleasePlugin.scala#L99-L115
*/
def runCommand(command: String): State => State = { st: State =>
import sbt.complete.Parser
@annotation.tailrec
def runCommand(command: String, state: State): State = {
val nextState = Parser.parse(command, state.combinedParser) match {
case Right(cmd) => cmd()
case Left(msg) => throw sys.error(s"Invalid programmatic input:\n$msg")
}
nextState.remainingCommands.toList match {
case Nil => nextState
case head :: tail => runCommand(head, nextState.copy(remainingCommands = tail))
}
}
runCommand(command, st.copy(remainingCommands = Nil)).
copy(remainingCommands = st.remainingCommands)
}
}
import sbt.Def.{SettingsDefinition, taskKey}
import sbt.Keys.{publishLocal, version}
import sbt.{Compile, TaskKey}
object PublishLocalSnapshot {
def definition: SettingsDefinition = StateCommand.taskDefinition(
key = publishLocalSnapshot,
updates = Seq(
version := withSuffix(version.value, "-SNAPSHOT")
),
task = publishLocal in Compile
)
lazy val publishLocalSnapshot: TaskKey[Unit] = taskKey[Unit](
"Runs publishLocal on '-SNAPSHOT' version."
)
private def withSuffix(original: String, suffix: String) = {
if (original endsWith suffix) {
original
} else {
original + suffix
}
}
}
import sbt.Command.command
import sbt.Def.{SettingList, SettingsDefinition}
import sbt.Keys.{commands, projectID, state}
import sbt.{Command, Def, Project, State, TaskKey}
object StateCommand {
def apply[A](
name: String,
updates: Seq[Def.Setting[_]],
task: TaskKey[A],
nextState: States => State): Command = {
command(name) { originalState =>
val extracted = Project extract originalState
val newState = extracted.append(updates, originalState)
val (updatedState, _) = Project.extract(newState).runTask(task, newState)
nextState(States(originalState, updatedState))
}
}
def taskDefinition[A](
key: TaskKey[Unit],
updates: Seq[Def.Setting[_]],
task: TaskKey[A]): SettingsDefinition = {
val name = s"${key.key.label}-command"
val settings = Seq(
key := {
val id = projectID.value.name
CommandRunner.runCommand(s";project $id;$name")(state.value)
},
commands ++= Seq(StateCommand(
name = name,
updates = updates,
task = task,
nextState = _.original
))
)
new SettingList(settings)
}
}
case class States(
original: State,
updated: State
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment