Why not make versions fixed in bower.json - bower

I know most projects have minimum versions defined in bower.json for a lot of libraries.
Something I don't understand is that would this be risky that if something updates and have break-changes or bugs, it will affect your application without you knowing it? What is the design thinking behind this?
Thanks!

We have just faced that exact issue on a project I am on, and the solution was to change our bower.json file to target fixed versions.
Specifically, we were targeting angularjs ^1.4.8. In AngularJS v1.6,
$location now uses '!' as the default hash-prefix for hash-bang URLs,
instead of the empty string
For better or for worse (mostly for worse) we had some hard-coded urls in a different application that pointed to this project that broke once bower automatically installed AngularJS 1.6 as part of our automated build process.
The solution was to simply lock down our versions rather than relying on the latest bug fix (i.e prefixing version numbers with ~) or minor build (i.e. prefixing version numbers with ^).
I think the reason that package managers like bower and npm default to dynamic versions is that they rely on semantic versioning, and in theory you should only encounter breaking changes when the major version number changes. Semver uses a major, minor, bugfix pattern. When the bugfix value is incremented it indicates that one or more backwards-compatible bugs have been resolved. When the minor version is incremented it indicates that new backwards-compatible functionality has been added. When the major version is incremented it indicates that new, breaking changes have been introduced.
The problem with this is that firstly, it relies on the package developer to respect the semver rules when they make changes to their packages, and secondly, even when semver is respected it can still lead to problems (as in the example I provided above).

Related

How to upgrade NuGet packages without breaking my project?

I have an old MVC application I need to make changes to. It would be nice to update all the recommended NuGet packages, but I know from experience that this can break a project.
In particular, I'm troubled by the following:
If one reads this a certain way, it appears that it's actually suggesting I upgrade to Twitter Bootstrap 5.1.2. I know for a fact that numerous breaking changes have been implemented since my current version.
I prefer not to have to rewrite the site. I thought Updates might have been a little smarter. Do I really need to know each package well enough to know if it would include breaking changes? Is there no way to specify compatible updates? Did Microsoft consider this aspect?
You do need to know each package well enough. Why? Because there's not a single way of doing versioning. Some packages, probably a lot of packages even, follow Semantic Versioning, but there's nothing to stop anyone from using any versioning they want (even if it doesn't make sense). There's nothing preventing you from going 3.0.1 to 15.14.13 with a change in an unimportant .txt file.
It's your responsibility to know what to update and when. Look at this Q&A to see how you can restrict the versions suggested: NuGet Limit max major version of a package

In the Flutter what is best way to add package in pubspec.yaml file?

In flutter I'm little bit concussion to add package.
Rather than add package with version, is it best way to add package without version in pubspec.yaml file?
Might be, By default it will acquire latest version. But what happen when after adding new version will be available?
You can omit the version or use any, but it's a good idea to add a version range.
Avoid updates breaking your app/package
Specifying a version constraint helps to avoid unexpected breaking your app by running flutter packages get when new dependency versions become available that contain breaking changes (are not compatible with your old code).
You can then intentionally extend the version range for a dependency when you align your code to the new version of the dependency.
Dart and packages are supposed to follow Semantic Versioning which means when an update contains a breaking change, the major version number needs to be incremented.
For versions below 1.0.0 incrementing the minor version number indicates a breaking change.
The ^ is a shortcut to define a version range that indicates the defined version and all later versions that don't contain breaking changes.
So usually you would use
some_dependency: ">=2.0.0 <3.0.0"
or short
some_dependency: ^2.0.0
If some update fixes a bug in 2.1.0 that your application or package depends on you can use
some_dependency: ">=2.1.0 <3.0.0"
or short
some_dependency: ^2.1.0
Performance
Specifying a narrow version constraint also can make flutter packages get/upgrade faster especially when your application contains a lot of dependencies because this reduces the search space for packages get/upgrade that it needs to traverse to find a compatible set of dependencies.
Missing functionality
Please upvote https://github.com/flutter/flutter/issues/12627 to get proper information from flutter packages get/upgrade when newer dependency versions are available than your constraints allow (like pub get/upgrade does for non-Flutter Dart projects)
See also
https://www.dartlang.org/tools/pub/versioning
What does plus one (+1) mean in dart's dependency versioning

microsoft teamfoundation GAC assembly, same version/key but different content

I ran into a situation where two machines both had "microsoft.teamfoundation.testmanagement.client.dll" in the GAC with the same version and public key. They differed in the content they contained though. The newer one had additional classes (e.g. BuildCoverage). Why would the content of the dll change while the version and public key stay the same? Is this common practice?
I don't know if it's common practice, but there are times when the AssemblyVersion (for Strong naming) isn't incremented during an "in-place" minor update to a GAC'd assembly to hot-fix a bug. Check the actual File Version by navigating to the file via command prompt and then checking it's properties. See if there's a difference between the files there. That should indicate if the actual build number is different between them. I bet a small VS hotfix has been applied to one and not another.
It's very normal to update an AssemblyFileVersion but not update the AssemblyVersion attribute. This is how hotfixes for .NET get shipped for example. The key is to test the hell out of the assembly to make sure it's completly backwards compatible to prevent DLL hell.

Best practices for using SVN with Delphi Visual Component packages?

With the desire to be able to reproduce a given revision of a project that is utilizing 3rd party visual component packages, what goes in SVN and what's the best way to implement/structure the SVN repos?
For non-visual components, the rule seems simple to ensure no reliance on outside repos - "no svn-externals reference to any outside repo allowed". I have a shared repo that I control, which is the only 'svn-externals' reference allowed. This makes it easy to implement and share these types of runtime itemss with sourcecode in different SVN projects. Any reference this internal shared repo is by 'svn-externals' using a specific revision number.
Visual packages seem to go counter to being able to be version controlled easily as they may have to be reinstalled at each revision. How to best create a SVN project which is able to be recreated later at a specific revision number...is there a recommended solution?
Previously we didn't worry about 3rd party components as they don't change often and we never had a real good solution. I was wondering if others have figure out the best way to handle this problem as I'm doing a spring cleaning/internal reorganization and wanted to do it 'better' than before.
Technically, the RTL/VCL source should also be in the SVN repo as well (if there's a Delphi hotfix/service pack released.)
My solution will likely be to create a virtual machine with a particular release of the Delphi environment with all visual controls installed. As we add/update visual controls, or update Delphi with hotfixes/service packs then we create a new version of the virtual machine. We then store an image of this VM revision on a shelf somewhere. Is this what you do? Does the Delphi activation/licensing work well (or at all) in this scenario?
Thanks,
Darian
You can prepare "start IDE" (and possibly "build") scripts for your projects and maintain them as project evolves in repository.
Regardless of your decision about keeping components in separate repositories and using externals, or including them in a single repository with possible branching, you should also include compiled bpl files for every component build and for every branch prepared for a specific Delphi version.
You should definitely try to keep most (if not all) of paths relative, in a worst case use environment variables to point to your root project dir.
Start IDE script allows you to keep each project and Delphi version environment spearately configured on a single Windows installation.
It should include necessary registry keys for your project and Delphi:
Windows Registry Editor Version 5.00
[-${DelphiRegKey}\Disabled Packages]
[-${DelphiRegKey}\Known Packages]
[-${DelphiRegKey}\Library]
[${DelphiRegKey}\Known Packages]
"$(BDS)\\Bin\\dclstd${CompilerVersion}.bpl"="Borland Standard Components"
"$(BDS)\\Bin\\dclie${CompilerVersion}.bpl"="Internet Explorer Components"
"$(BDS)\\Bin\\dcldb${CompilerVersion}.bpl"="Borland Database Components"
(...)
"${CustomComponentPack}"="Custom Components"
[${DelphiRegKey}\Library]
"Search Path"="${YourLibrarySourceFolder1};${YourLibrarySourceFolder2}"
(...)
You can then prepare batch file:
regedit /s project.reg
%DelphiPath%\bin\bds -rProjectRegKey Project.dpr
Where ${DelphiRegKey} is HKEY_CURRENT_USER\Software\Borland(or CodeGear in newer versions)\ProjectRegKey.
Basically it is easier when you will dump your current working configuration from registry, strip it from unnecessary keys, change paths to relative and then adapt to make it work with your project.
In such configuration, switching between projects and their branches which have different sets of components (and/or possibly using different Delphi version) is a matter of checking out a repository only and running the script.
Fortunately for us, we don't have to worry about a hotfix/service pack; we're still on Delphi 5. :D
Sigh, there was a time when an entire application (settings and all) would exist within a single directory - making this a non-issue. But, the world has moved on, and we have various parts of an application scattered all over the place:
registry
Windows\System
Program Files
Sometimes even User folders in "Application Data" or "Local Settings"
You are quite right to consider the impact of hotfixes/service packs. It's not only RTL/VCL that could be affected, but the compiler itself could have been slightly changed. Note also that running on the same line of thought, even when you upgrade Delphi versions, you need to build using the correct version. Admittedly this is a little easier because you can run different Delphi versions alongside each other.
However, I'm going to advise that it's probably not worth going to too much effort. Remember, working on old versions is always more expensive than working on the current version.
Ideally you want all your dev to be be on main branch code, you want to minimise patch-work on older versions.
So strive to keep the majority of your users on the latest version as much as possible.
Admittedly this isn't always possible.
You wouldn't want to jump over to the 'new version' without some testing first in any case.
Certain agile processes do tend to make this easier.
By using a separate build machine or VM, you already have a measure of control.
TIP: I would also suggest that the build process automtically copy build output to a different machine, or at least a different hard-drive.
Once you're satisfied with the service pack, you can plan when you want to roll it to your build machine.
It is extremely important to keep record of the label at which the build configuration changed. (Just in case.)
If your build scripts are also kept in source control, this happens implicitly.
When you've rolled out the hotfix/service pack, fixes to older versions should be actively discouraged.
Of course, they probably can't be eliminated, but if it's rare enough, then even manual reconfiguration could be feasible.
Instead of a VM option to keep your old configuration, you can also consider drive-imaging.
To save on the $$$ of VMWare LabManager, look for a command-line driven VM Player.
You might have to keep 2 "live" machines/VMs, but should never need more than that.
It's okay for an automatic build script to fail because the desired configuration isn't available. This will remind you to set it up manually.
Remember, working on old versions is always more expensive than working on the current version.
Third Party Packages
We went to a little bit more effort here. One of our main motivations though was the fact that we use about 8 third party packages. So doing something to standardise this in itslef made sense. We also decided running 8 installation programs was a PITA, so we devised an easy way to manually install all required packages from source-control.
Key Considerations
The build environment doesn't need any packages installed, provided the object and/or source files are accessible.
It would help if developers could fairly easily ensure they're building with the same version of third party libraries when necessary.
However, dev environments usually must install packages into the IDE.
This can sometimes cause problems with source compatibility.
For example new properties that get written to IDE maintained files.
Which of course brings us back to the second point.
Since Third Party packages are infrequently updated, they are placed within a slightly different area of source-control.
But, NB must still be referenced via relative paths.
We created the following folder structure:
...\ThirdParty\_DesignTimePackages //The actual package files only are copied here
...\ThirdParty\_RunTimePackages //As above, for any packages "required" by those above
...\ThirdParty\Suite1
...\ThirdParty\Suite2
...\ThirdParty\Suite3
As a result of this it's quite easy to configure a new environment:
Get latest version of all ThirdParty files.
Add _DesignTimePackages and _RunTimePackages to Windows Path
Open Delphi
Select Install Components
Select all packages from _DesignTimePackages.
Done!
Edit: Darian was concerned about the possibility of errors when switching switching versions of Design Packages. However, this approach avoids those kinds of problems.
By adding _DesignTimePackages and _RunTimePackages to the Windows Path, Delphi will always find required packages in the same place.
As a result, you're less likely to encounter the 'package nightmare' of incompatible versions.
Of course, if you do something silly like rebuild some of your packages and check-in the new version, you can expect problems - no matter what approach you follow.
I usually structure my repository in SVN like this:
/trunk/app1
/trunk/comp/thirdparty1
/trunk/comp/thirdparty2
/trunk/comp/thirdparty3...
I have, right in the root folder (trunk) a project group (.groupproj, or .bpg on old delphi) that contains all my components. (allcomponents.groupproj).
Installing on a new machine, means opening that package, and installing the designtime components. That's a drag on all versions of Delphi older than 2010, but 2010 and XE have a lovely feature so you can see at a glance, which components are designtime components.
I also, sometimes, will save myself the trouble of installing those components by hand, by making a build.bat file, and a regcomponents.bat file. The regcomponents just runs regedit , and imports the keys needed to register all those components, after build.bat has built them, and everything else.
When you move up from one delphi version to another, it's sure good to have both a batch and reg file, and a group project, to help you. Especially if you have to go through and do a lot of opening of project/packages and saving them as MyComponent3.dpk instead of MyComponent2.dpk, or updating the package extension from 150 to 160, or whatever your packages do.

File Version Vs. Product Version

In the Delphi Project Properties dialog, there are settings for the "Product Version" and the "File Version". Can anyone explain the philosophical differences between the two?
The Product Version will be the version number of your whole application.
The File Version will be the version number of this component.
The two are usually in sync, but don't have to be. It would depend upon how modular your application was.
So for example you might have an application that's at version 2.3.4.0 (say), but one file reader component that's at version 5.6.7.0 as it was inherited from a different application and another at version 1.2.0.0 as it's a more recent addition.
Additionally, some components might not change between releases so theoretically they should remain at their original file version.
However, as this might well cause confusion (not least with the developer) about which file goes with which version of the product these numbers are often kept in sync.
Not all the files are to be changed when the product version changes.
E.g. you've written a dll implementing the core functionality that remains unchanged during following product version changes.
Product version is the version of the product the executable is a part of, like Firedox 3.5.2 - all files in the product should have the same version (for a given version, obviously). The file version is normally the version of the specific file, like the firefox executable, for example, without respect to the product. This doesn't seem to get used much.
In contrast to the file version the product version is not necessarily numerical. E.g. we use the pre-build scripts to set it to the current date. This way, we can easily check when an executable was built.

Resources