summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Rodríguez <deivid.rodriguez@riseup.net>2025-08-05 18:32:44 +0200
committerHiroshi SHIBATA <hsbt@ruby-lang.org>2025-09-03 23:38:37 +0900
commit3b6c82ca4f6ee915e670c5be2342b10ed99c5844 (patch)
treeb24588042302d5640e36a7ff9d837f0549118728
parent834b941253b0da4e162c4fc318559f5cb545aadd (diff)
Completely remove `bundle viz` command
-rw-r--r--lib/bundler.rb1
-rw-r--r--lib/bundler/cli.rb20
-rw-r--r--lib/bundler/cli/viz.rb31
-rw-r--r--lib/bundler/graph.rb152
-rw-r--r--lib/bundler/man/bundle-viz.130
-rw-r--r--lib/bundler/man/bundle-viz.1.ronn36
-rw-r--r--lib/bundler/man/bundle.13
-rw-r--r--lib/bundler/man/bundle.1.ronn3
-rw-r--r--lib/bundler/man/index.txt1
-rw-r--r--spec/bundler/commands/viz_spec.rb144
-rw-r--r--spec/bundler/other/major_deprecation_spec.rb9
-rw-r--r--tool/bundler/test_gems.rb1
-rw-r--r--tool/bundler/test_gems.rb.lock6
13 files changed, 6 insertions, 431 deletions
diff --git a/lib/bundler.rb b/lib/bundler.rb
index 761679ec8d..f5b2abcd10 100644
--- a/lib/bundler.rb
+++ b/lib/bundler.rb
@@ -54,7 +54,6 @@ module Bundler
autoload :FREEBSD, File.expand_path("bundler/constants", __dir__)
autoload :GemHelper, File.expand_path("bundler/gem_helper", __dir__)
autoload :GemVersionPromoter, File.expand_path("bundler/gem_version_promoter", __dir__)
- autoload :Graph, File.expand_path("bundler/graph", __dir__)
autoload :Index, File.expand_path("bundler/index", __dir__)
autoload :Injector, File.expand_path("bundler/injector", __dir__)
autoload :Installer, File.expand_path("bundler/installer", __dir__)
diff --git a/lib/bundler/cli.rb b/lib/bundler/cli.rb
index 38264c6ebe..8acf25eba6 100644
--- a/lib/bundler/cli.rb
+++ b/lib/bundler/cli.rb
@@ -513,23 +513,9 @@ module Bundler
end
end
- unless Bundler.feature_flag.bundler_4_mode?
- desc "viz [OPTIONS]", "Generates a visual dependency graph", hide: true
- long_desc <<-D
- Viz generates a PNG file of the current Gemfile as a dependency graph.
- Viz requires the ruby-graphviz gem (and its dependencies).
- The associated gems must also be installed via 'bundle install'.
- D
- method_option :file, type: :string, default: "gem_graph", aliases: "-f", banner: "The name to use for the generated file. see format option"
- method_option :format, type: :string, default: "png", aliases: "-F", banner: "This is output format option. Supported format is png, jpg, svg, dot ..."
- method_option :requirements, type: :boolean, default: false, aliases: "-R", banner: "Set to show the version of each required dependency."
- method_option :version, type: :boolean, default: false, aliases: "-v", banner: "Set to show each gem version."
- method_option :without, type: :array, default: [], aliases: "-W", banner: "Exclude gems that are part of the specified named group."
- def viz
- SharedHelpers.major_deprecation 2, "The `viz` command has been renamed to `graph` and moved to a plugin. See https://github.com/rubygems/bundler-graph"
- require_relative "cli/viz"
- Viz.new(options.dup).run
- end
+ desc "viz [OPTIONS]", "Generates a visual dependency graph", hide: true
+ def viz
+ SharedHelpers.feature_removed! "The `viz` command has been renamed to `graph` and moved to a plugin. See https://github.com/rubygems/bundler-graph"
end
desc "gem NAME [OPTIONS]", "Creates a skeleton for creating a rubygem"
diff --git a/lib/bundler/cli/viz.rb b/lib/bundler/cli/viz.rb
deleted file mode 100644
index 5c09e00995..0000000000
--- a/lib/bundler/cli/viz.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-# frozen_string_literal: true
-
-module Bundler
- class CLI::Viz
- attr_reader :options, :gem_name
- def initialize(options)
- @options = options
- end
-
- def run
- # make sure we get the right `graphviz`. There is also a `graphviz`
- # gem we're not built to support
- gem "ruby-graphviz"
- require "graphviz"
-
- options[:without] = options[:without].join(":").tr(" ", ":").split(":")
- output_file = File.expand_path(options[:file])
-
- graph = Graph.new(Bundler.load, output_file, options[:version], options[:requirements], options[:format], options[:without])
- graph.viz
- rescue LoadError => e
- Bundler.ui.error e.inspect
- Bundler.ui.warn "Make sure you have the graphviz ruby gem. You can install it with:"
- Bundler.ui.warn "`gem install ruby-graphviz`"
- rescue StandardError => e
- raise unless e.message.to_s.include?("GraphViz not installed or dot not in PATH")
- Bundler.ui.error e.message
- Bundler.ui.warn "Please install GraphViz. On a Mac with Homebrew, you can run `brew install graphviz`."
- end
- end
-end
diff --git a/lib/bundler/graph.rb b/lib/bundler/graph.rb
deleted file mode 100644
index b22b17a453..0000000000
--- a/lib/bundler/graph.rb
+++ /dev/null
@@ -1,152 +0,0 @@
-# frozen_string_literal: true
-
-require "set"
-module Bundler
- class Graph
- GRAPH_NAME = :Gemfile
-
- def initialize(env, output_file, show_version = false, show_requirements = false, output_format = "png", without = [])
- @env = env
- @output_file = output_file
- @show_version = show_version
- @show_requirements = show_requirements
- @output_format = output_format
- @without_groups = without.map(&:to_sym)
-
- @groups = []
- @relations = Hash.new {|h, k| h[k] = Set.new }
- @node_options = {}
- @edge_options = {}
-
- _populate_relations
- end
-
- attr_reader :groups, :relations, :node_options, :edge_options, :output_file, :output_format
-
- def viz
- GraphVizClient.new(self).run
- end
-
- private
-
- def _populate_relations
- parent_dependencies = _groups.values.to_set.flatten
- loop do
- break if parent_dependencies.empty?
-
- tmp = Set.new
- parent_dependencies.each do |dependency|
- child_dependencies = spec_for_dependency(dependency).runtime_dependencies.to_set
- @relations[dependency.name] += child_dependencies.map(&:name).to_set
- tmp += child_dependencies
-
- @node_options[dependency.name] = _make_label(dependency, :node)
- child_dependencies.each do |c_dependency|
- @edge_options["#{dependency.name}_#{c_dependency.name}"] = _make_label(c_dependency, :edge)
- end
- end
- parent_dependencies = tmp
- end
- end
-
- def _groups
- relations = Hash.new {|h, k| h[k] = Set.new }
- @env.current_dependencies.each do |dependency|
- dependency.groups.each do |group|
- next if @without_groups.include?(group)
-
- relations[group.to_s].add(dependency)
- @relations[group.to_s].add(dependency.name)
-
- @node_options[group.to_s] ||= _make_label(group, :node)
- @edge_options["#{group}_#{dependency.name}"] = _make_label(dependency, :edge)
- end
- end
- @groups = relations.keys
- relations
- end
-
- def _make_label(symbol_or_string_or_dependency, element_type)
- case element_type.to_sym
- when :node
- if symbol_or_string_or_dependency.is_a?(Gem::Dependency)
- label = symbol_or_string_or_dependency.name.dup
- label << "\n#{spec_for_dependency(symbol_or_string_or_dependency).version}" if @show_version
- else
- label = symbol_or_string_or_dependency.to_s
- end
- when :edge
- label = nil
- if symbol_or_string_or_dependency.respond_to?(:requirements_list) && @show_requirements
- tmp = symbol_or_string_or_dependency.requirements_list.join(", ")
- label = tmp if tmp != ">= 0"
- end
- else
- raise ArgumentError, "2nd argument is invalid"
- end
- label.nil? ? {} : { label: label }
- end
-
- def spec_for_dependency(dependency)
- @env.requested_specs.find {|s| s.name == dependency.name }
- end
-
- class GraphVizClient
- def initialize(graph_instance)
- @graph_name = graph_instance.class::GRAPH_NAME
- @groups = graph_instance.groups
- @relations = graph_instance.relations
- @node_options = graph_instance.node_options
- @edge_options = graph_instance.edge_options
- @output_file = graph_instance.output_file
- @output_format = graph_instance.output_format
- end
-
- def g
- @g ||= ::GraphViz.digraph(@graph_name, concentrate: true, normalize: true, nodesep: 0.55) do |g|
- g.edge[:weight] = 2
- g.edge[:fontname] = g.node[:fontname] = "Arial, Helvetica, SansSerif"
- g.edge[:fontsize] = 12
- end
- end
-
- def run
- @groups.each do |group|
- g.add_nodes(
- group, {
- style: "filled",
- fillcolor: "#B9B9D5",
- shape: "box3d",
- fontsize: 16,
- }.merge(@node_options[group])
- )
- end
-
- @relations.each do |parent, children|
- children.each do |child|
- if @groups.include?(parent)
- g.add_nodes(child, { style: "filled", fillcolor: "#B9B9D5" }.merge(@node_options[child]))
- g.add_edges(parent, child, { constraint: false }.merge(@edge_options["#{parent}_#{child}"]))
- else
- g.add_nodes(child, @node_options[child])
- g.add_edges(parent, child, @edge_options["#{parent}_#{child}"])
- end
- end
- end
-
- if @output_format.to_s == "debug"
- $stdout.puts g.output none: String
- Bundler.ui.info "debugging bundle viz..."
- else
- begin
- g.output @output_format.to_sym => "#{@output_file}.#{@output_format}"
- Bundler.ui.info "#{@output_file}.#{@output_format}"
- rescue ArgumentError => e
- warn "Unsupported output format. See Ruby-Graphviz/lib/graphviz/constants.rb"
- raise e
- end
- end
- end
- end
- end
-end
diff --git a/lib/bundler/man/bundle-viz.1 b/lib/bundler/man/bundle-viz.1
deleted file mode 100644
index f2570103dc..0000000000
--- a/lib/bundler/man/bundle-viz.1
+++ /dev/null
@@ -1,30 +0,0 @@
-.\" generated with Ronn-NG/v0.10.1
-.\" http://github.com/apjanke/ronn-ng/tree/0.10.1
-.TH "BUNDLE\-VIZ" "1" "August 2025" ""
-.SH "NAME"
-\fBbundle\-viz\fR \- Generates a visual dependency graph for your Gemfile
-.SH "SYNOPSIS"
-\fBbundle viz\fR [\-\-file=FILE] [\-\-format=FORMAT] [\-\-requirements] [\-\-version] [\-\-without=GROUP GROUP]
-.SH "DESCRIPTION"
-\fBviz\fR generates a PNG file of the current \fBGemfile(5)\fR as a dependency graph\. \fBviz\fR requires the ruby\-graphviz gem (and its dependencies)\.
-.P
-The associated gems must also be installed via \fBbundle install(1)\fR \fIbundle\-install\.1\.html\fR\.
-.P
-\fBviz\fR command was deprecated in Bundler 2\.2\. Use bundler\-graph plugin \fIhttps://github\.com/rubygems/bundler\-graph\fR instead\.
-.SH "OPTIONS"
-.TP
-\fB\-\-file=FILE\fR, \fB\-f=FILE\fR
-The name to use for the generated file\. See \fB\-\-format\fR option
-.TP
-\fB\-\-format=FORMAT\fR, \fB\-F=FORMAT\fR
-This is output format option\. Supported format is png, jpg, svg, dot \|\.\|\.\|\.
-.TP
-\fB\-\-requirements\fR, \fB\-R\fR
-Set to show the version of each required dependency\.
-.TP
-\fB\-\-version\fR, \fB\-v\fR
-Set to show each gem version\.
-.TP
-\fB\-\-without=<list>\fR, \fB\-W=<list>\fR
-Exclude gems that are part of the specified named group\.
-
diff --git a/lib/bundler/man/bundle-viz.1.ronn b/lib/bundler/man/bundle-viz.1.ronn
deleted file mode 100644
index 730b0eed22..0000000000
--- a/lib/bundler/man/bundle-viz.1.ronn
+++ /dev/null
@@ -1,36 +0,0 @@
-bundle-viz(1) -- Generates a visual dependency graph for your Gemfile
-=====================================================================
-
-## SYNOPSIS
-
-`bundle viz` [--file=FILE]
- [--format=FORMAT]
- [--requirements]
- [--version]
- [--without=GROUP GROUP]
-
-## DESCRIPTION
-
-`viz` generates a PNG file of the current `Gemfile(5)` as a dependency graph.
-`viz` requires the ruby-graphviz gem (and its dependencies).
-
-The associated gems must also be installed via [`bundle install(1)`](bundle-install.1.html).
-
-`viz` command was deprecated in Bundler 2.2. Use [bundler-graph plugin](https://github.com/rubygems/bundler-graph) instead.
-
-## OPTIONS
-
-* `--file=FILE`, `-f=FILE`:
- The name to use for the generated file. See `--format` option
-
-* `--format=FORMAT`, `-F=FORMAT`:
- This is output format option. Supported format is png, jpg, svg, dot ...
-
-* `--requirements`, `-R`:
- Set to show the version of each required dependency.
-
-* `--version`, `-v`:
- Set to show each gem version.
-
-* `--without=<list>`, `-W=<list>`:
- Exclude gems that are part of the specified named group.
diff --git a/lib/bundler/man/bundle.1 b/lib/bundler/man/bundle.1
index 9bee76e58b..ece080b3e9 100644
--- a/lib/bundler/man/bundle.1
+++ b/lib/bundler/man/bundle.1
@@ -66,9 +66,6 @@ Open an installed gem in the editor
\fBbundle lock(1)\fR \fIbundle\-lock\.1\.html\fR
Generate a lockfile for your dependencies
.TP
-\fBbundle viz(1)\fR \fIbundle\-viz\.1\.html\fR (deprecated)
-Generate a visual representation of your dependencies
-.TP
\fBbundle init(1)\fR \fIbundle\-init\.1\.html\fR
Generate a simple \fBGemfile\fR, placed in the current directory
.TP
diff --git a/lib/bundler/man/bundle.1.ronn b/lib/bundler/man/bundle.1.ronn
index f368b32276..1c2b3df7af 100644
--- a/lib/bundler/man/bundle.1.ronn
+++ b/lib/bundler/man/bundle.1.ronn
@@ -76,9 +76,6 @@ We divide `bundle` subcommands into primary commands and utilities:
* [`bundle lock(1)`](bundle-lock.1.html):
Generate a lockfile for your dependencies
-* [`bundle viz(1)`](bundle-viz.1.html) (deprecated):
- Generate a visual representation of your dependencies
-
* [`bundle init(1)`](bundle-init.1.html):
Generate a simple `Gemfile`, placed in the current directory
diff --git a/lib/bundler/man/index.txt b/lib/bundler/man/index.txt
index 6cc5eb24cd..f610ba852a 100644
--- a/lib/bundler/man/index.txt
+++ b/lib/bundler/man/index.txt
@@ -29,4 +29,3 @@ bundle-remove(1) bundle-remove.1
bundle-show(1) bundle-show.1
bundle-update(1) bundle-update.1
bundle-version(1) bundle-version.1
-bundle-viz(1) bundle-viz.1
diff --git a/spec/bundler/commands/viz_spec.rb b/spec/bundler/commands/viz_spec.rb
deleted file mode 100644
index 0ad285104c..0000000000
--- a/spec/bundler/commands/viz_spec.rb
+++ /dev/null
@@ -1,144 +0,0 @@
-# frozen_string_literal: true
-
-RSpec.describe "bundle viz", if: Bundler.which("dot") do
- before do
- base_system_gems "rexml", "ruby-graphviz"
- end
-
- it "graphs gems from the Gemfile" do
- install_gemfile <<-G
- source "https://gem.repo1"
- gem "myrack"
- gem "myrack-obama"
- G
-
- bundle "viz"
- expect(out).to include("gem_graph.png")
-
- bundle "viz", format: "debug"
- expect(out).to eq(<<~DOT.strip)
- digraph Gemfile {
- concentrate = "true";
- normalize = "true";
- nodesep = "0.55";
- edge[ weight = "2"];
- node[ fontname = "Arial, Helvetica, SansSerif"];
- edge[ fontname = "Arial, Helvetica, SansSerif" , fontsize = "12"];
- default [style = "filled", fillcolor = "#B9B9D5", shape = "box3d", fontsize = "16", label = "default"];
- myrack [style = "filled", fillcolor = "#B9B9D5", label = "myrack"];
- default -> myrack [constraint = "false"];
- "myrack-obama" [style = "filled", fillcolor = "#B9B9D5", label = "myrack-obama"];
- default -> "myrack-obama" [constraint = "false"];
- "myrack-obama" -> myrack;
- }
- debugging bundle viz...
- DOT
- end
-
- it "graphs gems that are prereleases" do
- build_repo2 do
- build_gem "myrack", "1.3.pre"
- end
-
- install_gemfile <<-G
- source "https://gem.repo2"
- gem "myrack", "= 1.3.pre"
- gem "myrack-obama"
- G
-
- bundle "viz"
- expect(out).to include("gem_graph.png")
-
- bundle "viz", format: :debug, version: true
- expect(out).to eq(<<~EOS.strip)
- digraph Gemfile {
- concentrate = "true";
- normalize = "true";
- nodesep = "0.55";
- edge[ weight = "2"];
- node[ fontname = "Arial, Helvetica, SansSerif"];
- edge[ fontname = "Arial, Helvetica, SansSerif" , fontsize = "12"];
- default [style = "filled", fillcolor = "#B9B9D5", shape = "box3d", fontsize = "16", label = "default"];
- myrack [style = "filled", fillcolor = "#B9B9D5", label = "myrack\\n1.3.pre"];
- default -> myrack [constraint = "false"];
- "myrack-obama" [style = "filled", fillcolor = "#B9B9D5", label = "myrack-obama\\n1.0"];
- default -> "myrack-obama" [constraint = "false"];
- "myrack-obama" -> myrack;
- }
- debugging bundle viz...
- EOS
- end
-
- context "with another gem that has a graphviz file" do
- before do
- update_repo4 do
- build_gem "graphviz", "999" do |s|
- s.write("lib/graphviz.rb", "abort 'wrong graphviz gem loaded'")
- end
- end
-
- system_gems "graphviz-999", gem_repo: gem_repo4
- end
-
- it "loads the correct ruby-graphviz gem" do
- install_gemfile <<-G
- source "https://gem.repo1"
- gem "myrack"
- gem "myrack-obama"
- G
-
- bundle "viz", format: "debug"
- expect(out).to eq(<<~DOT.strip)
- digraph Gemfile {
- concentrate = "true";
- normalize = "true";
- nodesep = "0.55";
- edge[ weight = "2"];
- node[ fontname = "Arial, Helvetica, SansSerif"];
- edge[ fontname = "Arial, Helvetica, SansSerif" , fontsize = "12"];
- default [style = "filled", fillcolor = "#B9B9D5", shape = "box3d", fontsize = "16", label = "default"];
- myrack [style = "filled", fillcolor = "#B9B9D5", label = "myrack"];
- default -> myrack [constraint = "false"];
- "myrack-obama" [style = "filled", fillcolor = "#B9B9D5", label = "myrack-obama"];
- default -> "myrack-obama" [constraint = "false"];
- "myrack-obama" -> myrack;
- }
- debugging bundle viz...
- DOT
- end
- end
-
- context "--without option" do
- it "one group" do
- install_gemfile <<-G
- source "https://gem.repo1"
- gem "activesupport"
-
- group :rails do
- gem "rails"
- end
- G
-
- bundle "viz --without=rails"
- expect(out).to include("gem_graph.png")
- end
-
- it "two groups" do
- install_gemfile <<-G
- source "https://gem.repo1"
- gem "activesupport"
-
- group :myrack do
- gem "myrack"
- end
-
- group :rails do
- gem "rails"
- end
- G
-
- bundle "viz --without=rails:myrack"
- expect(out).to include("gem_graph.png")
- end
- end
-end
diff --git a/spec/bundler/other/major_deprecation_spec.rb b/spec/bundler/other/major_deprecation_spec.rb
index d17770d00c..dcefbe0afa 100644
--- a/spec/bundler/other/major_deprecation_spec.rb
+++ b/spec/bundler/other/major_deprecation_spec.rb
@@ -642,15 +642,12 @@ RSpec.describe "major deprecations" do
context "bundle viz" do
before do
- create_file "gems.rb", "source 'https://gem.repo1'"
- bundle "viz"
+ bundle "viz", raise_on_error: false
end
- it "prints a deprecation warning" do
- expect(deprecations).to include "The `viz` command has been renamed to `graph` and moved to a plugin. See https://github.com/rubygems/bundler-graph"
+ it "fails with a helpful message" do
+ expect(err).to include "The `viz` command has been renamed to `graph` and moved to a plugin. See https://github.com/rubygems/bundler-graph"
end
-
- pending "fails with a helpful message", bundler: "4"
end
context "bundle inject" do
diff --git a/tool/bundler/test_gems.rb b/tool/bundler/test_gems.rb
index 28113cd299..9776a96b90 100644
--- a/tool/bundler/test_gems.rb
+++ b/tool/bundler/test_gems.rb
@@ -11,7 +11,6 @@ gem "builder", "~> 3.2"
gem "rb_sys"
gem "fiddle"
gem "rubygems-generate_index", "~> 1.1"
-gem "ruby-graphviz"
gem "psych"
gem "etc", platforms: [:ruby, :windows]
gem "open3"
diff --git a/tool/bundler/test_gems.rb.lock b/tool/bundler/test_gems.rb.lock
index 99760ac573..fa61796f0f 100644
--- a/tool/bundler/test_gems.rb.lock
+++ b/tool/bundler/test_gems.rb.lock
@@ -33,9 +33,6 @@ GEM
rake-compiler-dock (1.9.1)
rb_sys (0.9.111)
rake-compiler-dock (= 1.9.1)
- rexml (3.4.1)
- ruby-graphviz (1.2.5)
- rexml
ruby2_keywords (0.0.5)
rubygems-generate_index (1.1.3)
compact_index (~> 0.15.0)
@@ -69,7 +66,6 @@ DEPENDENCIES
rack-test (~> 2.1)
rake (~> 13.1)
rb_sys
- ruby-graphviz
rubygems-generate_index (~> 1.1)
shellwords
sinatra (~> 4.1)
@@ -95,8 +91,6 @@ CHECKSUMS
rake (13.3.0) sha256=96f5092d786ff412c62fde76f793cc0541bd84d2eb579caa529aa8a059934493
rake-compiler-dock (1.9.1) sha256=e73720a29aba9c114728ce39cc0d8eef69ba61d88e7978c57bac171724cd4d53
rb_sys (0.9.111) sha256=65822fd8d57c248cd893db0efe01bc6edc15fcbea3ba6666091e35430c1cbaf0
- rexml (3.4.1) sha256=c74527a9a0a04b4ec31dbe0dc4ed6004b960af943d8db42e539edde3a871abca
- ruby-graphviz (1.2.5) sha256=1c2bb44e3f6da9e2b829f5e7fd8d75a521485fb6b4d1fc66ff0f93f906121504
ruby2_keywords (0.0.5) sha256=ffd13740c573b7301cf7a2e61fc857b2a8e3d3aff32545d6f8300d8bae10e3ef
rubygems-generate_index (1.1.3) sha256=3571424322666598e9586a906485e1543b617f87644913eaf137d986a3393f5c
shellwords (0.2.2) sha256=b8695a791de2f71472de5abdc3f4332f6535a4177f55d8f99e7e44266cd32f94