Skip to content

Instantly share code, notes, and snippets.

@pftg
Last active March 9, 2023 19:56
Show Gist options
  • Save pftg/fa8fe4ca2bb4638fbd19324376487f42 to your computer and use it in GitHub Desktop.
Save pftg/fa8fe4ca2bb4638fbd19324376487f42 to your computer and use it in GitHub Desktop.
Update indirect dependencies in yarn.lock. `ruby rejuvenation.rb & yarn install`
#!/usr/bin/env ruby
# USAGE: `$> ruby rejuvenation.rb`
require 'json'
EXTRACT_DEPENDENCY_NAME = /"?(.+?)@.+?"?(?:,\s+|\Z)/.freeze
EXTRACT_DEPENDENCY_DETAILS = /(^((?!= ).*?):\n.*?(?:\n\n|\Z))/m.freeze
def direct_dependencies_names
package_json = JSON.parse(File.open('package.json').read)
direct_dependencies = package_json.fetch_values('dependencies', 'devDependencies', 'peerDependencies') { }
direct_dependencies.compact.inject([]) { |memo, v| memo.concat(v.keys) }
end
@dependencies = direct_dependencies_names
yarn_lock_content = File.open('yarn.lock').read
File.open('yarn.lock', 'w') do |file|
yarn_lock_content.scan(EXTRACT_DEPENDENCY_DETAILS).map do |dependency_block|
direct_dep = @dependencies.include?(dependency_block[1].match(EXTRACT_DEPENDENCY_NAME).to_a[1])
file.puts dependency_block[0] if direct_dep
end
end
`yarn install`
$> curl "https://gist.githubusercontent.com/pftg/fa8fe4ca2bb4638fbd19324376487f42/raw/f9056244c416d2f56d6d94290e5ecef5960abf66/rejuvenation.rb" | ruby

or

$> ruby rejuvenation.rb
$> yarn install
@pftg
Copy link
Author

pftg commented Mar 9, 2023

@gordonmessmer yarn v1 upgrade will upgrade only packages defined in pacakge.json, but it does not care about indirect dependencies.
For example, you have in your package.json Av1 package, and there are such indirect dependencies:

Av1 -> Bv1 -> Cv1

Let's assume that C has a new version, Cv2, and you would like to use it. But yarn upgrade does not provide such a feature.
It can upgrade to Av2 only, and have like: Av2 -> Bv1 -> Cv2

So this snippet helped guys to upgrade to Cv2, but without upgrading to A and have: Av1 -> Bv1 -> Cv2

@gordonmessmer
Copy link

yarn v1 upgrade will upgrade only packages defined in pacakge.json, but it does not care about indirect dependencies.

If I run "yarn upgrade" v1 in a local environment, it updates both direct dependencies defined in packages.json and indirect dependencies defined by those modules.

So this snippet helped guys to upgrade to Cv2, but without upgrading to A and have: Av1 -> Bv1 -> Cv2

That makes sense. So, this script will allow you to update the indirect dependencies only and leave the direct dependencies at their currently-locked versions.

When is that better than listing specific versions in packages.json and using "yarn upgrade"?

@pftg
Copy link
Author

pftg commented Mar 9, 2023

It’s hard to set package versions for some indirect dependencies, as I recall something related to work with terminal or other legacy deps.

For example:

Av1 -> Bv1 -> Cv0.1.0
Av1 -> Dv1 -> Cv1.0.0

And you got new security patch Cv1.0.1 and Cv0.1.1

For big and uniq indirect dependencies better if you would put them into package.json, but again, js packages is a big mess.

@gordonmessmer
Copy link

It’s hard to set package versions for some indirect dependencies

I don't understand how the conversation turned to controlling the versions of indirect dependencies, when both "yarn upgrade" and this script will result in updating indirect dependencies to the newest available version allowed by their selectors, which seems like the best option in most cases.

@pftg
Copy link
Author

pftg commented Mar 9, 2023

Yarn does not upgrade indirect versions, it will eventually installs last indirect version when you are upgrading version from package.json. I think more details you can find in yarnpkg/yarn#4986

So you can use this script in cases when you cannot add them into list. One of the cases when the same package have more then 2 versions in the project and they have breaking changes, you cannot use one package to replace both.

@gordonmessmer
Copy link

Yarn does not upgrade indirect versions

As niklasholm and others have stated in that thread, that isn't true. "yarn upgrade" will upgrade indirect dependencies. The issue you linked to is a request for enhancement that would allow yarn to upgrade specific indirect dependencies without upgrading all of them.

But upgrading all of the indirect dependencies is what your script appears to do, and what "yarn upgrade" does.

@pftg
Copy link
Author

pftg commented Mar 9, 2023

Yeah you are right. This script had been created before, yarn could upgrade indirect deps. So now it’s redundant even for
v1

@pftg
Copy link
Author

pftg commented Mar 9, 2023

@gordonmessmer thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment