Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 --- | 1 --- |
| 2 layout: default | 2 layout: default |
| 3 title: "Pub: How does versioning work?" | 3 title: "Pub: How does versioning work?" |
| 4 description: "How packages are versioned and how pub works with them." | 4 description: "How packages are versioned and how pub works with them." |
| 5 has-permalinks: true | 5 has-permalinks: true |
| 6 --- | 6 --- |
| 7 | 7 |
| 8 # {{ page.title }} | 8 # {{ page.title }} |
| 9 | 9 |
| 10 One of pub's core concerns is helping you work with versioning. Here, I'll | 10 One of pub's core concerns is helping you work with versioning. Here, I'll |
| (...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 212 | 212 |
| 213 The fact that selecting a package version takes into account *every* package | 213 The fact that selecting a package version takes into account *every* package |
| 214 that depends on it has an important consequence: *the specific version that | 214 that depends on it has an important consequence: *the specific version that |
| 215 will be selected for a package is a global property of the app using that | 215 will be selected for a package is a global property of the app using that |
| 216 package.* | 216 package.* |
| 217 | 217 |
| 218 I'll walk through an example so you can see what this means. Let's say we have | 218 I'll walk through an example so you can see what this means. Let's say we have |
| 219 two apps. Here are their pubspecs: | 219 two apps. Here are their pubspecs: |
| 220 | 220 |
| 221 {% highlight yaml %} | 221 {% highlight yaml %} |
| 222 # myapp | 222 name: my_app |
| 223 dependencies: | 223 dependencies: |
| 224 widgets: | 224 widgets: |
| 225 {% endhighlight %} | 225 {% endhighlight %} |
| 226 | 226 |
| 227 {% highlight yaml %} | 227 {% highlight yaml %} |
| 228 # otherapp | 228 name: other_app |
| 229 dependencies: | 229 dependencies: |
| 230 widgets: | 230 widgets: |
| 231 collections: '<1.5.0' | 231 collections: '<1.5.0' |
| 232 {% endhighlight %} | 232 {% endhighlight %} |
| 233 | 233 |
| 234 They both depend on `widgets`, whose pubspec is: | 234 They both depend on `widgets`, whose pubspec is: |
| 235 | 235 |
| 236 {% highlight yaml %} | 236 {% highlight yaml %} |
| 237 # widgets | 237 name: widgets |
| 238 dependencies: | 238 dependencies: |
| 239 collections: '>=1.0.0 <2.0.0' | 239 collections: '>=1.0.0 <2.0.0' |
| 240 {% endhighlight %} | 240 {% endhighlight %} |
| 241 | 241 |
| 242 The `otherapp` package uses depends directly on `collections` itself. The | 242 The `other_app` package uses depends directly on `collections` itself. The |
| 243 interesting part is that it happens to have a different version constraint on | 243 interesting part is that it happens to have a different version constraint on |
| 244 it than `widgets` does. | 244 it than `widgets` does. |
| 245 | 245 |
| 246 What this means is that you can't just look at the `widgets` package in | 246 What this means is that you can't just look at the `widgets` package in |
| 247 isolation to figure out what version of `collections` it will use. It depends | 247 isolation to figure out what version of `collections` it will use. It depends |
| 248 on the context. In `myapp`, `widgets` will be using `collections 1.9.9`. But | 248 on the context. In `my_app`, `widgets` will be using `collections 1.9.9`. But |
| 249 in `otherapp`, `widgets` will get saddled with `collections 1.4.9` because of | 249 in `other_app`, `widgets` will get saddled with `collections 1.4.9` because of |
| 250 the *other* constraint that `otherapp` places on it. | 250 the *other* constraint that `otherapp` places on it. |
| 251 | 251 |
| 252 This is why each app gets its own "packages" directory: The concrete version | 252 This is why each app gets its own "packages" directory: The concrete version |
| 253 selected for each package depends on the entire dependency graph of the | 253 selected for each package depends on the entire dependency graph of the |
| 254 containing app. | 254 containing app. |
| 255 | 255 |
| 256 ## Lockfiles | 256 ## Lockfiles |
| 257 | 257 |
| 258 So once pub has solved your app's version constraints, then what? The end | 258 So once pub has solved your app's version constraints, then what? The end |
| 259 result is a complete list of every package that your app depends on either | 259 result is a complete list of every package that your app depends on either |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 316 | 316 |
| 317 As you're selecting versions of packages, they are changing the shape of | 317 As you're selecting versions of packages, they are changing the shape of |
| 318 the dependency graph itself. As the graph changes, that may change | 318 the dependency graph itself. As the graph changes, that may change |
| 319 constraints, which can cause you to select different versions, and then you | 319 constraints, which can cause you to select different versions, and then you |
| 320 go right back around in a circle. | 320 go right back around in a circle. |
| 321 | 321 |
| 322 Sometimes this process never settles down into a stable solution. Gaze into | 322 Sometimes this process never settles down into a stable solution. Gaze into |
| 323 the abyss: | 323 the abyss: |
| 324 | 324 |
| 325 {% highlight yaml %} | 325 {% highlight yaml %} |
| 326 # myapp 0.0.0 | 326 name: myapp |
|
Bob Nystrom
2012/08/29 17:47:32
my_app to be consistent with above?
sethladd
2012/08/29 19:49:18
Done.
| |
| 327 version: 0.0.0 | |
| 327 dependencies: | 328 dependencies: |
| 328 yin: '>=1.0.0' | 329 yin: '>=1.0.0' |
| 329 {% endhighlight %} | 330 {% endhighlight %} |
| 330 | 331 |
| 331 {% highlight yaml %} | 332 {% highlight yaml %} |
| 332 # yin 1.0.0 | 333 name: yin |
| 334 version: 1.0.0 | |
| 333 dependencies: | 335 dependencies: |
| 334 {% endhighlight %} | 336 {% endhighlight %} |
| 335 | 337 |
| 336 {% highlight yaml %} | 338 {% highlight yaml %} |
| 337 # yin 2.0.0 | 339 name: yin |
| 340 version: 2.0.0 | |
| 338 dependencies: | 341 dependencies: |
| 339 yang: '1.0.0' | 342 yang: '1.0.0' |
| 340 {% endhighlight %} | 343 {% endhighlight %} |
| 341 | 344 |
| 342 {% highlight yaml %} | 345 {% highlight yaml %} |
| 343 # yang 1.0.0 | 346 name: yang |
| 347 version: 1.0.0 | |
| 344 dependencies: | 348 dependencies: |
| 345 yin: '1.0.0' | 349 yin: '1.0.0' |
| 346 {% endhighlight %} | 350 {% endhighlight %} |
| 347 | 351 |
| 348 In all of these cases, there is no set of concrete versions that will work for | 352 In all of these cases, there is no set of concrete versions that will work for |
| 349 your app, and when this happens pub will report an error and tell you what's | 353 your app, and when this happens pub will report an error and tell you what's |
| 350 going on. It definitely will not try to leave you in some weird state where you | 354 going on. It definitely will not try to leave you in some weird state where you |
| 351 think things can work but won't. | 355 think things can work but won't. |
| 352 | 356 |
| 353 ## Summary | 357 ## Summary |
| 354 | 358 |
| 355 Wow, that's a lot to get through. Here's the important bits: | 359 Wow, that's a lot to get through. Here's the important bits: |
| 356 | 360 |
| 357 * Code reuse is great, but in order to let developers move quickly, packages | 361 * Code reuse is great, but in order to let developers move quickly, packages |
| 358 need to be able to evolve independently. | 362 need to be able to evolve independently. |
| 359 * Versioning is how you enable that. But depending on single concrete versions | 363 * Versioning is how you enable that. But depending on single concrete versions |
| 360 is too precise and with shared dependencies leads to version lock. | 364 is too precise and with shared dependencies leads to version lock. |
| 361 * To cope with that, you depend on *ranges* of versions. Pub will then walk | 365 * To cope with that, you depend on *ranges* of versions. Pub will then walk |
| 362 your dependency graph and pick the best versions for you. If it can't, it | 366 your dependency graph and pick the best versions for you. If it can't, it |
| 363 tells you. | 367 tells you. |
| 364 * Once your app has a solid set of versions for its dependencies, that gets | 368 * Once your app has a solid set of versions for its dependencies, that gets |
| 365 pinned down in a *lockfile*. That ensures that every machine your app is | 369 pinned down in a *lockfile*. That ensures that every machine your app is |
| 366 on is using the same versions of all of its dependencies. | 370 on is using the same versions of all of its dependencies. |
| OLD | NEW |