bower / bower

A package manager for the web
bower.io
MIT License
14.97k stars 1.84k forks source link

Discuss ability to specify branches, specific commits, etc #107

Closed satazor closed 11 years ago

satazor commented 11 years ago

The objective of this issue is that people can give some feedback so we can converge towards a solution and an implementation.

Follow up of: #105 and #8

People often find bugs on their dependencies and the typical thing to do is to fork it, fix it, make a PR and use the fork until its accepted (or discarded :P). This workflow does not directly integrates with bower because the fork would have to contain a new tag with the fixes. The new tag is a must because bower always uses tags and only fallbacks to commits when the repo has no tags at all.

So:

One question that arises.. how will the prune/conflict/most suitable version of a shared dependency work out if targeting specific commits/latest commits?

//cc @fat @maccman @addyosmani @sindresorhus @aeosynth @kirkstrobeck

toabi commented 11 years ago

Here is an example which demonstrates what I could think is nice:

{
  'somePackage': '1.2.x', # works like we know it 
  'my-lib-1': 'git://url.to.the/repo#v1.2.3' # a tag
  'my-lib-2': 'git://url.to.some/repo#a4bd91337' # that specific commit
  'my-lib-3': 'git://url.to.other/repo#gh-pages' # always the latest commit on gh-pages
  'my-lib-4': 'git://url.to.other/repo' # always the latest commit on master (default)
}

Because a git checkout treats tags, branches and commit-hashes the same we can consider them the same, too.

While installing I would just also interpret the thing after the hash, so the user has all the possibilities he needs.

And mixing those things together doesn't really make sense with git, if you ask me. Everything is just a pointer to one commit, may it be a branch, tag or commit-hash.

The question with the shared dependency is a though one though… I don't know if bower should do any magic there or just tell the user that libA needs version X of libB which the user has as a "custom" git source…

kirkstrobeck commented 11 years ago

@toabi I agree with that spec. I believe in the matter of the shared dependency it should just tell the user.

satazor commented 11 years ago

I do agree with almost everything @toabi.

Still, If we change bower install jquery or bower install git://github.com/components/jquery.git to install the latest commit (on master) bower will loose the ability to find the most suited version for the project.

This is an advanced feature and should be used carefully.

Well not necessarly because the component.json would be still be read and the version contained in it would be assumed. But still..

toabi commented 11 years ago

What we could do is: We won't change that the url or package name without a version specifier (#) fetches the latest version, but still the most suited one.

If a user wants the latest commit, then he can simply put git://bla.tld/foo#master there for example. Tadam.

satazor commented 11 years ago

Agree

satazor commented 11 years ago

@fat can you give your input?

fat commented 11 years ago

my opinion is if you need to specify individual commits or branches you're doing it wrong.

Everything should be built around tags. People develop unstable projects in master all the time, and pulling the latest code from the lastest commit in master when you specify a project just isn't safe.

Also, relying on tags will allow us to optimize downloads in the future around tars.

do not change bower to install jquery from the latest commit

lol, jquery itself is unstable in master. cmon.

Anahkiasen commented 11 years ago

That is very nice and all but you're kind of talking about an imaginary wonderland where all repos are all clean and tagged with ideal versions conventions and all. This is not the case, Github is a gigantic websites, there are hundreds of components one could want to use and you cannot rely on the idea that everyone will adopt Bower and bow to your conventions. You need to provide gracious fallbacks and means to use repos not using neither tags nor components.json files.

satazor commented 11 years ago

I have to agree with @Anahkiasen.

While most of the time you won't target specific commits/last commit on branch, it's useful for the workflow described in my post:

People often find bugs on their dependencies and the typical thing to do is to fork it, fix it, make a PR and use the fork until its accepted (or discarded :P).
This workflow does not directly integrates with bower because the fork would have to contain a new tag with the fixes. The new tag is a must because bower always uses tags and only fallbacks to commits when the repo has no tags at all.
toabi commented 11 years ago

I also think that it would be much better to make bower able to work with every repository one can find instead of just blessed ones.

In my opinion bower should be a simple but powerful "We can download all kind of client-side dependencies from everywhere™ and even do magic if people provide proper metadata." - If it would just be a "Manager for blessed libraries with component.json/tags", it would be sad. And I could just go and use http://jamjs.org

kirkstrobeck commented 11 years ago

+1 @satazor @toabi @Anahkiasen

paulirish commented 11 years ago

For me, managing a few bower repos has been frustrating because accepting PRs isn't so hard, but PRs cant also make tags, so it's incomplete.

I'd like to find a way to allow a nice participatory model where the community can help maintain a package with PRs and no tags required.

On Mon, Nov 12, 2012 at 5:58 PM, Kirk Strobeck notifications@github.comwrote:

