-
Notifications
You must be signed in to change notification settings - Fork 303
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enhance bootstrap launcher to download artifacts using global credentials. #1991
Enhance bootstrap launcher to download artifacts using global credentials. #1991
Conversation
1cf70ad
to
d738f5c
Compare
0fd2afe
to
1162d51
Compare
Thanks a lot for taking a cut at this! About how to add this, I think your point 2. should be the way to go, in the long term. The mirror logic is already implemented this way, via I guess we can leave it as is in a first time (so your point 1., and the current state of the PR), and work on making this PR mergeable. And at a later point in time, either find a way to use the Java-based In order to run the integration tests you added, we need to start an authenticated mirror repository, right? Do you think you can add that? (I've got to run right now, but there are examples of Sonatype instances being spawn in the code, I can point them later today, if needed). |
Thanks for your reply. I agree. Implementation (1) is a subset and requirement for implementation (2) so I thought it a reasonable place to start. In fact I had ported more of the code than is included in the pull request, but chopped it down to what was absolutely necessary. I'll have a look at spinning up a Sonatype instance in the integration test. I had seen logging for this in the test suite, so I'm sure I can find an example. I developed the change against an Artifactory instance I spun up in a container so, I expect integrating with an in-memory repository should be straight forward. Thanks for the suggestion. |
Spawning an Artifactory would be fine too. A Sonatype server is spawned via docker around here for example. By the way, if it's more practical, I think it should be do-able to write the tests in Scala (while keeping the main module in Java). And |
00ec61f
to
0540311
Compare
I found I updated What do you think of the updated pull request? |
Yes and it should be possible to convert the tests. Let me update the PR... |
c1fe79b
to
4d48fbd
Compare
Hi @alexarchambault. The Please let me know if there's anything else. Thanks |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @greg-a-atkinson!
Looks good overall, I only left some minor comments.
build.sbt
Outdated
libraryDependencies += Deps.collectionCompat % Test, | ||
libraryDependencies += Deps.java8Compat % Test, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NIT Let's merge those:
libraryDependencies += Deps.collectionCompat % Test, | |
libraryDependencies += Deps.java8Compat % Test, | |
libraryDependencies ++= Seq( | |
Deps.collectionCompat % Test, | |
Deps.java8Compat % Test | |
), |
@@ -0,0 +1,105 @@ | |||
package coursier.bootstrap.launcher; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NIT
package coursier.bootstrap.launcher; | |
package coursier.bootstrap.launcher |
val remoteUrls = Seq( | ||
new URL("https://repo1.maven.org/maven2/com/chuusai/shapeless_2.12/2.3.3/shapeless_2.12-2.3.3.jar") | ||
) | ||
val localUrls = Download.getLocalURLs(remoteUrls.asJava).asScala; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
val localUrls = Download.getLocalURLs(remoteUrls.asJava).asScala; | |
val localUrls = Download.getLocalURLs(remoteUrls.asJava).asScala |
project/Deps.scala
Outdated
@@ -20,6 +21,7 @@ object Deps { | |||
def caseApp = "com.github.alexarchambault" %% "case-app" % "2.0.0" | |||
def catsCore = "org.typelevel" %% "cats-core" % "2.2.0" | |||
def collectionCompat = "org.scala-lang.modules" %% "scala-collection-compat" % versions.collectionCompat | |||
def java8Compat = "org.scala-lang.modules" %% "scala-java8-compat" % versions.java8Compat |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No need to factor the version, as it's only used once.
def java8Compat = "org.scala-lang.modules" %% "scala-java8-compat" % versions.java8Compat | |
def java8Compat = "org.scala-lang.modules" %% "scala-java8-compat" % "0.9.1" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, this line should be moved between http4sDsl
and jimfs
, to keep dependencies sorted.
test("public URL") { | ||
withTmpDir { dir => | ||
try { | ||
Download.setCacheDir(dir.toFile) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the tests might run in parallel, which would be a problem here… To work around that, we can remove the static initializer on Download
, and make its methods non-static. #2000 does that, don't hesitate to rebase your work on it.
It should allow to just do
val download = new Download(dir.toFile, …)
download.getLocalURLs(…)
so that each test has its own Download
instance.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fine with me. I see that the bootstrap-launcher
doesn't enforce source and binary compatibility. Are you going to merge #2000? Then I'll rebase.
Thanks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's no binary compatibility checks for bootstrap-launcher
, as it's not meant to be used as a library (the same applies to the cli
module). I just merged #2000, just feel free to rebase.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's done: branch rebased and review comments applied. Please let me know if I missed anything. Thanks
69b40a0
to
8078a1e
Compare
val remoteUrls = Seq( | ||
new URL("https://repo1.maven.org/maven2/com/chuusai/shapeless_2.12/2.3.3/shapeless_2.12-2.3.3.jar") | ||
) | ||
val download = new Download(1, CachePath.defaultCacheDirectory(), Collections.emptyList()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't dir
be used here?
val download = new Download(1, CachePath.defaultCacheDirectory(), Collections.emptyList()) | |
val download = new Download(1, dir, Collections.emptyList()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for double checking. Yes, CachePath.defaultCacheDirectory()
should have been dir.toFile
. PR updated and checks out.
new URL(s"$testRepository/com/abc/test/0.1/test-0.1.pom" | ||
.replaceFirst(testRepositoryHost, s"$testRepositoryUser:$testRepositoryPassword@$testRepositoryHost")) | ||
) | ||
val download = new Download(1, CachePath.defaultCacheDirectory(), Collections.emptyList()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above:
val download = new Download(1, CachePath.defaultCacheDirectory(), Collections.emptyList()) | |
val download = new Download(1, dir, Collections.emptyList()) |
val remoteUrls = Seq( | ||
new URL(s"$testRepository/com/abc/test/0.1/test-0.1.pom") | ||
) | ||
val download = new Download(1, CachePath.defaultCacheDirectory(), Collections.singletonList( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above:
val download = new Download(1, CachePath.defaultCacheDirectory(), Collections.singletonList( | |
val download = new Download(1, dir, Collections.singletonList( |
d0ae1e7
to
1562eba
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @greg-a-atkinson!
Great. Thank you @alexarchambault |
Possible implementation for issue: #1774
Within my organisation we use a private authenticated Artifactory instance to serve all internal and external repositories. Ideally we would like to retrieve artifacts through this repository and not via a proxy. (A proxy requires domain credentials, while Artifactory only requires a user specific Artifactry API key, which more secure for adding to configuration files/properties/variables than domain credentials.)
When I configure the following
mirror.properties
:Most artifact retrievals succeed, but artifacts retrieved by the bootstrap launcher fail. For example, the Scala Metals plugin for VSCode fails to download various artifacts due to
401 Unauthorized
errors when the bootstrap launcher does not use the configured global credentials:The bootstrap launcher is a Java-only module, which makes sense as it will only have use of the core Java libraries before any dependencies are downloaded, but as a consequence it does not have access to the current Scala-based
Credentials
functionality. If ideally global credentials is used from bootstraps, the this could be implemented in a number of ways, each with different pros and cons:bootstrap-launcher
module is enhanced with just enough Java-based functionality to utilize the global credentials without any changes to the existing, out-of-scope Scala-based credentials functionality. Pros: No change to the the ScalaCredentials
API or implementation. Cons: Some duplication.paths
, could be enhanced with the complete credentials functionality, the Scala API updated to delegate to the Java implementation and theboostrap-launcher
updated to utilize the common credentials functionality. Pros: A single credentials implementation. Cons: Change, compatibility and larger initiative.Is there a preferred implementation in mind?
What do you think?
Happy to discuss.