Thread overview
Dub project has both .sdl and .json files. Is this normal or did I do something wrong?
Dec 18, 2017
WhatMeWorry
Dec 18, 2017
WebFreak001
Dec 19, 2017
Jacob Carlborg
Dec 19, 2017
Jacob Carlborg
Aug 03, 2018
Bastiaan Veelo
Aug 04, 2018
Jacob Carlborg
Aug 04, 2018
Neia Neutuladh
Aug 05, 2018
Bastiaan Veelo
Aug 05, 2018
Jacob Carlborg
December 18, 2017
I've been using Dub for a while but from the very beginning I decided to go with SDL 100% of the time, So I've got a dub.sdl file like:

name "01_10_camera_view_space"
description "A minimal D application."
authors "kheaser"
copyright "Copyright © 2017, kheaser"
license "proprietary"

dependency "derelict-al"      version="~>1.0.3"
dependency "derelict-assimp3" version="~>1.3.0"
dependency "derelict-fi"      version="~>2.0.3"
dependency "derelict-fmod"    version="~>2.0.4"
dependency "derelict-ft"      version="~>1.1.3"
dependency "derelict-gl3"     version="~>1.0.23"
dependency "derelict-glfw3"   version="~>3.1.3"
dependency "derelict-util"    version="~>2.0.6"
dependency "gl3n"             version="~>1.3.1"
  .............


But when I look the directory that has the dub.sdl file, I also see a file called dub.selections.json

{
	"fileVersion": 1,
	"versions": {
		"derelict-al": "1.0.3",
		"derelict-assimp3": "1.3.0",
		"derelict-fi": "2.0.3",
		"derelict-fmod": "2.0.4",
		"derelict-ft": "1.1.3",
		"derelict-gl3": "1.0.23",
		"derelict-glfw3": "3.1.3",
		"derelict-util": "2.0.6",
		"gl3n": "1.3.1"
	}
}


So how did this .json file get created and can I just delete it?  I only noticed this because when I was troubleshooting the project, I changed the dub.sdl library versions but the compile/run was using the library versions in dub.selections.json.

I did switch from using DMD to LDC, if that has any bearing.





December 18, 2017
On Monday, 18 December 2017 at 22:36:44 UTC, WhatMeWorry wrote:
>
> I've been using Dub for a while but from the very beginning I decided to go with SDL 100% of the time, So I've got a dub.sdl file like:
>
> name "01_10_camera_view_space"
> description "A minimal D application."
> authors "kheaser"
> copyright "Copyright © 2017, kheaser"
> license "proprietary"
>
> dependency "derelict-al"      version="~>1.0.3"
> dependency "derelict-assimp3" version="~>1.3.0"
> dependency "derelict-fi"      version="~>2.0.3"
> dependency "derelict-fmod"    version="~>2.0.4"
> dependency "derelict-ft"      version="~>1.1.3"
> dependency "derelict-gl3"     version="~>1.0.23"
> dependency "derelict-glfw3"   version="~>3.1.3"
> dependency "derelict-util"    version="~>2.0.6"
> dependency "gl3n"             version="~>1.3.1"
>   .............
>
>
> But when I look the directory that has the dub.sdl file, I also see a file called dub.selections.json
>
> {
> 	"fileVersion": 1,
> 	"versions": {
> 		"derelict-al": "1.0.3",
> 		"derelict-assimp3": "1.3.0",
> 		"derelict-fi": "2.0.3",
> 		"derelict-fmod": "2.0.4",
> 		"derelict-ft": "1.1.3",
> 		"derelict-gl3": "1.0.23",
> 		"derelict-glfw3": "3.1.3",
> 		"derelict-util": "2.0.6",
> 		"gl3n": "1.3.1"
> 	}
> }
>
>
> So how did this .json file get created and can I just delete it?  I only noticed this because when I was troubleshooting the project, I changed the dub.sdl library versions but the compile/run was using the library versions in dub.selections.json.
>
> I did switch from using DMD to LDC, if that has any bearing.

dub.selections.json is basically broken design, once it's there it will ignore any version value you write in dub.json/dub.sdl until you dub upgrade. This can lead to many bugs very easily, but just remember to dub upgrade every time you change versions and it will be fine.

