{"action":"created","comment":{"url":"https://api.github.com/repos/broadinstitute/cromwell/pulls/comments/38549277","id":38549277,"diff_hunk":"@@ -177,125 +199,200 @@ case class WorkflowActor(workflow: WorkflowDescriptor,\n       if (toState.isTerminal) setTimer(s\"WorkflowActor termination message: $tag\", Terminate, AkkaTimeout, DontRepeatTimer)\n   }\n \n-  private def persistStatus(call: Call, callStatus: CallStatus): Future[Unit] = {\n-    persistStatus(Iterable(call), callStatus)\n+  private def persistStatus(key: ExecutionStoreKey, callStatus: CallStatus): Future[Unit] = {\n+    persistStatus(Iterable(key), callStatus)\n   }\n \n-  private def persistStatus(calls: Traversable[Call], callStatus: CallStatus): Future[Unit] = {\n-    executionStore ++= calls.map { _ -> callStatus}.toMap\n-    val callFqns = calls.map(_.fullyQualifiedName)\n-    log.info(s\"$tag persisting status of calls ${callFqns.mkString(\", \")} to $callStatus.\")\n-    dataAccess.setStatus(workflow.id, callFqns, callStatus)\n+  private def persistStatus(key: Traversable[ExecutionStoreKey], callStatus: CallStatus): Future[Unit] = {\n+    executionStore ++= key map { _ -> callStatus }\n+\n+    key foreach { k =>\n+      val indexLog = k.index.map(i => s\" (shard $i)\").getOrElse(\"\")\n+      log.info(s\"$tag persisting status of ${k.scope.fullyQualifiedName}$indexLog to $callStatus.\")\n+    }\n+\n+    dataAccess.setStatus(workflow.id, key map { k => ExecutionDatabaseKey(k.scope.fullyQualifiedName, k.index) }, callStatus)\n   }\n \n-  private def awaitCallComplete(call: Call, outputs: CallOutputs): Try[Unit] = {\n-    val callFuture = handleCallCompleted(call, outputs)\n+  private def awaitCallComplete(key: OutputKey, outputs: CallOutputs): Try[Unit] = {\n+    val callFuture = handleCallCompleted(key, outputs)\n     Await.ready(callFuture, AkkaTimeout)\n     callFuture.value.get\n   }\n \n-  private def handleCallCompleted(call: Call, outputs: CallOutputs): Future[Unit] = {\n-    log.info(s\"$tag handling completion of call '${call.fullyQualifiedName}'.\")\n+  private def handleCallCompleted(key: OutputKey, outputs: CallOutputs): Future[Unit] = {\n+    log.info(s\"$tag handling completion of call '${key.scope.fullyQualifiedName}'.\")\n     for {\n-      _ <- dataAccess.setOutputs(workflow.id, call, outputs)\n-      _ <- persistStatus(call, ExecutionStatus.Done)\n-    } yield ()\n+      _ <- dataAccess.setOutputs(workflow.id, key, outputs)\n+      _ <- persistStatus(key, ExecutionStatus.Done)\n+    } yield()\n   }\n \n-  private def startActor(call: Call, locallyQualifiedInputs: Map[String, WdlValue]): Unit = {\n+  private def startActor(callKey: CallKey, locallyQualifiedInputs: Map[String, WdlValue]): Unit = {\n     if (locallyQualifiedInputs.nonEmpty) {\n-      log.info(s\"$tag inputs for call '${call.fullyQualifiedName}':\")\n+      log.info(s\"$tag inputs for call '${callKey.scope.fullyQualifiedName}':\")\n       locallyQualifiedInputs foreach { input =>\n         log.info(s\"$tag     ${input._1} -> ${input._2}\")\n       }\n     } else {\n-      log.info(s\"$tag no inputs for call '${call.fullyQualifiedName}'\")\n+      log.info(s\"$tag no inputs for call '${callKey.scope.fullyQualifiedName}'\")\n     }\n \n-    val callActorProps = CallActor.props(call, locallyQualifiedInputs, backend, workflow)\n-    val callActor = context.actorOf(callActorProps, s\"CallActor-${workflow.id}-${call.name}\")\n+    val callActorProps = CallActor.props(callKey, locallyQualifiedInputs, backend, workflow)\n+    val callActor = context.actorOf(callActorProps)\n     callActor ! CallActor.Start\n-    log.info(s\"$tag created call actor for ${call.fullyQualifiedName}.\")\n+    log.info(s\"$tag created call actor for ${callKey.scope.fullyQualifiedName}.\")\n   }\n \n-  /**\n-   * Start all calls which are currently in state `NotStarted` and whose prerequisites are all `Done`,\n-   * i.e. the calls which should now be eligible to run.  Update status to `Starting` in DataAccess and\n-   * start Call actors.  Return a Future of Iterable[Unit] to allow the caller to compose or block.\n-   */\n-  type CallAndInputs = (Call, Map[String, WdlValue])\n-  private def tryStartingRunnableCalls(): Try[Any] = {\n-\n-    def isRunnable(call: Call) = call.prerequisiteCalls(workflow.namespace).forall(executionStore.get(_).get == ExecutionStatus.Done)\n-    /**\n-     * Start all calls which are currently in state `NotStarted` and whose prerequisites are all `Done`,\n-     * i.e. the calls which should now be eligible to run.\n-     */\n-    def findRunnableCalls: Iterable[Call] = {\n-      for {\n-        callEntry <- executionStore if callEntry._2 == ExecutionStatus.NotStarted\n-        call = callEntry._1 if isRunnable(call)\n-      } yield call\n+  private def tryStartingRunnableCalls(): Try[Traversable[ExecutionStoreKey]] = {\n+\n+    def upstreamEntries(entry: ExecutionStoreKey, prerequisiteScope: Scope): Seq[ExecutionStoreEntry] = {\n+      prerequisiteScope.closestCommonAncestor(entry.scope) match {\n+        /**\n+         * If this entry refers to a Scope which has a common ancestor with prerequisiteScope\n+         * and that common ancestor is a Scatter block, then find the shard with the same index\n+         * as 'entry'.  In other words, if you're in the same scatter block as your pre-requisite\n+         * scope, then depend on the shard (with same index).\n+         *\n+         * NOTE: this algorithm was designed for ONE-LEVEL of scattering and probably does not\n+         * work as-is for nested scatter blocks\n+         */\n+        case Some(ancestor: Scatter) =>\n+          executionStore filter { case(k, _) => k.scope == prerequisiteScope && k.index == entry.index } toSeq\n+\n+        /**\n+         * Otherwise, simply refer to the entry the collector entry.  This means that 'entry' depends\n+         * on every shard of the pre-requisite scope to finish.\n+         */\n+        case _ =>\n+          executionStore filter { case(k, _) => k.scope == prerequisiteScope && k.index.isEmpty } toSeq\n+      }\n     }\n \n-    val runnableCalls = findRunnableCalls\n-    if (runnableCalls.isEmpty) {\n-      log.info(s\"$tag no runnable calls to start.\")\n-      Success(())\n-    } else {\n-      log.info(s\"$tag starting calls: \" + runnableCalls.map {_.fullyQualifiedName}.toSeq.sorted.mkString(\", \"))\n-      val futureCallsAndInputs = for {\n-        _ <- persistStatus(runnableCalls, ExecutionStatus.Starting)\n-        allInputs <- Future.sequence(runnableCalls map fetchLocallyQualifiedInputs)\n-      } yield runnableCalls zip allInputs\n-      Await.ready(futureCallsAndInputs, AkkaTimeout)\n-      futureCallsAndInputs.value.get match {\n-        case Success(callsAndInputs) =>\n-          callsAndInputs foreach { case (call, inputs) => startActor(call, inputs) }\n-          Success(())\n-        case failure => failure\n+    def arePrerequisitesDone(key: ExecutionStoreKey): Boolean = {\n+      val upstream = key.scope.prerequisiteScopes.map(s => upstreamEntries(key, s))\n+      val downstream = key match {\n+        case collector: CollectorKey => findShardEntries(collector)\n+        case _ => Nil\n       }\n+      val dependencies = upstream.flatten ++ downstream\n+      val dependenciesResolved = dependencies.isEmpty || dependencies.forall(isDone)\n+\n+      /**\n+       * We need to make sure that all prerequisiteScopes have been resolved to some entry before going forward.\n+       * If a scope cannot be resolved it may be because it is in a scatter that has not been populated yet,\n+       * therefore there is no entry in the executionStore for this scope.\n+       * If that's the case this prerequisiteScope has not been run yet, hence the (upstream forall {_.nonEmpty})\n+       */\n+      (upstream forall { _.nonEmpty }) && dependenciesResolved\n+    }\n+\n+    def isRunnable(entry: ExecutionStoreEntry) = {\n+      val (key, status) = entry\n+      status == ExecutionStatus.NotStarted && arePrerequisitesDone(key)\n+    }\n+\n+    def findRunnableEntries: Traversable[ExecutionStoreEntry] = executionStore filter isRunnable\n+\n+    val runnableEntries = findRunnableEntries\n+\n+    val runnableCalls = runnableEntries collect { case(k: CallKey, v) => k.scope }\n+    if (runnableCalls.nonEmpty)\n+      log.info(s\"$tag starting calls: \" + runnableCalls.map(_.fullyQualifiedName).toSeq.sorted.mkString(\", \"))\n+\n+    val entries: Traversable[Try[Iterable[ExecutionStoreKey]]] = runnableEntries map {\n+      case (k: ScatterKey, v) => processRunnableScatter(k, v)\n+      case (k: CollectorKey, v) => processRunnableCollector(k)\n+      case (k: CallKey, v) => processRunnableCall(k, v)\n+      case (k, v) =>\n+        val message = s\"$tag Unknown entry in execution store:\\nKEY: $k\\nVALUE:$v\"\n+        log.error(message)\n+        Failure(new UnsupportedOperationException(message))\n+    }\n+\n+    entries.find(_.isFailure) match {\n+      case Some(failure) => failure\n+      case _ => Success(entries.flatMap(_.get))\n     }\n   }\n-  /* Return a Markdown table of all entries in the database */\n-  private def symbolsMarkdownTable(): Option[String] = {\n-    val header = Seq(\"SCOPE\",\"NAME\",\"I/O\",\"TYPE\",\"VALUE\")\n-    val maxColChars = 100\n-    val rows = fetchAllEntries map { entry =>\n-      val valueString = entry.wdlValue match {\n-        case Some(value) => s\"(${value.wdlType.toWdlString}) \" + value.valueString\n-        case _ => \"\"\n-      }\n-      Seq(\n-        entry.key.scope,\n-        entry.key.name,\n-        if (entry.key.input) \"INPUT\" else \"OUTPUT\",\n-        entry.wdlType.toWdlString,\n-        if (valueString.length > maxColChars) valueString.substring(0, maxColChars) else valueString\n-      )\n-    } toSeq\n-\n-    rows match {\n-      case r: Seq[Seq[String]] if r.isEmpty => None\n-      case _ => Some(TerminalUtil.mdTable(rows, header))\n+\n+  private def lookupNamespace(name: String): Try[WdlNamespace] = {\n+    workflow.namespace.namespaces find { _.importedAs.contains(name) } match {\n+      case Some(x) => Success(x)\n+      case _ => Failure(new WdlExpressionException(s\"Could not resolve $name as a namespace\"))\n     }\n   }\n \n-  def fetchLocallyQualifiedInputs(call: Call): Future[Map[String, WdlValue]] = {\n-    // TODO: This assumes that each Call has a parent that's a Workflow, but with scatter-gather that might not be the case \n-    val parentWorkflow = call.parent map { _.asInstanceOf[Workflow] } getOrElse {\n-      throw new WdlExpressionException(\"Expecting 'call' to have a 'workflow' parent.\")\n+  private def lookupCall(key: ExecutionStoreKey, workflow: Workflow)(name: String): Try[WdlObject] = {\n+    workflow.calls find { _.name == name } match {\n+      case Some(matchedCall) =>\n+        /**\n+         * After matching the Call, this determines if the `key` depends on a single shard\n+         * of a scatter'd job or if it depends on the whole thing.  Right now, the heuristic\n+         * is \"If we're both in a scatter block together, then I depend on a shard.  If not,\n+         * I depend on the collected value\"\n+         *\n+         * TODO: nested-scatter - this will likely not be sufficient for nested scatters\n+         */\n+        val index: ExecutionIndex = matchedCall.closestCommonAncestor(key.scope) flatMap {\n+          case s: Scatter => key.index\n+          case _ => None\n+        }\n+        fetchCallOutputEntries(findOutputKey(matchedCall, index) getOrElse {\n+          throw new WdlExpressionException(s\"Could not find a callKey for name '${matchedCall.name}'\")\n+        })\n+      case None => Failure(new WdlExpressionException(s\"Could not find a call with name '$name'\"))\n+    }\n+  }\n+\n+  private def lookupDeclaration(workflow: Workflow)(name: String): Try[WdlValue] = {\n+    workflow.declarations find { _.name == name } match {\n+      case Some(declaration) => fetchFullyQualifiedName(declaration.fullyQualifiedName)\n+      case None => Failure(new WdlExpressionException(s\"Could not find a declaration with name '$name'\"))\n     }\n+  }\n \n-    object CallInputWdlFunctions extends WdlFunctions {\n-      def getFunction(name: String): WdlFunction = {\n-        throw new WdlExpressionException(\"TODO: Some functions may be allowed in this context\")\n+  private def lookupScatterVariable(callKey: CallKey, workflow: Workflow)(name: String): Try[WdlValue] = {\n+    val scatterBlock = callKey.scope.ancestry collect { case s: Scatter if s.item == name => s } headOption\n+    val scatterCollection = scatterBlock map { s =>\n+      s.collection.evaluate(scatterCollectionLookupFunction(workflow, callKey), new NoFunctions) match {\n+        case Success(v: WdlArray) if callKey.index.isDefined =>\n+          if (v.value.isDefinedAt(callKey.index.get))\n+            Success(v.value(callKey.index.get))\n+          else\n+            Failure(new WdlExpressionException(s\"Index ${callKey.index.get} out of bounds for $name array.\"))\n+        case _ => Failure(new WdlExpressionException(s\"$name did not evaluate to a WdlArray\"))","path":"src/main/scala/cromwell/engine/workflow/WorkflowActor.scala","position":417,"original_position":417,"commit_id":"277c951d8b19f14e1040bc6bbec34e412ab01536","original_commit_id":"277c951d8b19f14e1040bc6bbec34e412ab01536","user":{"login":"mcovarr","id":10790523,"avatar_url":"https://avatars.githubusercontent.com/u/10790523?v=3","gravatar_id":"","url":"https://api.github.com/users/mcovarr","html_url":"https://github.com/mcovarr","followers_url":"https://api.github.com/users/mcovarr/followers","following_url":"https://api.github.com/users/mcovarr/following{/other_user}","gists_url":"https://api.github.com/users/mcovarr/gists{/gist_id}","starred_url":"https://api.github.com/users/mcovarr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mcovarr/subscriptions","organizations_url":"https://api.github.com/users/mcovarr/orgs","repos_url":"https://api.github.com/users/mcovarr/repos","events_url":"https://api.github.com/users/mcovarr/events{/privacy}","received_events_url":"https://api.github.com/users/mcovarr/received_events","type":"User","site_admin":false},"body":"doesn't seem like the right error if `Success(v: WdlArray) if !callKey.index.isDefined`","created_at":"2015-09-02T15:51:59Z","updated_at":"2015-09-02T15:51:59Z","html_url":"https://github.com/broadinstitute/cromwell/pull/165#discussion_r38549277","pull_request_url":"https://api.github.com/repos/broadinstitute/cromwell/pulls/165","_links":{"self":{"href":"https://api.github.com/repos/broadinstitute/cromwell/pulls/comments/38549277"},"html":{"href":"https://github.com/broadinstitute/cromwell/pull/165#discussion_r38549277"},"pull_request":{"href":"https://api.github.com/repos/broadinstitute/cromwell/pulls/165"}}},"pull_request":{"url":"https://api.github.com/repos/broadinstitute/cromwell/pulls/165","id":43783236,"html_url":"https://github.com/broadinstitute/cromwell/pull/165","diff_url":"https://github.com/broadinstitute/cromwell/pull/165.diff","patch_url":"https://github.com/broadinstitute/cromwell/pull/165.patch","issue_url":"https://api.github.com/repos/broadinstitute/cromwell/issues/165","number":165,"state":"open","locked":false,"title":"Scatter/Gather support","user":{"login":"scottfrazer","id":58551,"avatar_url":"https://avatars.githubusercontent.com/u/58551?v=3","gravatar_id":"","url":"https://api.github.com/users/scottfrazer","html_url":"https://github.com/scottfrazer","followers_url":"https://api.github.com/users/scottfrazer/followers","following_url":"https://api.github.com/users/scottfrazer/following{/other_user}","gists_url":"https://api.github.com/users/scottfrazer/gists{/gist_id}","starred_url":"https://api.github.com/users/scottfrazer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/scottfrazer/subscriptions","organizations_url":"https://api.github.com/users/scottfrazer/orgs","repos_url":"https://api.github.com/users/scottfrazer/repos","events_url":"https://api.github.com/users/scottfrazer/events{/privacy}","received_events_url":"https://api.github.com/users/scottfrazer/received_events","type":"User","site_admin":false},"body":"","created_at":"2015-08-31T16:37:03Z","updated_at":"2015-09-02T15:51:59Z","closed_at":null,"merged_at":null,"merge_commit_sha":"bdcd4febd3aa2edd35b95143dc5f7d197e0b6f8e","assignee":{"login":"mcovarr","id":10790523,"avatar_url":"https://avatars.githubusercontent.com/u/10790523?v=3","gravatar_id":"","url":"https://api.github.com/users/mcovarr","html_url":"https://github.com/mcovarr","followers_url":"https://api.github.com/users/mcovarr/followers","following_url":"https://api.github.com/users/mcovarr/following{/other_user}","gists_url":"https://api.github.com/users/mcovarr/gists{/gist_id}","starred_url":"https://api.github.com/users/mcovarr/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mcovarr/subscriptions","organizations_url":"https://api.github.com/users/mcovarr/orgs","repos_url":"https://api.github.com/users/mcovarr/repos","events_url":"https://api.github.com/users/mcovarr/events{/privacy}","received_events_url":"https://api.github.com/users/mcovarr/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/broadinstitute/cromwell/pulls/165/commits","review_comments_url":"https://api.github.com/repos/broadinstitute/cromwell/pulls/165/comments","review_comment_url":"https://api.github.com/repos/broadinstitute/cromwell/pulls/comments{/number}","comments_url":"https://api.github.com/repos/broadinstitute/cromwell/issues/165/comments","statuses_url":"https://api.github.com/repos/broadinstitute/cromwell/statuses/277c951d8b19f14e1040bc6bbec34e412ab01536","head":{"label":"broadinstitute:scatter-gather","ref":"scatter-gather","sha":"277c951d8b19f14e1040bc6bbec34e412ab01536","user":{"login":"broadinstitute","id":393552,"avatar_url":"https://avatars.githubusercontent.com/u/393552?v=3","gravatar_id":"","url":"https://api.github.com/users/broadinstitute","html_url":"https://github.com/broadinstitute","followers_url":"https://api.github.com/users/broadinstitute/followers","following_url":"https://api.github.com/users/broadinstitute/following{/other_user}","gists_url":"https://api.github.com/users/broadinstitute/gists{/gist_id}","starred_url":"https://api.github.com/users/broadinstitute/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/broadinstitute/subscriptions","organizations_url":"https://api.github.com/users/broadinstitute/orgs","repos_url":"https://api.github.com/users/broadinstitute/repos","events_url":"https://api.github.com/users/broadinstitute/events{/privacy}","received_events_url":"https://api.github.com/users/broadinstitute/received_events","type":"Organization","site_admin":false},"repo":{"id":34136406,"name":"cromwell","full_name":"broadinstitute/cromwell","owner":{"login":"broadinstitute","id":393552,"avatar_url":"https://avatars.githubusercontent.com/u/393552?v=3","gravatar_id":"","url":"https://api.github.com/users/broadinstitute","html_url":"https://github.com/broadinstitute","followers_url":"https://api.github.com/users/broadinstitute/followers","following_url":"https://api.github.com/users/broadinstitute/following{/other_user}","gists_url":"https://api.github.com/users/broadinstitute/gists{/gist_id}","starred_url":"https://api.github.com/users/broadinstitute/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/broadinstitute/subscriptions","organizations_url":"https://api.github.com/users/broadinstitute/orgs","repos_url":"https://api.github.com/users/broadinstitute/repos","events_url":"https://api.github.com/users/broadinstitute/events{/privacy}","received_events_url":"https://api.github.com/users/broadinstitute/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/broadinstitute/cromwell","description":"Workflow Execution Engine using WDL","fork":false,"url":"https://api.github.com/repos/broadinstitute/cromwell","forks_url":"https://api.github.com/repos/broadinstitute/cromwell/forks","keys_url":"https://api.github.com/repos/broadinstitute/cromwell/keys{/key_id}","collaborators_url":"https://api.github.com/repos/broadinstitute/cromwell/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/broadinstitute/cromwell/teams","hooks_url":"https://api.github.com/repos/broadinstitute/cromwell/hooks","issue_events_url":"https://api.github.com/repos/broadinstitute/cromwell/issues/events{/number}","events_url":"https://api.github.com/repos/broadinstitute/cromwell/events","assignees_url":"https://api.github.com/repos/broadinstitute/cromwell/assignees{/user}","branches_url":"https://api.github.com/repos/broadinstitute/cromwell/branches{/branch}","tags_url":"https://api.github.com/repos/broadinstitute/cromwell/tags","blobs_url":"https://api.github.com/repos/broadinstitute/cromwell/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/broadinstitute/cromwell/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/broadinstitute/cromwell/git/refs{/sha}","trees_url":"https://api.github.com/repos/broadinstitute/cromwell/git/trees{/sha}","statuses_url":"https://api.github.com/repos/broadinstitute/cromwell/statuses/{sha}","languages_url":"https://api.github.com/repos/broadinstitute/cromwell/languages","stargazers_url":"https://api.github.com/repos/broadinstitute/cromwell/stargazers","contributors_url":"https://api.github.com/repos/broadinstitute/cromwell/contributors","subscribers_url":"https://api.github.com/repos/broadinstitute/cromwell/subscribers","subscription_url":"https://api.github.com/repos/broadinstitute/cromwell/subscription","commits_url":"https://api.github.com/repos/broadinstitute/cromwell/commits{/sha}","git_commits_url":"https://api.github.com/repos/broadinstitute/cromwell/git/commits{/sha}","comments_url":"https://api.github.com/repos/broadinstitute/cromwell/comments{/number}","issue_comment_url":"https://api.github.com/repos/broadinstitute/cromwell/issues/comments{/number}","contents_url":"https://api.github.com/repos/broadinstitute/cromwell/contents/{+path}","compare_url":"https://api.github.com/repos/broadinstitute/cromwell/compare/{base}...{head}","merges_url":"https://api.github.com/repos/broadinstitute/cromwell/merges","archive_url":"https://api.github.com/repos/broadinstitute/cromwell/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/broadinstitute/cromwell/downloads","issues_url":"https://api.github.com/repos/broadinstitute/cromwell/issues{/number}","pulls_url":"https://api.github.com/repos/broadinstitute/cromwell/pulls{/number}","milestones_url":"https://api.github.com/repos/broadinstitute/cromwell/milestones{/number}","notifications_url":"https://api.github.com/repos/broadinstitute/cromwell/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/broadinstitute/cromwell/labels{/name}","releases_url":"https://api.github.com/repos/broadinstitute/cromwell/releases{/id}","created_at":"2015-04-17T19:39:36Z","updated_at":"2015-08-24T15:16:51Z","pushed_at":"2015-09-02T15:47:19Z","git_url":"git://github.com/broadinstitute/cromwell.git","ssh_url":"git@github.com:broadinstitute/cromwell.git","clone_url":"https://github.com/broadinstitute/cromwell.git","svn_url":"https://github.com/broadinstitute/cromwell","homepage":"http://broadinstitute.github.io/cromwell/","size":5725,"stargazers_count":7,"watchers_count":7,"language":"Scala","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":0,"mirror_url":null,"open_issues_count":4,"forks":0,"open_issues":4,"watchers":7,"default_branch":"master"}},"base":{"label":"broadinstitute:develop","ref":"develop","sha":"26c20a03b0de497dcc07c6434648ba264376f4a7","user":{"login":"broadinstitute","id":393552,"avatar_url":"https://avatars.githubusercontent.com/u/393552?v=3","gravatar_id":"","url":"https://api.github.com/users/broadinstitute","html_url":"https://github.com/broadinstitute","followers_url":"https://api.github.com/users/broadinstitute/followers","following_url":"https://api.github.com/users/broadinstitute/following{/other_user}","gists_url":"https://api.github.com/users/broadinstitute/gists{/gist_id}","starred_url":"https://api.github.com/users/broadinstitute/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/broadinstitute/subscriptions","organizations_url":"https://api.github.com/users/broadinstitute/orgs","repos_url":"https://api.github.com/users/broadinstitute/repos","events_url":"https://api.github.com/users/broadinstitute/events{/privacy}","received_events_url":"https://api.github.com/users/broadinstitute/received_events","type":"Organization","site_admin":false},"repo":{"id":34136406,"name":"cromwell","full_name":"broadinstitute/cromwell","owner":{"login":"broadinstitute","id":393552,"avatar_url":"https://avatars.githubusercontent.com/u/393552?v=3","gravatar_id":"","url":"https://api.github.com/users/broadinstitute","html_url":"https://github.com/broadinstitute","followers_url":"https://api.github.com/users/broadinstitute/followers","following_url":"https://api.github.com/users/broadinstitute/following{/other_user}","gists_url":"https://api.github.com/users/broadinstitute/gists{/gist_id}","starred_url":"https://api.github.com/users/broadinstitute/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/broadinstitute/subscriptions","organizations_url":"https://api.github.com/users/broadinstitute/orgs","repos_url":"https://api.github.com/users/broadinstitute/repos","events_url":"https://api.github.com/users/broadinstitute/events{/privacy}","received_events_url":"https://api.github.com/users/broadinstitute/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/broadinstitute/cromwell","description":"Workflow Execution Engine using WDL","fork":false,"url":"https://api.github.com/repos/broadinstitute/cromwell","forks_url":"https://api.github.com/repos/broadinstitute/cromwell/forks","keys_url":"https://api.github.com/repos/broadinstitute/cromwell/keys{/key_id}","collaborators_url":"https://api.github.com/repos/broadinstitute/cromwell/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/broadinstitute/cromwell/teams","hooks_url":"https://api.github.com/repos/broadinstitute/cromwell/hooks","issue_events_url":"https://api.github.com/repos/broadinstitute/cromwell/issues/events{/number}","events_url":"https://api.github.com/repos/broadinstitute/cromwell/events","assignees_url":"https://api.github.com/repos/broadinstitute/cromwell/assignees{/user}","branches_url":"https://api.github.com/repos/broadinstitute/cromwell/branches{/branch}","tags_url":"https://api.github.com/repos/broadinstitute/cromwell/tags","blobs_url":"https://api.github.com/repos/broadinstitute/cromwell/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/broadinstitute/cromwell/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/broadinstitute/cromwell/git/refs{/sha}","trees_url":"https://api.github.com/repos/broadinstitute/cromwell/git/trees{/sha}","statuses_url":"https://api.github.com/repos/broadinstitute/cromwell/statuses/{sha}","languages_url":"https://api.github.com/repos/broadinstitute/cromwell/languages","stargazers_url":"https://api.github.com/repos/broadinstitute/cromwell/stargazers","contributors_url":"https://api.github.com/repos/broadinstitute/cromwell/contributors","subscribers_url":"https://api.github.com/repos/broadinstitute/cromwell/subscribers","subscription_url":"https://api.github.com/repos/broadinstitute/cromwell/subscription","commits_url":"https://api.github.com/repos/broadinstitute/cromwell/commits{/sha}","git_commits_url":"https://api.github.com/repos/broadinstitute/cromwell/git/commits{/sha}","comments_url":"https://api.github.com/repos/broadinstitute/cromwell/comments{/number}","issue_comment_url":"https://api.github.com/repos/broadinstitute/cromwell/issues/comments{/number}","contents_url":"https://api.github.com/repos/broadinstitute/cromwell/contents/{+path}","compare_url":"https://api.github.com/repos/broadinstitute/cromwell/compare/{base}...{head}","merges_url":"https://api.github.com/repos/broadinstitute/cromwell/merges","archive_url":"https://api.github.com/repos/broadinstitute/cromwell/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/broadinstitute/cromwell/downloads","issues_url":"https://api.github.com/repos/broadinstitute/cromwell/issues{/number}","pulls_url":"https://api.github.com/repos/broadinstitute/cromwell/pulls{/number}","milestones_url":"https://api.github.com/repos/broadinstitute/cromwell/milestones{/number}","notifications_url":"https://api.github.com/repos/broadinstitute/cromwell/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/broadinstitute/cromwell/labels{/name}","releases_url":"https://api.github.com/repos/broadinstitute/cromwell/releases{/id}","created_at":"2015-04-17T19:39:36Z","updated_at":"2015-08-24T15:16:51Z","pushed_at":"2015-09-02T15:47:19Z","git_url":"git://github.com/broadinstitute/cromwell.git","ssh_url":"git@github.com:broadinstitute/cromwell.git","clone_url":"https://github.com/broadinstitute/cromwell.git","svn_url":"https://github.com/broadinstitute/cromwell","homepage":"http://broadinstitute.github.io/cromwell/","size":5725,"stargazers_count":7,"watchers_count":7,"language":"Scala","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":true,"forks_count":0,"mirror_url":null,"open_issues_count":4,"forks":0,"open_issues":4,"watchers":7,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/broadinstitute/cromwell/pulls/165"},"html":{"href":"https://github.com/broadinstitute/cromwell/pull/165"},"issue":{"href":"https://api.github.com/repos/broadinstitute/cromwell/issues/165"},"comments":{"href":"https://api.github.com/repos/broadinstitute/cromwell/issues/165/comments"},"review_comments":{"href":"https://api.github.com/repos/broadinstitute/cromwell/pulls/165/comments"},"review_comment":{"href":"https://api.github.com/repos/broadinstitute/cromwell/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/broadinstitute/cromwell/pulls/165/commits"},"statuses":{"href":"https://api.github.com/repos/broadinstitute/cromwell/statuses/277c951d8b19f14e1040bc6bbec34e412ab01536"}}}}