-
-
Notifications
You must be signed in to change notification settings - Fork 232
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
Maven repository package supplier added #1415
Conversation
Thanks for your pull request and interest in making D better, @andre2007! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please see CONTRIBUTING.md for more information. If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment. |
Test added |
Didn't review the code in detail, yet, but from the outside everything looks good. Considering that there have been additional proposals for extended repository support, maybe we should start thinking about how to generalize the registry protocol specification, could for example be a prefix ( |
I really like the "maven+https://" proposal. This makes the additional console argument and env variable superfluous. I will adapt the coding.
|
The new logic does not work due to bug #1418 |
|
||
Allowed protocols are dub+http(s):// and maven+http(s)://. | ||
*/ | ||
PackageSupplier getRegistryPackageSupplier(string url) |
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 worked around bug #1418 by adapting the string before creating URL.
If this is OK I would leave the method as it is and solve the bug in URL in an independent pr.
What is your preference?
|
mvn+https:// |
I changed to protocol mvn+https. |
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.
A few comments. Looks nice already!
@@ -290,6 +290,150 @@ class RegistryPackageSupplier : PackageSupplier { | |||
} | |||
} | |||
|
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.
Not related to this PR, but imho with this file getting larger and larger,this would be better of in being a package.
source/dub/packagesupplier.d
Outdated
return null; | ||
Version[] ret; | ||
foreach (json; md["versions"]) { | ||
auto cur = Version(cast(string)json["version"]); |
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.
.get!string
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.
done
source/dub/packagesupplier.d
Outdated
ret ~= cur; | ||
} | ||
ret.sort(); | ||
return ret; |
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 method is still uncovered.
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.
Should be covered now. An additional test was added to issue1416-maven-repo-pkg-supplier.sh which should retrieve the latest version.
continue; | ||
} | ||
} | ||
} |
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 know that the RegistryPackageProvider does this too, but it's probably better to this generically in a RetryingPackageProvider, but that's not something this PR needs or should address.
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.
or a retrying download function
URL m_mavenUrl; | ||
struct CacheEntry { Json data; SysTime cacheTime; } | ||
CacheEntry[string] m_metadataCache; | ||
Duration m_maxCacheTime; |
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.
In theory you still might run out of memory within one day.
source/dub/packagesupplier.d
Outdated
m_metadataCache.remove(packageId); | ||
} | ||
|
||
auto url = m_mavenUrl~ NativePath(packageId ~ "/maven-metadata.xml"); |
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: you could be more consistent with spacing when using ~
- at least within the same line ;-)
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.
done
source/dub/packagesupplier.d
Outdated
continue; | ||
} | ||
} | ||
} |
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.
Looks like we are better off with having a "generic" downloadRetry
method for this. Could be a simple parameter to download
?
source/dub/packagesupplier.d
Outdated
} | ||
} | ||
|
||
Json json = serializeToJson(["name": Json(packageId), "versions": Json.emptyArray]); |
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.
auto json = Json(["name": Json(packageId), "versions": Json.emptyArray]);
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.
done
source/dub/packagesupplier.d
Outdated
Json best = null; | ||
Version bestver; | ||
foreach (json; md["versions"]) { | ||
auto cur = Version(cast(string)json["version"]); |
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.
.get!string
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.
done
source/dub/packagesupplier.d
Outdated
} else if (bestver.isPreRelease) { | ||
if (!cur.isPreRelease || cur > bestver) best = json; | ||
} else if (!cur.isPreRelease && cur > bestver) best = json; | ||
bestver = Version(cast(string)best["version"]); |
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.
Instead of copy/pasting this from the other supplies,I suggest to move it in a separate method.
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.
done
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.
Re-added the comments that got outdated while I added them. Stupid GH :/
source/dub/dub.d
Outdated
*/ | ||
PackageSupplier getRegistryPackageSupplier(string url) | ||
{ | ||
if (url.toLower.startsWith("dub+")) |
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.
- avoid the allocation ->
asLowerCase
- Do we even need lowering?
- You could make this generic and faster (
startsWith
supports a variadic overload for better performance as the string checking is only done once)
import std.algorithm : map;
import std.meta : aliasSeqOf;
enum needles = [
["dub+", "RegistryPackageSupplier"],
["maven+", "M2RegistryPackageSupplier"],
];
switch(url.startsWith(aliasSeqOf!(map!(a => a[0])(needles))))
{
static foreach (uint i, el; needles)
case i + 1:
mixin("return new "~ el[1] ~"(URL(url["~el.length.to!string~"0 .. $]));");
default:
return new RegistryPackageSupplier(URL(url));
}
edit: you probably can't use static foreach
yet as GDC doesn't support this yet, but the "normal" CTFE foreach works as well.
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.
done
test/test_maven_registry.d
Outdated
router.get("*", folder.serveStaticFiles); | ||
listenHTTP(text(":", port), router); | ||
runApplication(); | ||
} |
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.
Might be worthwhile to look into whether the duplication from test_registry.d
can be avoided.
Maybe a switch to make fallbacks optional?
Though OTOH it might be a good idea to check whether the retry logic actually works.
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.
You are right, I removed this file and use test_registry.d instead
test/test_maven_registry.d
Outdated
@@ -0,0 +1,19 @@ | |||
/+dub.sdl: | |||
dependency "vibe-d" version="~>0.8.3-alpha.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.
0.8.3 has been released for a while now.
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.
done
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.
By changing to 0.8.3 there are some failing tests:
Root package test_maven_registry reference vibe-d ~>0.8.3 cannot be satisfied.
https://travis-ci.org/dlang/dub/jobs/357730493
"$DUB" fetch maven-dubpackage --version=1.0.5 --skip-registry=all --registry=mvn+http://localhost:$PORT/maven/release/dubpackages | ||
|
||
if ! dub remove maven-dubpackage --non-interactive --version=1.0.5 2>/dev/null; then | ||
die 'DUB not have installed package from maven registry.' |
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.
Spelling:
- DUB did not install
- DUB doesn't have the installed
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.
done
private { | ||
URL m_mavenUrl; | ||
struct CacheEntry { Json data; SysTime cacheTime; } | ||
CacheEntry[string] m_metadataCache; |
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.
When only new packages are added this cache is never cleared. It doubt it matters because usage is through one-time CLI mostly + there are less than a million MVN packages.
Thanks for your comments, the easy ones I already solved, the others will take some time.
|
Oh I just used |
I tried to generalize the download retry but I didn't found a nice way. By generalizing you loose the dedicated error/log statements: There is one failing test, s.th. about /dub/test/ddox.sh, I am not really sure what is the cause:
|
Blocked by sporadic dub registry network issues and error in vibed eventcore 0.8.34. Failing test cause by:
|
@wilzbach
My proposal is to have a straight forward solution. I will update the pr |
Any chance to get this pr tagged for 1.9.0? |
source/dub/dub.d
Outdated
else if (url.startsWith("mvn+")) | ||
{ | ||
return new MavenRegistryPackageSupplier(URL(url[4..$])); | ||
} |
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.
how about using the startsWith overload which returns a uint with multiple needles here? if this gets more this will probably be a bit ugly because of lots of copy paste, though startsWith might not be the perfect solution here as then you would be limited to a fixed length for all the checks you use there.
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.
Thank you for the tip, I adapted the coding and use multiple needles now
Done. I don't see any bigger issues, so this should hopefully work out :) |
continue; | ||
} | ||
} | ||
} |
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.
or a retrying download function
|
||
private Json getMetadata(string packageId) | ||
{ | ||
import std.xml; |
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.
not sure if it's a good idea to import this, vibe should really contain something for xml or at least html parsing
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 checked, unfortunately vibed doesn't contain anything regarding xml. It would maybe possible to parse the text via regex (Find all child "version" tags within parent tag "versions") or plain string functions. But as phobos contains a xml parsers which works quite well for this scenario, I am not 100% sure.
<release>1.0.6</release> | ||
<versions> | ||
<version>1.0.5</version> | ||
<version>1.0.6</version> |
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.
mixed tab and space here
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.
done
Do you have a time schedule when this pull request can be merged? |
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 guess anytime. Any objections @s-ludwig?
The purpose of this pull request is to be a door opener for dub in commercial sector. In build infrastructure it is in many cases not allowed to connect to the public internet (code.dlang.org) for security reasons. Instead the companies runs their own repositories using software like Nexus or Artifactory.
It is quite hard to convince system administrators to also run additional software like dub registry.
To solve this problem, this pull request enables dub to connect to maven repositories to retrieve dub packages. Environment variable
DUB_REGISTRY
and console argument--registry
now accepts additional protocols (dub/mvn). Example:--registry dub+https://code.dlang.org
--registry mvn+http://localhost:8040/artifactory/libs-release/dubpackages
These Maven urls consists of the path to a maven repository + a group id.
(libs-release is the maven repository, dubpackages is the group id)
In the maven repository you deploy your dub package with group id "dubpackages" and
as artifactId you use dub package name and as version you use dub package version.
Maven creates a metadata xml file which get quite handy for retrieving metadata needed for dub
This metadata and the archives (zip)files are stored using canonical paths.
http://localhost:8040/artifactory/libs-release/dubpackages/d-unit/maven-metadata.xml
http://localhost:8040/artifactory/libs-release/dubpackages/d-unit/0.8.2/d-unit-0.8.2.zip
As far as I know Maven does not provide a nice generic way to implement the searchPackages method.
Therefore I left this method empty.
Can you have a look at this pr?