{"action":"opened","issue":{"url":"https://api.github.com/repos/sbt/sbt/issues/2879","repository_url":"https://api.github.com/repos/sbt/sbt","labels_url":"https://api.github.com/repos/sbt/sbt/issues/2879/labels{/name}","comments_url":"https://api.github.com/repos/sbt/sbt/issues/2879/comments","events_url":"https://api.github.com/repos/sbt/sbt/issues/2879/events","html_url":"https://github.com/sbt/sbt/issues/2879","id":197699562,"number":2879,"title":"Feature request: fetch/launch artifact api (à la Coursier)","user":{"login":"olafurpg","id":1408093,"avatar_url":"https://avatars.githubusercontent.com/u/1408093?v=3","gravatar_id":"","url":"https://api.github.com/users/olafurpg","html_url":"https://github.com/olafurpg","followers_url":"https://api.github.com/users/olafurpg/followers","following_url":"https://api.github.com/users/olafurpg/following{/other_user}","gists_url":"https://api.github.com/users/olafurpg/gists{/gist_id}","starred_url":"https://api.github.com/users/olafurpg/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/olafurpg/subscriptions","organizations_url":"https://api.github.com/users/olafurpg/orgs","repos_url":"https://api.github.com/users/olafurpg/repos","events_url":"https://api.github.com/users/olafurpg/events{/privacy}","received_events_url":"https://api.github.com/users/olafurpg/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2016-12-27T12:58:40Z","updated_at":"2016-12-27T12:58:40Z","closed_at":null,"body":"## Problem\r\n\r\nWhen writing an sbt build or plugin, fetching an artifact coordinate (moduleid) and then launching a main class from that classpath is currently difficult. It would be nice if it was as simple as using the [coursier command line interface](https://github.com/alexarchambault/coursier#command-line-1)\r\n\r\n```bash\r\n$ ./coursier fetch org.apache.spark:spark-sql_2.11:1.6.1\r\n$ ./coursier launch com.lihaoyi:ammonite_2.11.8:0.7.0\r\n$ ./coursier launch com.lihaoyi:ammonite_2.11.8:0.7.0 # jars are cached\r\n```\r\n\r\n### Potential use-cases\r\n\r\n- wrap a command line tool into an sbt plugin, for example [scalafmt](https://olafurpg.github.io/scalafmt/#sbt)\r\n- manually add a compiler plugin to `scalacOptions` with `-Xplugin:/path/to/jar`, for example scoverage and scalafix. I can't say why scoverage favors this approach over `addCompilerPlugin`. In scalafix, I bumped into\r\n  1. problems because the scalafix compiler plugin has dependencies\r\n  2. \"ignoring duplicate plugin\" warnings when I used `addCompilerPlugin`\r\n  3. problems when I wanted to optionally enable the sbt plugin if `scalafixEnabled in Global := true` (same is true for `scoverageEnabled`).\r\n\r\nNice-to-have additional features on top of plain fetch/launch:\r\n- classpath is cached between `launch` invocations to benefit from JIT\r\n- custom in/out/err streams\r\n- custom working directory (e.g., depending from which project the command/task was executed)\r\n\r\n### Explored alternatives\r\n To my best knowledge, the idiomatic way to accomplish the same in sbt is to use `libraryDependencies += ModuleId` and then call `update.value`. You can use this trick in several ways and each of them have some caveats:\r\n\r\n- build project in default configuration. Problems\r\n  1. the dependency is a dependency to the project's application\r\n  2. you need to support the defined scalaVersion in that project causing issues like \r\nhttps://github.com/sbt/sbt/issues/2786\r\n  3. it's super slow (as in takes minutes) when testing on large cross-built (Scala.js) projects with `-SNAPSHOT` versions because you need to resolve the same locally published `-SNAPSHOT` version in every single project.\r\n- build project in custom configuration. Problems:\r\n  1. Problems 2 and 3 still apply from before.\r\n  2. it requires quite a bit of ceremony to work (e.g., `configurations += config(\"foo\").hide`).\r\n- synthetic project (>0.13.13 only). Scalafmt and scalafix use this approach. Problems:\r\n  1. you're still at the mercy of what `++$SCALA_VERSION` (https://github.com/olafurpg/scalafmt/issues/641) or `fork in ThisBuild` (https://github.com/olafurpg/scalafmt/issues/654) settings the user defines.\r\n  2. requires quite a bit of ceremony, esp. if your cross-build to multiple scala versions.\r\n  3. synthetic projects are silently ignored in sbt <0.13.13 causing cryptic error messages\r\n\r\nAlternatively, I could use the coursier api to fetch and launch the jars myself. The downside to this is that\r\n1. I still need to implement the `launch` (+ nice-to-have features) since the coursier cli is 2.11 only and\r\n2. coursier pulls in dependencies like scalaz which can conflicts with other libraries on the build classpath.\r\n\r\ncc/ @sjrd @alexarchambault "}}
{"actor":{"display_login":"olafurpg"}}