Skip to content
This repository has been archived by the owner on Apr 29, 2024. It is now read-only.

Commit

Permalink
Merge pull request #16 from Tapad/feature/errorHandleUnsupported
Browse files Browse the repository at this point in the history
Added the ability to handle unsupported fields in Compose file.
  • Loading branch information
kurtkopchik authored Jun 13, 2016
2 parents 422bf7b + 2955870 commit 255df97
Show file tree
Hide file tree
Showing 6 changed files with 87 additions and 5 deletions.
14 changes: 13 additions & 1 deletion src/main/scala/com/tapad/docker/ComposeFile.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import scala.collection.{ Iterable, Seq }
import scala.io.Source._
import scala.util.{ Try, Success, Failure }

trait ComposeFile extends SettingsHelper with ComposeCustomTagHelpers {
trait ComposeFile extends SettingsHelper with ComposeCustomTagHelpers with PrintFormatting {
// Compose file Yaml keys
val imageKey = "image"
val environmentKey = "environment"
Expand All @@ -33,6 +33,9 @@ trait ComposeFile extends SettingsHelper with ComposeCustomTagHelpers {

val environmentDebugKey = "JAVA_TOOL_OPTIONS"

//List of docker-compose fields that are currently unsupported by the plugin
val unsupportedFields = List("build", "container_name", "extends")

type yamlData = Map[String, java.util.LinkedHashMap[String, Any]]

/**
Expand All @@ -52,6 +55,9 @@ trait ComposeFile extends SettingsHelper with ComposeCustomTagHelpers {

getComposeFileServices(composeYaml).map { service =>
val (serviceName, serviceData) = service
for (field <- unsupportedFields if serviceData.containsKey(field)) {
throw ComposeFileFormatException(getUnsupportedFieldErrorMsg(field))
}
val imageName = serviceData.get(imageKey).toString

//Update Compose yaml with any images built as part of dockerComposeUp regardless of how it's defined in the
Expand Down Expand Up @@ -88,10 +94,16 @@ trait ComposeFile extends SettingsHelper with ComposeCustomTagHelpers {
}
}

def getUnsupportedFieldErrorMsg(fieldName: String): String = {
s"Docker Compose field '$fieldName:' is currently not supported by sbt-docker-compose. Please see the README for " +
s"more information on the set of unsupported fields."
}

/**
* Attempt to get the fully qualified path to the environment file. It will first attempt to find the file using the
* path provided. If that fails it will attempt to find the file relative to the docker-compose yml location. Otherwise,
* it will throw an exception with information about the file that could not be located.
*
* @param fileName The file name to find
* @param composePath The path to the directory of the docker-compose yml file being used
* @return The fully qualified path to the file
Expand Down
24 changes: 21 additions & 3 deletions src/main/scala/com/tapad/docker/DockerComposePlugin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ import scala.collection._
import scala.concurrent.duration._
import scala.util.Try

/**
* The exception type to be thrown when there is a format issue in the Compose file
*
* @param message The error message to be displayed on the console
*/
case class ComposeFileFormatException(message: String) extends Exception(message)

/**
* Defines an internal to external port mapping for a Docker Compose service port
*
Expand Down Expand Up @@ -82,8 +89,13 @@ class DockerComposePluginLocal extends AutoPlugin with ComposeFile with DockerCo
s"Supply '$skipPullArg' as a parameter to use local images instead of pulling the latest from the Docker Registry. " +
s"Supply '$skipBuildArg' as a parameter to use the current Docker image for the main project instead of building a new one.", "") {
(state: State, args: Seq[String]) =>

launchInstanceWithLatestChanges(state, args)
try {
launchInstanceWithLatestChanges(state, args)
} catch {
case ex: ComposeFileFormatException =>
printError(ex.message)
state
}
}

lazy val dockerComposeStopCommand = Command.args("dockerComposeStop", ("dockerComposeStop", "Stops all local Docker " +
Expand All @@ -109,7 +121,13 @@ class DockerComposePluginLocal extends AutoPlugin with ComposeFile with DockerCo
s"Supply '$testTagOverride:<tagName1,tagName2>' as a parameter to override the tags specified in the testTagsToExecute setting." +
"To execute a test pass against a previously started dockerComposeUp instance just pass the instance id to the command as a parameter", "") { (state: State, args: Seq[String]) =>

composeTestRunner(state, args)
try {
composeTestRunner(state, args)
} catch {
case ex: ComposeFileFormatException =>
printError(ex.message)
state
}
}

def launchInstanceWithLatestChanges(state: State, args: Seq[String]): State = {
Expand Down
6 changes: 6 additions & 0 deletions src/test/resources/unsupported_field_build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
testservice:
build: /path/to/build/dir
environment:
JAVA_TOOL_OPTIONS: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
ports:
- "0:5005"
7 changes: 7 additions & 0 deletions src/test/resources/unsupported_field_container_name.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
testservice:
image: testservice:latest
container_name: my-test-container
environment:
JAVA_TOOL_OPTIONS: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005
ports:
- "0:5005"
6 changes: 6 additions & 0 deletions src/test/resources/unsupported_field_extends.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
testservice:
extends:
file: debug_port.yml
service: testservice
ports:
- "8000:8000"
35 changes: 34 additions & 1 deletion src/test/scala/ComposeFileProcessingSpec.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,47 @@ import java.util

import com.tapad.docker.DockerComposeKeys._
import com.tapad.docker.DockerComposePlugin._
import com.tapad.docker.{ ComposeFile, DockerComposePluginLocal }
import com.tapad.docker.{ ComposeFile, ComposeFileFormatException, DockerComposePluginLocal }
import org.mockito.Mockito._
import org.scalatest.mock.MockitoSugar
import org.scalatest.{ BeforeAndAfter, FunSuite, OneInstancePerTest }
import sbt.Keys._

class ComposeFileProcessingSpec extends FunSuite with BeforeAndAfter with OneInstancePerTest with MockitoSugar {

test("Validate Compose field 'build:' results in correct exception thrown and error message printing") {
val composeMock = getComposeFileMock()
val composeFilePath = getClass.getResource("unsupported_field_build.yml").getPath
val composeYaml = composeMock.readComposeFile(composeFilePath)

val thrown = intercept[ComposeFileFormatException] {
composeMock.processCustomTags(null, null, composeYaml)
}
assert(thrown.getMessage == getUnsupportedFieldErrorMsg("build"))
}

test("Validate Compose field 'container_name:' results in correct exception thrown and error message printing") {
val composeMock = getComposeFileMock()
val composeFilePath = getClass.getResource("unsupported_field_container_name.yml").getPath
val composeYaml = composeMock.readComposeFile(composeFilePath)

val thrown = intercept[ComposeFileFormatException] {
composeMock.processCustomTags(null, null, composeYaml)
}
assert(thrown.getMessage == getUnsupportedFieldErrorMsg("container_name"))
}

test("Validate Compose field 'extends:' results in correct exception thrown and error message printing") {
val composeMock = getComposeFileMock()
val composeFilePath = getClass.getResource("unsupported_field_extends.yml").getPath
val composeYaml = composeMock.readComposeFile(composeFilePath)

val thrown = intercept[ComposeFileFormatException] {
composeMock.processCustomTags(null, null, composeYaml)
}
assert(thrown.getMessage == getUnsupportedFieldErrorMsg("extends"))
}

test("Validate Compose <localBuild> tag results in 'build' image source and custom tag is removed") {
val composeMock = getComposeFileMock(serviceName = "nomatch")
val composeFilePath = getClass.getResource("localbuild_tag.yml").getPath
Expand Down

0 comments on commit 255df97

Please sign in to comment.