+1 @satazor https://github.com/satazor @toabi https://github.com/toabi @Anahkiasen https://github.com/Anahkiasen

— Reply to this email directly or view it on GitHubhttps://github.com/twitter/bower/issues/107#issuecomment-10297443.

addyosmani commented 11 years ago

^ :+1:

fat commented 11 years ago

hm… I think you guys are approaching this the wrong way – the goal shouldn't be to make bower magically consume everything which remotely resembles a package. It should be to educate authors to improve their repos and publish bower consumable packages.

Historically that's how package managers have worked… and there's a reason for that.

Package managers need to rely on package maintainers to tell us when a package is reliable – not the other way around.

Imagine building a high scale application like twitter.com. Or google search. Would you want google search relying on a commit sha?

the idea is kinda hilarious to me, and for that reason i'm completely against it. because people will do it.

what if i rebase my commit history? or delete my branch? it's just too vulnerable.

@paulirish every package manager i know requires a publish step unfortunately. However, I agree it would be nice if you could do it from the github interface – maybe try bringing it up with one of your github homies?

fat commented 11 years ago

sorry didn't mean to close…

sindresorhus commented 11 years ago

Also, relying on tags will allow us to optimize downloads in the future around tars.

You can use commits to fetch tars.

what if i rebase my commit history? or delete my branch? it's just too vulnerable.

GitHub will still keep around the tar.


So the thing is that a lot of projects rely on anything being in master as useable, especially small projects, and don't bother tagging. While this is not best practice, we have to face reality. We should absolutely not advice user to do their projects this way, but I'm for making the best of the situation and supporting it. Face it, users are going to find ways to misuse your product wether much you try to prevent it.

necolas commented 11 years ago

This discussion seems particularly GitHub-centric at the moment.

So the thing is that a lot of projects rely on anything being in master as useable, especially small projects, and don't bother tagging.

If you're not specifying a fixed commit-ish, then you're not relying on a known, fixed version.

users are going to find ways to misuse your product...

That doesn't mean that you should make it easy for them to do so.

fat commented 11 years ago

GitHub will still keep around the tar.

wuh? really?

If i have mybranch… and i delete it with git push origin :mybranch… you can download a tar of my deleted branch?

and if i git rebase -i – squash a bunch of commits into a single commit… you can download a tar of a commit i previously pushed?

@sindresorhus can you tell me how to do that… out of curiosity

necolas commented 11 years ago

AFAIK, GitHub does eventually do some clean up, at least w.r.t. the commits you can access by URL…so I'd assume they eventually do with the tars too.

sindresorhus commented 11 years ago

If you're not specifying a fixed commit-ish, then you're not relying on a known, fixed version.

Ok, should have been clear. I'm not for being able to specify branch, only a specific commit.

AFAIK, GitHub does eventually do some clean up, at least w.r.t. the commits you can access by URL…so I'd assume they eventually do with the tars too.

No idea, they might, but it has worked with a lost commit of grunt for months now, but I see the point on not relying on some undocumented feature. But I think GitHub also keep around commits from deleted branches for some comparison purposes or something.

@fat You can download specific commit using this url: https://github.com/twitter/bower/archive/4f5f36e4b3.tar.gz

But that is moot anyway, since you should never ever rebase something that is pushed.

necolas commented 11 years ago

Yep. Personally, I think it makes more sense to stay focused on git features within the context of package management.

fat commented 11 years ago

should never ever rebase

i think you may have just joined me in the "imaginary wonderland"

+1 to necolas… it's ok to optimize around github, but not to build features which only work on github.

kirkstrobeck commented 11 years ago

seems like a healthy compromise could be to support latest master with latest

{
  'my-lib-5': 'git://url.to.other/repo#latest'
}
necolas commented 11 years ago

seems like a healthy compromise could be to support latest master with latest

What's the use case for specifying a moving pointer rather than a commit-ish?

sindresorhus commented 11 years ago

i think you may have just joined me in the "imaginary wonderland"

I've always been there. Only thing that keeps me sane these days.

it's ok to optimize around github, but not to build features which only work on github.

@fat Uhm, you were the one suggestion using tars:

Also, relying on tags will allow us to optimize downloads in the future around tars.

What's the use case for specifying a moving pointer rather than a commit-ish?

Lazyness? (carelessness?). Relying on master will eventually break your project. I think we should steer the discussion away from that. What people actually need is to be able to specify a commit sha to be able to work around lazy non-tagging maintainers.

fat commented 11 years ago

Uhm, you where the one suggestion using tars

Tars as an optimization – not as an all or nothing.

fat commented 11 years ago

Honestly, i'm done discussing this. If you want to push it through, push it through.

fran6co commented 11 years ago

+1 for parsing branches too. A lot of projects are not using tags and there is no easy way to include them. This is a showstopper for using bower for every frontend dependency.

maccman commented 11 years ago

fwiw, I completely agree with @fat here.

vendethiel commented 11 years ago

+1 to allow branches/commits as versions

It'd be really useful in several cases : You may want to try out the last bugfix to test out if your usecase is resolved, to try out some feature, etc Maybe the project maintainer isn't tagging and you want to use the latest version disponible or maybe you need a very certain version to try something (used as something like bisect).

adambiggs commented 11 years ago

+1

Keep default behaviour the same as it is now, but imho there should be some way to target specific commits for testing/debugging (don't care about targeting branches though).

I totally agree this feature shouldn't be used in production, but sometimes during dev you can't get work done without a specific commit of some dependency.

E.g.: I sent a pull request to SlexAxton/require-handlebars-plugin which has been merged into master, but hasn't been tagged yet. Our app's UI is broken without this minor fix.

To get it through Bower, I had to point to my fork and push up a new tag (for only 2 loc changed). This feels like overkill when I could just go...

"require-handlebars-plugin": "SlexAxton/require-handlebars-plugin#73a4399319"

... and then set it back to "require-handlebars-plugin": "~0.4.1" when the next tag comes out.

scothis commented 11 years ago

I'm new to Bower, just downloaded it for the first time this morning, and am in the process of defining component.json files for my projects. Sounds easy enough, until I try to test my work. Whoops, I can only install from a tag. I don't want to tag my code just to test a config before a release, that seems horribly backwards.

In my opinion any git refspec should be installable: tags, commits, branches, whatever. I fully agree that depending on a branch for production code is a bad idea, however, it's incredibly useful for testing changes. Dumb people will do dumb things, it's not the tool's job to be their nanny.

satazor commented 11 years ago

@scothis Since you are new to bower there is two things that you should know.

scothis commented 11 years ago

@satazor thanks for the quick reply. In this case I wanted to test the components.json file and it's dependencies. bower link doesn't resolve dependencies, so that's a no go...

I don't want to hijack this thread, so I'll post a question elsewhere if I can't figure this out. I may just chance a tag and fix it later if it's borked.

satazor commented 11 years ago

@robdodson thing is that the default should be what bower does now, which is checking out tags. But in the end, we should give the ability to target branches, like master.

robdodson commented 11 years ago

@satazor yeah I'm in a situation now where I'm trying to create two repos, one depending on the other using bower. I'm in the dev stage with both of them, trying to figure out the structure. Having to rely on tags is making it really annoying for development. I'm planning to dev with submodules and then switch to bower when we have our structure worked out. It would be nicer if I could target the master branch at least in this really rough 'sketching' phase.

somerandomdude commented 11 years ago

I'm in the same boat. I could really use the ability to specify a branch. +1 for this.

gentbot commented 11 years ago

having the ability to specify branches would be great +1.

adambiggs commented 11 years ago

FYI, I found that you can target a branch using GitHub's archive service.

So to target the latest commit in master, you can go:

"dependency_name": "https://github.com/user/repo/archive/master.zip"
robdodson commented 11 years ago

Interesting. It doesn't seem to work with my private repos but it does work for public repos. Unfortunately we have to work in private so we're outta luck there.

gsmith85 commented 11 years ago

+1 on being able to specify branches / hashes.

If I'm going to use Bower I'd like to manage all my third party dependencies through my components.json file. Where I'm currently comfortable using the semantic versioning and Bower's registry for major libraries that are well maintained, the idea of having to rely on the latest commit on master of a smaller repository makes me cringe.

In the case of hashes, I understand that some moron could rebase their repository and blow away the hash I was depending on, but at least in that case Bower would fail loudly. I prefer this option to a scenario where I can't depend on my software working because I may have grabbed an unvetted version of a dependency that previously worked fine.

iknite commented 11 years ago

Imho we are all almost on the same page, authors should care about his repos and developers should have the ability to specify were to subscribe to. @toabi's syntax seems fair enough to me.

Please remember that bower aims to be The unopinionated package manager™ so let developers opinion about how to screw his project, with messy repos, rebased commits and so on.

Making strong documentation on good practices is good enough to me. Encourage in tag versioning but unforced to use it.

@satazor can you decide with way to go, so we can let our code talks instead our words?

satazor commented 11 years ago

Yes I will schedule this addition to 0.8.0 milestone.

reebalazs commented 11 years ago

I had a look at this issue, and I am a bit confused. What is the status of specifying git branches as dependancies? I am under the impression that this is not yet implemented anywhere, but I may be wrong.

@fat, I understand you are saying that depending on the top of a git branch is a bad practice. The reason why I would find this useful at all, because I am thinking of a specific use case. In this, there is an ongoing development of several packages. Releasing or tagging this packages after each commit would be very unpractical. Still, I would like to enable all developers working on the project, that they get the newest development on each update. Naturally, after the product gets released, it should not depend on unreleased versions of its dependancies, so depending on branches would only occur before releasing, so I agree on this 100%, but still I would like to have a way of development installation.

Provided that you agree on this use case, but at the same time you think that bower should not support this case by allowing dependancies to git branches, then, how would you suggest to support this workflow in a sensible way?

robdodson commented 11 years ago

yeah my team is basically living @reebalazs 's example. We're using git submodules but being able to target branches for development will be huge.

mikegrassotti commented 11 years ago

Same here

On Feb 22, 2013, at 7:51 PM, Rob Dodson notifications@github.com wrote:

yeah my team is basically living @reebalazs 's example. We're using git submodules but being able to target branches for development will be huge.

— Reply to this email directly or view it on GitHub.

necolas commented 11 years ago

IMO, developing against a moving target is a bad way to go about things. Even when your package is undergoing rapid iteration, other packages that are depending on it should point to specific commits and undergo their own iteration upon a stable foundation. You wouldn't need to cut a new tag each time if you could reference specific commits (a la npm). But you also don't need to update the package reference for every commit because you're not going to be significantly breaking a package's API or design features every single commit. This leaves it up to a team to communicate when significant changes have taken place in their package, and when authors of a separate package should take a moment to adapt it to deal with the changes that have taken place in one of its dependencies.

Allowing people to specific branch pointers is inevitably going to leak into production and kind of makes a mockery of the very idea of managing package versions. It means that I can't even check out your package (even during "early development") one day and then be sure (when I resolve my project's dependencies) that it will still work the next, despite remaining unchanged itself. One of your dependencies specified with a branch pointer might have changed in a way that blows up your entire package.

AFAICT, this is analogous to creating a feature branch and deciding for yourself when to merge master back into it. You do this at consciously decided moments, e.g., when the team lets you know that master is undergoing significant change and you shouldn't let your feature diverge too far.

I'm happy to be convinced otherwise. But at the moment, I can't see how being able to specify branches is a good thing.

robdodson commented 11 years ago

@necolas so you're saying don't do branches but do do specific commits yes? Like how git submodules work? If so I'm fine with that as well. I just need something that isn't exclusively tags.

jiverson commented 11 years ago

I guess I am confused, is bower suppose to protect you as a developer from bad packages? Or try to make repos follow some rule? First off specifically only checking for tags just won't work in a development cycle, you can't keep tagging on every commit that is just unrealistic.

But why put these arbitrary limitations on what someone puts in their repo for others to use? If someone adds in their component.json file that points to a specific branch, so be it, and if I use their package and it starts breaking my shit ....well I probably won't use it for very long or just fork and fix it myself. Either way let us decide, if you supply the gun and I shoot myself, you are not responsible.

As of right now the development team I work on don't use bower because of 2 reasons (the 3rd would be nice to have):

  1. Not letting us just point to a branch or specific commit
  2. Let us ignore files unneeded instead of pulling the whole repo(I know this is better with the ignore feature but still needs to be a bit more robust)
  3. Let the developer installing the package supply our own component.json file so we can specific what we need(enhancement? bower install jquery mycomponent.json)
desandro commented 11 years ago

:-1: for now on this feature. In short, I see more problems created over problems solved.

As a reminder, granpappies fat & maccman have already weighed in. necolas's above comment is spot-on.

In addition...


One of Bower's biggest and best features is how it resolves dependencies and versioning. Adding more granular controls like commit-specific versions or more abstract controls like latest-commit to branch would significantly complicate how versions are resolved.

Yes we could add additional feature that commits/branches are only for local development, and then add documentation about why we strip commit/branch versions from the public registry, but then we're adding more features to solve for a previously added feature.


The bigger issue here may not be Bower's feature-set, but with the practice of software development with Bower.

I'm currently working my own Bower-ified project. Unlike some who have chimed in this thread, I'm finding Bower's requirement of explicit versions to be beneficial to my development workflow. This is just me working on the project. My project has a lot dependencies. Even as one person, who has it all in my head, I can't keep track of everything. Working with explicit versions feels a lot more stable than just working off of master for 10+ repos.

If a larger, over-arching project exposes a problem in a dependency, they I go back and address that problem solely in the dependency. A test gets added to the dependency's project. The problem is resolved. The dependency's version is updated. Then bower update back in the larger. If I've properly identified and isolated the problem, I can rest assure that the associated problem will be resolved in the larger project.

Explicit versioning encourages me to keep separate projects separate and un-muddled.