How to set the version of my project? - composer-php

How do I set the version and stability of my composer project?
I assumed this would be done in the composer.json file, but none of the popular frameworks seem to have anything in there indicating the version of the current project, just their dependencies. How do I set it?

The documentation is buried under a section called "tags".
Basically, the preferred method of adding versions is by creating a VCS tag that "looks" like a version. Composer will read these tags and determine the version based on that.

Related

Gradle dependency library updated by another library

My gradle has for some time had a dependency on the (amazing) Android library Picasso. It has always been set to version 2.5.2
implementation 'com.squareup.picasso:picasso:2.5.2'
I recently updated all my Firebase libraries from a fairly old version to the latest. At which point something odd happened.
My Picasso method calls began to error
Picasso.with(context)
Which I know from this SO article results from a change to Picasso.
cannot find symbol method with() using picasso library android and I need to change to
Picasso.get()
OK not a big deal, but it got me wondering. Obviously Firebase uses the latest version of Picasso and is making my project use the latest version as well. My question is why is my local gradle file ignored and the newer version of Picasso defaulted to?
Off the top of my head: Since you declare a specific version that requirement is not flexible. To allow for a newer version if available a + declaration is required. My guess is that another dependency is also dependent on Picasso after the updates. Gradle, when given a redundant dependency, will select the newer version.
This is in alignment with what you said, if I understand correctly. If Firebase uses a newer Picasso version, because it requires that version, then Gradle is given two versions to choose one from. This will always result in the newer version being chosen. At least this is default behavior afaik.
It seems to me that you already know Picasso is used by Firebase. If you want to see where which dependency comes from however, you can look into build scans:
gradle build --scan
https://scans.gradle.com/?_ga=2.166196030.1236003146.1565212874-222812074.1565212874
A little bit more advanced dependency management:
1) Set Gradle behavior on dependency conflict:
https://docs.gradle.org/current/dsl/org.gradle.api.artifacts.ResolutionStrategy.html
2) Declare version constraints (see Rich version declaration):
https://docs.gradle.org/current/userguide/declaring_dependencies.html
You can check the official doc:
Gradle resolves version conflicts by picking the highest version of a module. Build scans and the dependency insight report are immensely helpful in identifying why a specific version was selected.

What are the workarounds when Composer dependencies conflict in versions?

My projects depends on two packages, A and B, and they both depend on some-library, unfortunately in incompatible versions:
A depends on lib # 1.0
B depends on lib # 2.0
This is unresolvable by Composer because PHP can only load a single version of a class / interface at runtime.
What are my options? I am fine with "ugly" workarounds as long as they are automated. Doing fragile and manual work like forking A and upgrading its usage of some-library is something I'd like to avoid at all costs.
There are no workarounds. By design, Composer assumes that your project uses consistent dependencies and everything is maintained valid.
As mentioned in the comments, you can prefix the dependencies to isolate the part of the project that needs a particular library version. In this way, the prefixed code is consistent in Composer terms and you can continue developing with the latest versions.
These are a couple of prefixers that I can recommend:
humbug/php-scoper is a well-known tool that can prefix code based on Search & Replace steps (Finders and Patchers).
PHP-Prefixer is an automated online service to apply prefixes to Composer dependencies, based on composer.json definitions. You define the new namespace and prefix for your project.
Disclaimer: I'm the lead PHP-Prefixer developer.

How do I determine which levels are available for a given dependency?

I'm relatively new to Android Studio and find myself very confused about the levels for dependencies in Gradle. Let me explain why, then I am seeking assistance with a specific issue and the broader issue of choosing dependency levels. I should mention that I am using Android Studio 3.1.3 with Gradle 4.4. My Min SDK Level is 24 and my compile level is 27).
I am doing my first experiments with Settings and have skimmed several tutorials (online and in YouTube). They all begin with the advice that you need to add a dependency for Preferences in your Gradle file. (They aren't consistent in WHICH dependency to add but I think that's because there are different approaches to doing preferences.) In any case, once you've chosen which approach you are going to take, you need to add the appropriate dependency to your build.gradle (Module app) file.
So, let's say we decide to add com.android.support:preference. According to the manual - https://developer.android.com/reference/android/support/v7/preference/Preference - the current version is v7:28.0.0-alpha1. If I add that to the Gradle file though and try to sync, Android Studio tells me I should not let the dependency be a higher level than the compile SDK level (which is 27).
So, I imitated the level that I used in other dependencies, like appcompat, and set the level to v7:27.1.1 and tried to sync again. That failed too. Apparently, no such version of the dependency exists.
Most of the tutorials I've seen are two years old and refer to dependencies that are at level 24, which I assume is going to be too low.
And that brings me to my question: How do I determine which versions of a dependency actually exist so that I can choose an appropriate level?
I read through this page on the Android developer site and I suspect you may have the syntax wrong for the dependency. The v7 should be part of the module name, not the version as I understand it.
Try:
dependencies {
implementation "com.support.android-v7:27.1.1"
}
This page makes reference to palette-v7:27.1.1 so I assume the same version exists for preference.

Ordering when using dynamic versions in gradle + beta versions

In a gradle file it's possible to specify a dependency with a dynamic version, like:
compile 'some.dependency:name:1.+'
This is documented to resolve the "newest" matching version. I have two questions:
[1] What does "newest" mean? Suppose the available versions are:
1.0
1.1-beta
1.1
Is the "newest" one 1.1-beta or 1.1? Does it depend at all on when the versions were published, or is it purely based on the version strings? If purely based on the strings, what ordering is used, because if it's just alphabetical then I think 1.1-beta would end up being "newer" than 1.1.
[2] As a publisher of a module, is there a sensible way of publishing a beta build such that developers who are depending on your module and using dynamic versions wont automatically pick it up? Is there a standard or recognized way of doing this?
Thanks!
[I'm aware using dynamic versions is discouraged. These questions are from the point of view of someone providing a module, and wanting to ensure that developers who do use it and ignore this advice still don't end up pulling in something unexpected]
I' m guessing you are publishing to maven, and as I know, there should be an xml file named maven-metadata.xml which holds the information of the latest upload to the corresponding artifact. So I guess it does not depend on your naming convention but what you upload the latest. If you would upload 1.0.0.1 the latest then it would be downloaded not 1.1-beta or 1.1 versions.
For more info check here.

Maven Resources Plugin symbolic link handling

In the src/test/resources folder of a maven project there's a relative symbolic link.
With the 2.6 version of the plugin, the actual file is copied.
After updating to the 3.0.1 version, it copies the link instead of the file and on a subsequent run (without clean) fails (mvn -e shows it's because of a FileAlreadyExistsException).
Is there any config option to restore the behavior from the previous version ?
I agree, having a link as a test resource is a really bad idea.
This is a known bug in the maven-resources-plugin: MRESOURCES-237 Resource plugin’s handling of symbolic links changed in 3.0.x, broke existing behaviour, unfixed but known for 1½ years.
Unfortunately, there’s not (yet) a configuration option. Introducing it (and defaulting it to “follow symlinks” instead of copy-preserving them) would fix this issue.
For now, the only solution is to downgrade the maven-resources-plugin. I also upgraded from 2.6, and have just now downgraded to 2.7 (last of the 2.x series), and can confirm that it works around this bug and properly copies the symlinks’ contents.
Update: due to the “Mark invalid” issue (a bug in maven-filtering) you should consider staying with 2.6 if you don’t need any of the new 2.7 features, or have to amend the plugin definition with an updated dependency on maven-filtering 1.3 (or maybe newer).

Resources