dub.selections.json stores the versions which got picked when first adding the dependency so that others can get the same version of the dependency and should hopefully get a working build if you managed to build it. The two major problems: if your new version range doesn't actually allow that version anymore dub will still use it anyway until you dub upgrade. Second it doesn't even store commit hashes when using ~master. So basically assuming the dependency author properly uses SemVer (don't break backwards compatibility on minor releases) and your version range only accepts minor updates it is literally nonsense to freeze the package on a minor version if your range allows a higher version. Basically you are missing security patches if you use dub.selections.json

To be honest I wouldn't push it to git, it keeps changing, always only gives conflicts and breaks things, especially when using "path". But the dub devs say it should be pushed, though I have never seen anything good come out of it.
December 19, 2017
On 2017-12-18 23:57, WebFreak001 wrote:

> dub.selections.json is basically broken design

The design is fine, not so sure about the implementation. I've explain many time before why it's necessary.

-- 
/Jacob Carlborg
December 19, 2017
On 2017-12-18 23:36, WhatMeWorry wrote:
> 
> I've been using Dub for a while but from the very beginning I decided to go with SDL 100% of the time, So I've got a dub.sdl file like:
> 
> name "01_10_camera_view_space"
> description "A minimal D application."
> authors "kheaser"
> copyright "Copyright © 2017, kheaser"
> license "proprietary"
> 
> dependency "derelict-al"      version="~>1.0.3"
> dependency "derelict-assimp3" version="~>1.3.0"
> dependency "derelict-fi"      version="~>2.0.3"
> dependency "derelict-fmod"    version="~>2.0.4"
> dependency "derelict-ft"      version="~>1.1.3"
> dependency "derelict-gl3"     version="~>1.0.23"
> dependency "derelict-glfw3"   version="~>3.1.3"
> dependency "derelict-util"    version="~>2.0.6"
> dependency "gl3n"             version="~>1.3.1"
>    .............
> 
> 
> But when I look the directory that has the dub.sdl file, I also see a file called dub.selections.json
> 
> {
>      "fileVersion": 1,
>      "versions": {
>          "derelict-al": "1.0.3",
>          "derelict-assimp3": "1.3.0",
>          "derelict-fi": "2.0.3",
>          "derelict-fmod": "2.0.4",
>          "derelict-ft": "1.1.3",
>          "derelict-gl3": "1.0.23",
>          "derelict-glfw3": "3.1.3",
>          "derelict-util": "2.0.6",
>          "gl3n": "1.3.1"
>      }
> }
> 
> 
> So how did this .json file get created and can I just delete it?
You should keep it. If you have developed an application it should be committed to git, if it's a library it should not be committed.

-- 
/Jacob Carlborg
August 03, 2018
On Tuesday, 19 December 2017 at 10:15:18 UTC, Jacob Carlborg wrote:
> On 2017-12-18 23:36, WhatMeWorry wrote:
[...]
>> 
>> But when I look the directory that has the dub.sdl file, I also see a file called dub.selections.json
>> 
>> {
>>      "fileVersion": 1,
>>      "versions": {
>>          "derelict-al": "1.0.3",
>>          "derelict-assimp3": "1.3.0",
>>          "derelict-fi": "2.0.3",
>>          "derelict-fmod": "2.0.4",
>>          "derelict-ft": "1.1.3",
>>          "derelict-gl3": "1.0.23",
>>          "derelict-glfw3": "3.1.3",
>>          "derelict-util": "2.0.6",
>>          "gl3n": "1.3.1"
>>      }
>> }
>> 
>> 
>> So how did this .json file get created and can I just delete it?
> You should keep it. If you have developed an application it should be committed to git, if it's a library it should not be committed.

But if you commit it, and a compiler deprecation causes a dependency in that pinned version to fail to compile, then your app won't compile either, even though your code itself does not suffer from the deprecation and even though a newer release of the dependency is available that solves the deprecations. This means that, if your app is on code.dlang.org, people won't be able to dub fetch && dub run.

What advantages does committing dub.selections.json have that outweigh this disadvantage?

It would be OK if dub.selections.json would also pin the compiler version and there were a standard way to select that version (like dvm, but without its shortcomings).

For example, scod 0.4.4 does not compile with dmd 2.081.1 because of this (https://github.com/MartinNowak/scod/issues/14). Its latest change to dub.selections.json is only three months old, to make it work with dmd 2.080.0. This illustrates that if you're unlucky, you may have to bring out frequent new releases with updates to dub.selections.json (through "dub upgrade") even though your app is stable and doesn't change.
August 04, 2018
On 2018-08-03 21:41, Bastiaan Veelo wrote:

> But if you commit it, and a compiler deprecation causes a dependency in
> that pinned version to fail to compile, then your app won't compile
> either, even though your code itself does not suffer from the
> deprecation and even though a newer release of the dependency is
> available that solves the deprecations. This means that, if your app is
> on code.dlang.org, people won't be able to dub fetch && dub run.
>
> What advantages does committing dub.selections.json have that outweigh
> this disadvantage?

The advantage is you get the same application every time, now and six months later. If the dependencies are not pinned you might get updated dependencies that break your build, or even worse, the build passes but the application behaves differently.

-- 
/Jacob Carlborg
August 04, 2018
On Friday, 3 August 2018 at 19:41:32 UTC, Bastiaan Veelo wrote:
> But if you commit it, and a compiler deprecation causes a dependency in that pinned version to fail to compile, then your app won't compile either, even though your code itself does not suffer from the deprecation and even though a newer release of the dependency is available that solves the deprecations. This means that, if your app is on code.dlang.org, people won't be able to dub fetch && dub run.

This is also true if the dependency gets a major version bump and then gets updated for a breaking compiler change.

If the dependency range is broad enough, you can `dub upgrade && dub run`.

> What advantages does committing dub.selections.json have that outweigh this disadvantage?

Dependencies don't always follow semantic versioning. For instance, a binding for a C library that is actively developed might reasonably follow the bound library's versioning. Or the maintainer might make a mistake and commit a breaking change without bumping to a new major version.

This is why my top-level projects these days have specific versions of dependencies rather than the more commonly used ranges. I'm only going to test against those specific versions, so why should I claim that my application can use future versions?

> It would be OK if dub.selections.json would also pin the compiler version and there were a standard way to select that version (like dvm, but without its shortcomings).

That would be good. If I were less lazy, I could add that to dub. It already manages packages; the compiler is just a slightly different dependency.
August 05, 2018
On Saturday, 4 August 2018 at 17:53:45 UTC, Neia Neutuladh wrote:
> On Friday, 3 August 2018 at 19:41:32 UTC, Bastiaan Veelo wrote:
>> But if you commit it, and a compiler deprecation causes a dependency in that pinned version to fail to compile, then your app won't compile either, even though your code itself does not suffer from the deprecation and even though a newer release of the dependency is available that solves the deprecations. This means that, if your app is on code.dlang.org, people won't be able to dub fetch && dub run.
>
> This is also true if the dependency gets a major version bump and then gets updated for a breaking compiler change.
>
> If the dependency range is broad enough, you can `dub upgrade && dub run`.

You mean the dependency range in dub.selections.json of an app on code.dlang.org? I would be in favour of it being a range, but I think that is unusual. Usually people just commit the generated file unedited, which seems to always be pinned to the patch level?

Anyway, dub documentation could be a lot more verbose on dub.selections.json :-)

>> What advantages does committing dub.selections.json have that outweigh this disadvantage?
>
> Dependencies don't always follow semantic versioning. For instance, a binding for a C library that is actively developed might reasonably follow the bound library's versioning. Or the maintainer might make a mistake and commit a breaking change without bumping to a new major version.
>
> This is why my top-level projects these days have specific versions of dependencies rather than the more commonly used ranges. I'm only going to test against those specific versions, so why should I claim that my application can use future versions?

I know that failing to build is better than potential erroneous execution, so I understand the rationale. It’s just that I get build failures after updating to the newest compiler often enough that it's frustrating. Build failures in tools that I use in my build that is, like dfmt, ddox, scod.

>> It would be OK if dub.selections.json would also pin the compiler version and there were a standard way to select that version (like dvm, but without its shortcomings).
>
> That would be good. If I were less lazy, I could add that to dub. It already manages packages; the compiler is just a slightly different dependency.

Apart from solving this problem, there are other advantages:
1. It would make it possible to check out an older version of your software and compile it without problems, and be sure that it results in the same binary as when that version was committed.
2. You can easily work with different compilers in different branches. Like using ldc in the release branch of your CI and dmd in your feature branch, or work on porting to a different compiler outside the master branch.

But since dub is distributed with the compiler, handling the compiler as a dependency might not be straightforward. How would you prevent getting trapped in an old version when dub downgrades itself? Which of the installed dub versions du you use to do dub upgrade? How would dub appear in dub.selections.json?

If you have ideas on this, I am genuinely interested.

-Bastiaan
August 05, 2018
On 2018-08-05 10:30, Bastiaan Veelo wrote:

> You mean the dependency range in dub.selections.json of an app on
> code.dlang.org? I would be in favour of it being a range, but I think
> that is unusual. Usually people just commit the generated file unedited,
> which seems to always be pinned to the patch level?

It should be pinned down to the patch level, that's the whole point. The file should not be edited manually.

> Anyway, dub documentation could be a lot more verbose on
> dub.selections.json :-)

That wouldn't hurt.

-- 
/Jacob Carlborg