加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

不用使用动态的版本依赖

发布时间:2020-12-13 22:14:43 所属栏目:百科 来源:网络整理
导读:在170期的adroid weekly里面有一篇文章, 说的是关于我们在gradle里面使用动态依赖这件事。 他希望人们使用具体的版本的,而不是模糊的。理由如下: 1. Dependencies can unexpectedly introduce behavior changes to your app. Read your changelogs careful

在170期的adroid weekly里面有一篇文章,

说的是关于我们在gradle里面使用动态依赖这件事。

他希望人们使用具体的版本的,而不是模糊的。理由如下:

1. Dependencies can unexpectedly introduce behavior changes to your app. Read your changelogs carefully!

2. The same source built on two different machines can differ. How many times have you said "but it works on my machine?"

3. Similarly,builds built on thesamemachine but atdifferenttimes can differ. I've wasted so much time on builds that worked on minute then broke the next.

4. Past builds cannot be reproduced perfectly. This makes it difficult to revert safely.

5. There aresecurity implicationsif a bad actor introduces a malicious version of a dependenc


第2、3条似乎已经足够说服力了。
作为一个好习惯,还是使用具体的版本号吧。

---------------------------------

原文:

Don't use dynamic versions for your dependencies

Everyone,please,to stop using dynamic versions for your dependencies.

In Gradle,dynamic versions use the+sign like so:

compile 'com.android.support:appcompat-v7:23.0.+'

Ideally,your builds should be predictable and consistent. Identical source code should yield the same result,every time you build.

Dynamic versions add nondeterminism to your build.In other words,the same source codemay notyield the same output. This behavior manifests itself in all sorts of nasty problems:

  • Dependencies can unexpectedly introduce behavior changes to your app. Read your changelogs carefully!

  • The same source built on two different machines can differ. How many times have you said "but it works on my machine?"

  • Similarly,builds built on thesamemachine but atdifferenttimes can differ. I've wasted so much time on builds that worked on minute then broke the next.

  • Past builds cannot be reproduced perfectly. This makes it difficult to revert safely.

  • There aresecurity implicationsif a bad actor introduces a malicious version of a dependency.

The solution is simple:always specify your dependency versions explicitly.

But But But...!

Here's a couple of arguments I've heard for using dynamic versioning and why I disagree.

I don't want to bother updating dependencies.

Your laziness will likely cost you more time down the road fixing some problem created by dynamic versions.

Bugfix updates should be safe and absorbed as quickly as possible.

In other words,if you're using23.0.+,it should never break because the patch version should only update for bug fixes.

There are two problems with this idea. First,you have to trust that the library is using versions to denote patches correctly. And second,you have to trust that the developerneverwrites a bug into a patch version. Two big ifs; not worth the risk.

My library needs to use dynamic versioning; otherwise I have to release a new version of the library every time one of its dependencies updates.

This is wrong on two counts.

First,userscanupdate your library's dependencies without a new version of your library. They just need to define the dependency on their own:

// Depends on appcompat-v7:23.0.0
compile 'com.trello:rxlifecycle-components:0.3.0'

// Even though rxlifecycle-components uses 23.0.0,// the build will ultimately use 23.0.1 as provided below
compile 'com.android.support:appcompat-v7:23.0.1'

Second,if a dependency updates in a way thatbreaksyour library,then you need to manually update your library anyways!

In other words: it isn't needed and it won't save you effort.

Developers can't be trusted to update their dependencies.

Otherwise known asthe Fabric argumentfor why you should use+with their plugin:

// The Fabric Gradle plugin uses an open ended version to
// react quickly to Android tooling updates
classpath 'io.fabric.tools:gradle:1.+'

The choice here is thus: you can either break your build after updating tools (which is an expected occasional outcome),or your build can randomly break when you unknowingly get a new version of Fabric.

I would rather take the route where I know what changed vs. the one where I have to hunt down the root problem.

Removing Dynamic Versions

Hopefully you're itching to get rid of all your dynamic versions. How do you do it?

For Android developers,there's a couple handy tools you can use. If you're using Android Studio then you can select a dynamic version and useALT+ENTERto pop up the quickfix dialog. From there select "Replace with specific version."

If you want to see all your dependencies at once then use the taskandroidDependencies:

$ ./gradlew androidDependencies

If you're not building Android then you'll have to resort to thedependenciestask:

$ ./gradlew dependencies

Often times you'll need to specify the subproject you're targeting for this task. Supposing my app is inapp-dir/,this is how you'd do it:

$ ./gradlew :app-dir:dependencies

These tasks showmostdependencies but they're missing the buildscript ones (i.e.,plugins like Fabric). As far as I know,there's no easy way to list these. You have to add your own task that prints it out for you:

// Add this to your build.gradle
task buildscriptDependencies << {  
    buildscript.configurations.classpath.each { println it }
}

Then you can run this new script to get the buildscript versions:

$ ./gradlew buildscriptDependencies

Once you've purged your dynamic versions,I suggest usingthe gradle-versions-pluginon a regular basis to update your dependencies.

Exception

As with everything in programming,there are always exceptions. There'sa plugin from Netflixthat partially solves dynamic version problems. It allows you to define a range for a dependency but then alsolocksthat dependency in place afterwards. This doesn't save you from a dependency update randomly breaking your build but it does keep builds consistent.

Personally,updating dependencies by hand is simple enough and I like to read changelogs to make sure nothing is catching me off guard. I haven't tried this plugin as a result,but it could be appropriate if you have enough tests in place to protect you from dependencies breaking code.


Thanks tothe many people who proofread this article:Wojtek Kaliciński,Johan Nilsson,Ryan Harter,Sebastiano Poggi,andJake Wharton.


http://blog.danlew.net/2015/09/09/dont-use-dynamic-versions-for-your-dependencies/?utm_source=Android+Weekly&utm_campaign=98aaa2f697-Android_Weekly_170&utm_medium=email&utm_term=0_4eb677ad19-98aaa2f697-337880413

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读