-
Notifications
You must be signed in to change notification settings - Fork 932
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
Refactored retrieving of remote projects and added support for FTP, Mercurial and Subversion #309
Conversation
Thanks! I probably won't have time to review this for a couple of days. |
If you have any questions about the code (i tried to make it as readable as possible) or if you find something that needs fixing, don't hesitate to ask. |
I reviewed this a week ago, but it seems my comment didn't show up, so sorry about the delay. The overall goals of separating out the individual retrievers, adding new ones, and optimizing git usage are good.
There is already a type for retrievers: BuildLoaders.Resolver: type Resolver = ResolveInfo => Option[() => File] This is a better type for a partial function than having two methods in a trait like Scala's PartialFunction. |
Thanks for the reply. I will fix these suggestions and push the new commits in few days. Additionally, if you could tell me the way to do it, I can also add configuration so people can define new retrievers in their build files. |
It is already possible. See https://github.com/harrah/xsbt/wiki/Build-Loaders. |
error("Nonzero exit code (" + result + "): " + command.mkString(" ")) | ||
} | ||
// Note: Git MUST come before Remote and Local because it can also handle `http(s)`, `ftp` and `file` URIs. | ||
private val retrievers = List(Retriever.Subversion, Retriever.Mercurial, Retriever.Git, Retriever.Remote, Retriever.Local) |
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 I said configuration, I was thinking about this line which hardcodes default retrievers. Is it fine, w.r.t. outside configuration of Resolvers, to do it like this?
Oh, sorry. Yes, that should work. Users can't remove the defaults without configuring a full build loader, but they can override one by adding a resolve that handles that URI. Is that what you are asking? |
I tried to follow code but i got lost :) so i asked to be sure to not create problems. thanks for the clarification. also, i pushed new commits: now i am using BuildLoader.Resolver instead of my own trait and i replaced all implicits with normal methods as you suggested. |
Great, thanks for the continued work!
val Local: Resolver = (info: ResolveInfo) => {
... body of apply method ...
}
|
Hopefully this is better now :-) Changes:
|
This looks close. If it weren't for #1, I think it could be merged.
|
Good catch with #1. I fixed all your suggestions and made two additional changes:
|
Now that I've tried it out, it throws an exception when using a URI like
You might want to use ScalaTest, specs2, or ScalaCheck for unit tests or sbt's scripted tests for integration testing: https://github.com/harrah/xsbt/blob/gh-pages/Developing.pdf?raw=true. Please ask if you have any questions. |
…tories. fixes #331 System propery sbt.global.plugins configures global plugins directory default: $sbt.global.base/plugins System property sbt.global.staging configures global staging directory default: $sbt.global.base/staging System property sbt.global.settings configures directory containing global .sbt files default: $sbt.global.base
I had the same mistake in I tested it on my machine manually and now it works. I can create some unit tests for RichURI, but I am still not sure how can I test retrieving. If I use remote git, mercurial, and svn repositories it will make testing very slow and dependent on internet connection. So do you have any other ideas? |
…k/xsbt into wip_sourcepos_eugenevigdorchik
Wip sourcepos eugenevigdorchik
Right. Looking at the code it seems a new temporary directory is created every time RetrieveUnit.apply is called, so checking for exists() doesn't make much sense. |
It doesn't have to create new directory for each new retrieval. If you try to retrieve same URI twice, second time you don't have to do anything and just return the directory that is already there. Again, same semantic as in previous code. Is that what you asked or did I understood you wrong? |
Yes, sorry for that. |
But, figuring out where to resolve URI is not same. Local retriever will just point to given URI if it is writable. SVN, mercurial and git will normalize repository URI so that for example Of course, you can put all this into RetrieveUnit, but it doesn't gain anything because it will still be specific for each case. I just prefer to keep all retrieve-specific things inside corresponding retriever. If you or harrah prefer other way you can take my code and move that to RetrieveUnit. Furthermore, this check has to be in the returned function because we have to check if local directory exists as a precaution before we try to create it. That means that RetrieveUnit would have to be responsible for creating the returned functions, which changes whole design of retrievers because they then become just Unit functions. |
@vigdorchik OSTYPE can be probably dealt with in a subsequent pull request, right? @saserr to be clear, the patch is a good one and important and will go in. I asked Eugene to look at it to give you faster feedback and for a fresh review as it is harder to look at it clearly after a few revisions. |
No problem, of course. Glad to help at least little bit :) Should I also rebase on top of 0.12 branch instead of 0.11 as there won't be any more 0.11.x releases? |
Yes, put it on the 0.12 branch. |
Instead of cloning from a remote git repository for each branch, revision or tag separately, the git resolver locally clones only once the remote git repository and then creates further local clones from this local copy of the remote repository. First, optimization, of course, is execution speed, because cloning local repository is much faster than remote repository. Furthermore, because git uses hard-linking when a clone of local repository is created, the second optimization is in space consumption. For example, if we have one project that uses https://github.com/harrah/xsbt.git#v0.11.1 and second project that uses https://github.com/harrah/xsbt.git#v0.11.2, in previous git resolver implementation it would require two separate clones of the remote git repository at https://github.com/harrah/xsbt.git. But, the new git resolver requires only one clone of the remote git repository and two local clones which take no space because of hard-linking.
Non-standard git URIs are ones that do not start with 'git:' nor end with '.git'. An example of non-standard git URI is 'ssh://server/home/user/repo'. The mechanism for specifying a non-standard git URI is done by prefixing the whole URI with 'git:' to signify that it should be handled with the git resolver. For example, non-standard git URIs like 'git:ssh://server/user/repo' and 'git:https://server/user/repo' can now be used.
All mercurial URIs have to be prefixed with 'hg:' to separate them from URIs for other resolvers. For example, 'hg:https://server/user/repo' can now be used.
All subversion URIs have to be prefixed with 'svn:' to separate them from URIs for other resolvers. For example, 'svn:https://server/repo' can now be used.
It messed up this pull request after rebase, because it didn't change it to 0.12 branch. I am closing it and opening new one for 0.12 branch. |
This pull contains:
Examples of git URIs:
Examples of mercurial URIs:
Examples of subversion URIs: