fxpio / composer-asset-plugin

NPM/Bower Dependency Manager for Composer
MIT License
893 stars 156 forks source link

Why plugin recurses through bower versions? #257

Closed kirill-konshin closed 7 years ago

kirill-konshin commented 7 years ago
$ composer global require "fxp/composer-asset-plugin:~1.2.0"
$ composer create-project --prefer-dist --stability=stable yiisoft/yii2-app-advanced yii-application
Installing yiisoft/yii2-app-advanced (2.0.9)
  - Installing yiisoft/yii2-app-advanced (2.0.9)
    Downloading: Connecting...
Could not fetch https://api.github.com/repos/yiisoft/yii2-app-advanced/zipball/fd3b27541b4af8dad7df4481c031e5cb6ff54671, please create a GitHub OAuth token to go over the API rate limit
Head to https://github.com/settings/tokens/new?scopes=repo&description=Composer+on+foo
to retrieve a token. It will be stored in "/Users/foo/.composer/auth.json" for future use by Composer.
Token (hidden): 
Token stored successfully.
    Downloading: 100%         

Created project in yii-application
Loading composer repositories with package information
Updating dependencies (including require-dev)
Reading bower.json of bower-asset/jquery.inputmask (3.1.45)

The last line goes all the way to Reading bower.json of bower-asset/jquery.inputmask (3.1.0) and lower. What's the point??? It is just a waste of time and leads to Github throttling. Is there any way force composer to just pick first good version and go with it?

francoispluchino commented 7 years ago

Because that is the minimum required version of this dependency, and the composer.lock file is not present in the project.

So, the Solver SAT must analysis all versions of all dependencies between the minimum version and the latest available version.

For the update, the plugin optimizes the analysis with the last installed version.

kirill-konshin commented 7 years ago

If the version listed in dependency is >3.1.0 then 3.1.45 should fulfill it and process should stop on step one...

cebe commented 7 years ago

@kirill-konshin the thing is, that 3.1.45 might not be possible to install dependent on the other dependencies, e.g. it may require a jquery version higher than the one an other package has required. Solving dependencies is a complex job which in case of composer searches the possible combination of versions for the best possible solution.

A good read about this topic: https://medium.com/@sdboyer/so-you-want-to-write-a-package-manager-4ae9c17d9527#.6n70i6k8w

kirill-konshin commented 7 years ago

That's quite obvious... But... For optimization purpose the best way is to blindly try all deps at maximum possible version, and only if it does not fit -- then perform the tricky part.

francoispluchino commented 7 years ago

Normally, it' is recommended to keep the composer.lock file. With him, Composer makes no request, and installs directelly the dependencies.

kirill-konshin commented 7 years ago

Unfortunately that's not the case for Docker containers, for example. They are supposed to be built from scratch, e.g. no lock files. Although I tried it with lock file too already, but I don't like the idea that dependencies during initial installation are listed in two places -- in composer.json and also in a cached form in composer.lock. Also some people assume that it's a bad practice to keep lock file in source control.

cebe commented 7 years ago

if you want predictable deployments, e.g. have the same software in production and on the system where you test whether everything works, you must use lock file. I see no reason to not commit composer.lock in an application repository.

francoispluchino commented 7 years ago

There is a very good article about it, see Composer: It’s All About the Lock File, but that's not the only one.

kirill-konshin commented 7 years ago

Some offtopic material here :) this sound ridiculously weird to me, I quote:

The point of the lock file is to record the exact versions that are installed so they can be re-installed. This means that if you have a version spec of 1.* and your co-worker runs composer update which installs 1.2.4, and then commits the composer.lock file, when you composer install, you will also get 1.2.4, even if 1.3.0 has been released. This ensures everybody working on the project has the same exact version.

Then just have 1.2.4 in composer.json, no wildcards or special symbols, only exact version, just like you do in package.json of NPM. For some reason NPM does not have this pathetic lock file and it's working just fine... Otherwise nobody have guarantee that 1.3.0 will sneak into your repo...

cebe commented 7 years ago

@kirill-konshin you can just use 1.2.4 in composer.json and the asset-plugin will not download any other version to check. That would solve the original question for you.

francoispluchino commented 7 years ago

Sorry, it's wrong, NPM has the same behavior: npm-shrinkwrap. On the other hand, Bower hasn't the locker, and it's a problem, you are forced to define all the dependencies in the project root.

francoispluchino commented 7 years ago

After, it is only a recommendation to be sure to have the same dependencies in environments dev, test and prod.

kirill-konshin commented 7 years ago

@cebe unfortunately, not. This package is installed by Yii2 and as mentioned here https://github.com/yiisoft/yii2/issues/8094#issuecomment-253167497 getting rid of visual dependencies is planned but not yet there...

@francoispluchino Shrinkwrap is considered as a bad practice for super special cases. Normally nobody ever should use it. So I still think that lock file is just a hack... I might be wrong, sorry, but that's just my opinion...

Bower is probably the worst package manager ever, no wonder why it's in decline these days...

Anyway, let's get back to original topic.

As far as I understood, the solution to avoid deep lookup of bower deps is to have lock file, right?

francoispluchino commented 7 years ago

Yes, or define in your root composer.json file the last versions of all dependencies. Which, therefore avoids using the composer.lock file (the last comment of @cebe).

kirill-konshin commented 7 years ago

OK, so before bower deps are dropped from Yii2 I will use lock then in order to not pollute json.

francoispluchino commented 7 years ago

The engineers at Facebook have posted a great article on how they use NPM and Shrinkwrap, explaining all their problems, and their solutions in relation to their needs.

Finally, they created a new alternative client Yarn natively using a lockfile, and explains their motivations. They worked with Exponent, Google, and Tilde.

Interesting point in addition to its consistency, its security, and its performance, Yarn is compatible with both the npm and bower workflows and supports mixing registries.

On reading the post, it look like to the mechanism of Composer with this plugin (although they are inspired to Bundler, Cargo and NPM), but with optimizations in their Solver :-).

It's always interesting to read this kind of blog post.

The post: Yarn: A new package manager for JavaScript The analysis: Compare Yarn Performance