Initial API.

Josh Suereth 2014-01-15 13:15:25 -08:00
parent 3280a667d5
commit a7483e4a24
1 changed files with 131 additions and 0 deletions

131
Server-Client-level-API.md Normal file

@ -0,0 +1,131 @@
This document outlines the high-level Server API exposed by sbt 1.0. Beneath this API is one of simple `Request`/`Response`/`Event` messages. While that API will expounded upon, this API represents the "core" of what the other API should expose, and the "best mechanism" of how to consume it.
# Connecting to sbt
```scala
package sbt.client
/**
* This represents something that will connect to the sbt server *and* reconnect on failure.
*
* You can close the connection and stop reconnecting by calling `close()`.
*/
trait SbtConnector extends Closeable {
/**
* Register a callback to be notified on initial connection and subsequent reconnects to
* an sbt server. If the server is already connected, the handler will be called immediately.
*
* @param handler A callback that will be called upon every connection/reconnect.
* @param ex The context (thread) where the handler should be executed.
*/
def onConnect(handler: SbtClient => Unit)(implicit ex: ExecutionContext): Subscription
}
```
# Interacting with the Server
```scala
package sbt.client
/** This represents a connection to the Sbt server, and all the actions that can be performed against an active sbt build. */
trait SbtClient extends Closeable {
/**
* This is our mechanism of watching the build structure to see when it changes,
* and update our information about the build.
*
* @param listener - A listener that is notified on build structure changes.
* @param ex - The context in which we should execute the listener.
*
* @return
* A subscription which can be used to unsubscribe to notifications.
*
* Note: This will load the entire build structure and pass it too us.
*/
def watchBuild(listener: BuildStructureListener)(implicit ex: ExecutionContext): Subscription
// TODO - A mechanism to dynamically load key-dependencies, which are too expensive to compute up front.
// Possibly via watching a project and pulling configuration off of it.
/**
* Gives us the autocompletions possible for a given command string.
*
* @param partialCommand An incomplete command or task string
*
* @return A set of "more complete" strings that could be used as sbt commands.
*
* TODO - This should probably return some more structured "completion" thing.
* That would allow us to return examples or <tag> types that a client would not use
* in autocomplete...
*/
def possibleAutocompletions(partialCommand: String): Future[Set[String]]
/**
* This tries to find whether there is a build key associated with the
* current string.
*
* TODO - default/current project?
* TODO - How to handle delegate keys?
* TODO - Does this make sense to expose?
*/
def lookupScopedKey(name: String): Future[Option[ScopedKey]]
/**
* Runs the command/task associated with the given input string.
*
* @param commandOrTask The full command/task string to run.
* that should be evaluated.
* @return A future that will return Unit if the command request was successfully sent.
*/
def requestExecution(commandOrTask: String): Future[Unit]
/**
* Adds a listener to general events which are fired from this sbt server. These can be things like
* "TaskStarted, TaskCanceled, or even custom events from plugins (via GenericEvent).
*
* @param listener A function that is called when events are fired from sbt.
* @param ex The execution context on which to call the listener.
*/
def handleEvents(listener: EventListener)(implicit ex: ExecutionContext): Subscription
/**
* Adds a listener to a particular setting. If this setting changes, the event listener
* will be notified with the new value (and sent the initial value).
*
* @param key The setting to listen to changes on.
* @param listener A function that is called when the setting value changes.
* @param ex The execution context on which to call the listener.
*/
def watch[T](key: SettingKey[T])(listener: ValueListener[T])(implicit ex: ExecutionContext): Subscription
/**
* Adds a listener for the value of a particular task. If the evaluated task result changes, the event
* listener will be notified of the new value.
*
* Since tasks read their state from the filesystem, it is not guaranteed that an event will be fired upon change *unless* some
* task in the dependency of the specified one is run, requiring the value of the current task to be re-evaluated.
*
* @param key The task to listen to changes for.
* @param listener A function that is called when the setting value changes.
* @param ex The execution context on which to call the listener.
*/
def watch[T](key: TaskKey[T])(l: ValueListener[T])(implicit ex: ExecutionContext): Subscription
}
```
# Various helper classes
Subscription
```scala
package sbt.client
trait Subscription {
def cancel(): Unit
}
```
various aliases:
```scala
package sbt
package object client {
type BuildStructureListener = MinimalBuildStructure => Unit
type ValueListener[T] = (ScopedKey, TaskResult[T]) => Unit
type EventListener = Event => Unit
}
```