file_tree_visualizer 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 487ea44c103965a0bf633fc0d618c50fb4a0c7d8ddbbee53b61f4d99a959d3f9
4
- data.tar.gz: 89a961a923ab5ae1a9f83ada18f1951905e5ccde53219de8ba83fe5bd34b14f1
3
+ metadata.gz: b48b5d1e8f778bbacb3fb9e05cbcbe01cc2bcfe461a9483e6a26ecee97ea61e4
4
+ data.tar.gz: 871f3db43591f0bed5778d21a42431a50dad4604fc559690a4fe7c469a97ed05
5
5
  SHA512:
6
- metadata.gz: fd1eddbd5b1ae2b077e521f8ddd09dad953c12679aac80da81253cb18673a2f300d5146f86e244da85888b4872e59e823174c7a35e47f58aaa76cfa859e23cea
7
- data.tar.gz: 7e91afaea1510c5c3ea03695666a1edac1390bd1be55c15c5bd9a6092bdc10a35f981bce7289f0a9a1e05ef5f0823c84a4da54161929a42868150dda92d90729
6
+ metadata.gz: eac6f7ab5f691589e622b2c595164b6b7f9043d75b5d22ea3e9aa04eba60fa8919f061ece96a824fd02e60c59dfe40f4894c61cf6a45742becc717e3b7c59f18
7
+ data.tar.gz: 5ec9b4396e7c5e2bdb56608091a60f0370655d1b895b15fdff0210a77fd79658ec7969545bdc27068c3a052dc44f9b01fcd3bf7a5482d2deaf69b4c060ae879f
data/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # file_tree_visualizer
2
2
 
3
+ [![CI](https://github.com/JohnBidwellB/file-tree-visualizer/actions/workflows/release.yml/badge.svg)](https://github.com/JohnBidwellB/file-tree-visualizer/actions/workflows/release.yml)
4
+ [![RubyGems](https://badge.fury.io/rb/file_tree_visualizer.svg)](https://rubygems.org/gems/file_tree_visualizer)
5
+
3
6
  Ruby gem to scan file trees from the terminal and generate a fully offline interactive HTML report with the items that consume the most disk space.
4
7
 
5
8
  ## What it does
@@ -30,7 +33,7 @@ file-tree-visualizer /path/to/scan -o report.html
30
33
  Install a specific version:
31
34
 
32
35
  ```bash
33
- gem install file_tree_visualizer -v 0.1.0
36
+ gem install file_tree_visualizer -v 0.2.1
34
37
  ```
35
38
 
36
39
  ## Local development install
@@ -38,7 +41,7 @@ gem install file_tree_visualizer -v 0.1.0
38
41
  ```bash
39
42
  bundle install
40
43
  gem build file_tree_visualizer.gemspec
41
- gem install ./file_tree_visualizer-0.1.0.gem
44
+ gem install ./file_tree_visualizer-0.2.1.gem
42
45
  file-tree-visualizer /path/to/scan -o report.html
43
46
  ```
44
47
 
@@ -55,7 +58,12 @@ During scanning, an interactive terminal shows a progress bar with processed fil
55
58
  -t, --top N Number of largest files to keep in ranking (default: 200)
56
59
  --follow-symlinks Follow symbolic links
57
60
  --no-progress Disable progress bar
61
+ --exclude PATTERNS Exclude patterns (comma-separated or repeated)
62
+ --summary Print summary to terminal
63
+ --json FILE Export full result as JSON
64
+ --csv FILE Export top files as CSV
58
65
  --lang LANG Language for CLI and report (en|es)
66
+ -v, --version Print version
59
67
  -h, --help Show help
60
68
 
61
69
  Language resolution priority:
@@ -64,12 +72,68 @@ Language resolution priority:
64
72
  - fallback to English (`en`)
65
73
  ```
66
74
 
75
+ ## Common workflows
76
+
77
+ Print current gem version:
78
+
79
+ ```bash
80
+ file-tree-visualizer --version
81
+ ```
82
+
83
+ Summary only (no HTML file generated unless `--output` is explicitly provided):
84
+
85
+ ```bash
86
+ file-tree-visualizer --summary
87
+ ```
88
+
89
+ Summary + HTML report:
90
+
91
+ ```bash
92
+ file-tree-visualizer . --summary --output report.html
93
+ ```
94
+
95
+ Exclude directories and files by pattern:
96
+
97
+ ```bash
98
+ file-tree-visualizer . --exclude "node_modules,.git,*.log" --exclude "tmp/**"
99
+ ```
100
+
101
+ Export JSON and CSV in one run:
102
+
103
+ ```bash
104
+ file-tree-visualizer . --summary --json scan.json --csv top-files.csv
105
+ ```
106
+
107
+ ## Contributing
108
+
109
+ 1. Create a feature branch from `main`.
110
+ 2. Implement your change and run tests locally.
111
+ 3. Push your branch and open a Pull Request.
112
+ 4. Wait for CI to pass and at least one approval.
113
+
114
+ ```bash
115
+ git checkout -b feat/short-description
116
+ bundle exec rake test
117
+ git push origin feat/short-description
118
+ ```
119
+
120
+ Branch policy:
121
+ - For collaborators, `main` is protected and requires PR + CI + approval.
122
+ - Repository admins can bypass these rules when needed.
123
+
67
124
  ## Automatic release to RubyGems
68
125
 
69
- - This repository publishes the gem automatically when pushing a tag with format `v*` (for example `v0.0.4`).
126
+ - This repository publishes the gem automatically when pushing a tag with format `v*` (for example `v0.2.1`).
70
127
  - Before using it, configure the `RUBYGEMS_API_KEY` secret in GitHub Actions.
128
+ - You can also trigger the workflow manually from GitHub Actions (`workflow_dispatch`).
129
+
130
+ ```bash
131
+ git tag v0.2.1
132
+ git push origin v0.2.1
133
+ ```
134
+
135
+ Reusable release notes template:
71
136
 
72
137
  ```bash
73
- git tag v0.0.4
74
- git push origin v0.0.4
138
+ gh release create v0.2.1 --title "v0.2.1" --notes-file .github/release-template.md
75
139
  ```
@@ -5,8 +5,8 @@ require_relative 'lib/file_tree_visualizer/version'
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = 'file_tree_visualizer'
7
7
  spec.version = FileTreeVisualizer::VERSION
8
- spec.authors = ['jbidwell1']
9
- spec.email = ['devnull@example.com']
8
+ spec.authors = ['John Bidwell']
9
+ spec.email = ['johnbidwellb@gmail.com']
10
10
 
11
11
  spec.summary = 'CLI Ruby tool to analyze file sizes and generate an interactive HTML report.'
12
12
  spec.description = 'Scans a directory recursively, computes file/directory sizes, and generates an HTML report rendered with React.'
@@ -14,7 +14,8 @@ Gem::Specification.new do |spec|
14
14
  spec.license = 'MIT'
15
15
  spec.required_ruby_version = '>= 2.7'
16
16
 
17
- spec.metadata['source_code_uri'] = spec.homepage
17
+ spec.metadata['source_code_uri'] = "#{spec.homepage}/tree/main"
18
+ spec.metadata['bug_tracker_uri'] = "#{spec.homepage}/issues"
18
19
  spec.metadata['changelog_uri'] = "#{spec.homepage}/blob/main/CHANGELOG.md"
19
20
 
20
21
  spec.files = Dir.chdir(__dir__) do
@@ -30,4 +31,5 @@ Gem::Specification.new do |spec|
30
31
  spec.bindir = 'bin'
31
32
  spec.executables = ['file-tree-visualizer']
32
33
  spec.require_paths = ['lib']
34
+ spec.add_dependency 'csv', '~> 3.3'
33
35
  end
@@ -1,6 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'optparse'
4
+ require 'csv'
5
+ require 'json'
4
6
 
5
7
  module FileTreeVisualizer
6
8
  class CLI
@@ -13,6 +15,11 @@ module FileTreeVisualizer
13
15
 
14
16
  def run
15
17
  options, parser, locale = parse_options(@argv.dup)
18
+ if options[:version]
19
+ puts FileTreeVisualizer::VERSION
20
+ return 0
21
+ end
22
+
16
23
  if options[:help]
17
24
  puts parser
18
25
  return 0
@@ -24,22 +31,30 @@ module FileTreeVisualizer
24
31
  t(locale, 'cli.errors.invalid_directory', path: expanded_path)
25
32
  end
26
33
 
27
- scanner = Scanner.new(top_limit: options[:top], follow_symlinks: options[:follow_symlinks])
34
+ scanner = Scanner.new(
35
+ top_limit: options[:top],
36
+ follow_symlinks: options[:follow_symlinks],
37
+ excludes: options[:exclude_patterns]
38
+ )
28
39
  progress = ProgressRenderer.new(enabled: options[:progress], locale: locale)
29
40
  callback = options[:progress] ? progress.method(:render) : nil
30
41
  result = scanner.scan(expanded_path, progress: callback)
31
42
  progress.finish
32
- report = ReportBuilder.new(result: result, source_path: expanded_path, locale: locale).build
33
-
34
- output_path = File.expand_path(options[:output])
35
- File.write(output_path, report)
36
-
37
- puts t(locale, 'cli.messages.report_generated', path: output_path)
38
- puts t(locale, 'cli.messages.scanned',
39
- directories: result.stats[:directories],
40
- files: result.stats[:files],
41
- skipped: result.stats[:skipped])
42
- puts t(locale, 'cli.messages.total_size', size: format_bytes(result.stats[:bytes]))
43
+ generated_at = Time.now.utc
44
+ output_path = maybe_write_report(options, expanded_path, result, locale, generated_at)
45
+ json_path = write_json_export(options[:json_output], expanded_path, result, locale, generated_at)
46
+ csv_path = write_csv_export(options[:csv_output], result)
47
+ print_summary(expanded_path, result, locale) if options[:summary]
48
+ puts t(locale, 'cli.messages.report_generated', path: output_path) if output_path
49
+ puts t(locale, 'cli.messages.json_generated', path: json_path) if json_path
50
+ puts t(locale, 'cli.messages.csv_generated', path: csv_path) if csv_path
51
+ unless options[:summary]
52
+ puts t(locale, 'cli.messages.scanned',
53
+ directories: result.stats[:directories],
54
+ files: result.stats[:files],
55
+ skipped: result.stats[:skipped])
56
+ end
57
+ puts t(locale, 'cli.messages.total_size', size: format_bytes(result.stats[:bytes])) unless options[:summary]
43
58
  0
44
59
  rescue OptionParser::ParseError, ArgumentError => e
45
60
  locale = error_locale
@@ -133,7 +148,13 @@ module FileTreeVisualizer
133
148
  top: Scanner::DEFAULT_TOP_LIMIT,
134
149
  follow_symlinks: false,
135
150
  progress: true,
151
+ summary: false,
152
+ output_given: false,
153
+ json_output: nil,
154
+ csv_output: nil,
155
+ exclude_patterns: [],
136
156
  lang: nil,
157
+ version: false,
137
158
  help: false
138
159
  }
139
160
 
@@ -164,6 +185,7 @@ module FileTreeVisualizer
164
185
 
165
186
  opts.on('-o', '--output FILE', t(locale, 'cli.output_option', default: DEFAULT_OUTPUT)) do |value|
166
187
  options[:output] = value
188
+ options[:output_given] = true
167
189
  end
168
190
 
169
191
  opts.on('-t', '--top N', Integer, t(locale, 'cli.top_option', default: Scanner::DEFAULT_TOP_LIMIT)) do |value|
@@ -178,10 +200,30 @@ module FileTreeVisualizer
178
200
  options[:progress] = false
179
201
  end
180
202
 
203
+ opts.on('--exclude PATTERNS', t(locale, 'cli.exclude_option')) do |value|
204
+ options[:exclude_patterns].concat(split_patterns(value))
205
+ end
206
+
207
+ opts.on('--summary', t(locale, 'cli.summary_option')) do
208
+ options[:summary] = true
209
+ end
210
+
211
+ opts.on('--json FILE', t(locale, 'cli.json_option')) do |value|
212
+ options[:json_output] = value
213
+ end
214
+
215
+ opts.on('--csv FILE', t(locale, 'cli.csv_option')) do |value|
216
+ options[:csv_output] = value
217
+ end
218
+
181
219
  opts.on('--lang LANG', t(locale, 'cli.lang_option')) do |value|
182
220
  options[:lang] = value
183
221
  end
184
222
 
223
+ opts.on('-v', '--version', t(locale, 'cli.version_option')) do
224
+ options[:version] = true
225
+ end
226
+
185
227
  opts.on('-h', '--help', t(locale, 'cli.help_option')) do
186
228
  options[:help] = true
187
229
  end
@@ -198,6 +240,10 @@ module FileTreeVisualizer
198
240
  nil
199
241
  end
200
242
 
243
+ def split_patterns(value)
244
+ value.to_s.split(',').map(&:strip).reject(&:empty?)
245
+ end
246
+
201
247
  def t(locale, key, **vars)
202
248
  I18n.t(locale, key, **vars)
203
249
  end
@@ -221,5 +267,72 @@ module FileTreeVisualizer
221
267
  precision = value < 10 ? 2 : 1
222
268
  format("%.#{precision}f %s", value, units[unit_index])
223
269
  end
270
+
271
+ def maybe_write_report(options, source_path, result, locale, generated_at)
272
+ should_write = !options[:summary] || options[:output_given]
273
+ return nil unless should_write
274
+
275
+ report = ReportBuilder.new(
276
+ result: result,
277
+ source_path: source_path,
278
+ locale: locale,
279
+ generated_at: generated_at
280
+ ).build
281
+ output_path = File.expand_path(options[:output])
282
+ File.write(output_path, report)
283
+ output_path
284
+ end
285
+
286
+ def write_json_export(target_path, source_path, result, locale, generated_at)
287
+ return nil unless target_path
288
+
289
+ output_path = File.expand_path(target_path)
290
+ payload = {
291
+ source_path: source_path,
292
+ generated_at: generated_at.iso8601,
293
+ locale: locale,
294
+ version: FileTreeVisualizer::VERSION,
295
+ stats: result.stats,
296
+ root: result.root,
297
+ top_files: result.top_files
298
+ }
299
+ File.write(output_path, JSON.pretty_generate(payload))
300
+ output_path
301
+ end
302
+
303
+ def write_csv_export(target_path, result)
304
+ return nil unless target_path
305
+
306
+ output_path = File.expand_path(target_path)
307
+ CSV.open(output_path, 'w') do |csv|
308
+ csv << %w[rank path name size_bytes size_human]
309
+ result.top_files.each_with_index do |item, index|
310
+ csv << [index + 1, item[:path], item[:name], item[:size], format_bytes(item[:size])]
311
+ end
312
+ end
313
+ output_path
314
+ end
315
+
316
+ def print_summary(source_path, result, locale)
317
+ puts t(locale, 'cli.summary.heading')
318
+ puts t(locale, 'cli.summary.source', path: source_path)
319
+ puts t(locale, 'cli.summary.total_size', size: format_bytes(result.stats[:bytes]))
320
+ puts t(locale, 'cli.summary.files', count: result.stats[:files])
321
+ puts t(locale, 'cli.summary.directories', count: result.stats[:directories])
322
+ puts t(locale, 'cli.summary.skipped', count: result.stats[:skipped])
323
+ puts t(locale, 'cli.summary.top_files')
324
+
325
+ if result.top_files.empty?
326
+ puts " #{t(locale, 'cli.summary.none')}"
327
+ return
328
+ end
329
+
330
+ result.top_files.each_with_index do |item, index|
331
+ puts format(' %<rank>d. %<size>s %<path>s',
332
+ rank: index + 1,
333
+ size: format_bytes(item[:size]),
334
+ path: item[:path])
335
+ end
336
+ end
224
337
  end
225
338
  end
@@ -13,10 +13,17 @@ module FileTreeVisualizer
13
13
  'top_option' => 'Number of largest files in ranking (default: %<default>s)',
14
14
  'follow_symlinks_option' => 'Follow symbolic links during scan',
15
15
  'no_progress_option' => 'Disable progress bar',
16
+ 'exclude_option' => 'Exclude patterns (comma-separated or repeated)',
17
+ 'summary_option' => 'Print terminal summary',
18
+ 'json_option' => 'Export scan result as JSON',
19
+ 'csv_option' => 'Export top files as CSV',
16
20
  'lang_option' => 'Language for CLI and report (en|es)',
21
+ 'version_option' => 'Print version',
17
22
  'help_option' => 'Show this help',
18
23
  'messages' => {
19
24
  'report_generated' => 'Report generated at: %<path>s',
25
+ 'json_generated' => 'JSON exported at: %<path>s',
26
+ 'csv_generated' => 'CSV exported at: %<path>s',
20
27
  'scanned' => 'Scanned: %<directories>s directories, %<files>s files, %<skipped>s skipped.',
21
28
  'total_size' => 'Total size: %<size>s'
22
29
  },
@@ -30,6 +37,16 @@ module FileTreeVisualizer
30
37
  'progress' => {
31
38
  'preparing' => 'Preparing scan %<spinner>s Files:%<files>s Dirs:%<dirs>s',
32
39
  'scanning' => 'Scanning [%<bar>s] %<percent>s%% Files:%<pf>s/%<tf>s Dirs:%<pd>s/%<td>s'
40
+ },
41
+ 'summary' => {
42
+ 'heading' => 'Summary',
43
+ 'source' => 'Source: %<path>s',
44
+ 'total_size' => 'Total size: %<size>s',
45
+ 'files' => 'Files: %<count>s',
46
+ 'directories' => 'Directories: %<count>s',
47
+ 'skipped' => 'Skipped entries: %<count>s',
48
+ 'top_files' => 'Top files:',
49
+ 'none' => '(none)'
33
50
  }
34
51
  },
35
52
  'report' => {
@@ -72,10 +89,17 @@ module FileTreeVisualizer
72
89
  'top_option' => 'Cantidad de archivos pesados en ranking (default: %<default>s)',
73
90
  'follow_symlinks_option' => 'Sigue enlaces simbólicos durante el escaneo',
74
91
  'no_progress_option' => 'Desactiva la barra de progreso',
92
+ 'exclude_option' => 'Excluye patrones (separados por coma o repetidos)',
93
+ 'summary_option' => 'Imprime resumen en terminal',
94
+ 'json_option' => 'Exporta resultado del escaneo como JSON',
95
+ 'csv_option' => 'Exporta top de archivos como CSV',
75
96
  'lang_option' => 'Idioma para CLI y reporte (en|es)',
97
+ 'version_option' => 'Muestra version',
76
98
  'help_option' => 'Muestra esta ayuda',
77
99
  'messages' => {
78
100
  'report_generated' => 'Reporte generado en: %<path>s',
101
+ 'json_generated' => 'JSON exportado en: %<path>s',
102
+ 'csv_generated' => 'CSV exportado en: %<path>s',
79
103
  'scanned' => 'Escaneado: %<directories>s directorios, %<files>s archivos, %<skipped>s omitidos.',
80
104
  'total_size' => 'Tamano total: %<size>s'
81
105
  },
@@ -89,6 +113,16 @@ module FileTreeVisualizer
89
113
  'progress' => {
90
114
  'preparing' => 'Preparando escaneo %<spinner>s Arch:%<files>s Dir:%<dirs>s',
91
115
  'scanning' => 'Escaneando [%<bar>s] %<percent>s%% Arch:%<pf>s/%<tf>s Dir:%<pd>s/%<td>s'
116
+ },
117
+ 'summary' => {
118
+ 'heading' => 'Resumen',
119
+ 'source' => 'Origen: %<path>s',
120
+ 'total_size' => 'Tamano total: %<size>s',
121
+ 'files' => 'Archivos: %<count>s',
122
+ 'directories' => 'Directorios: %<count>s',
123
+ 'skipped' => 'Entradas omitidas: %<count>s',
124
+ 'top_files' => 'Top archivos:',
125
+ 'none' => '(ninguno)'
92
126
  }
93
127
  },
94
128
  'report' => {
@@ -5,9 +5,10 @@ module FileTreeVisualizer
5
5
  DEFAULT_TOP_LIMIT = 200
6
6
  Result = Struct.new(:root, :top_files, :stats, keyword_init: true)
7
7
 
8
- def initialize(top_limit: DEFAULT_TOP_LIMIT, follow_symlinks: false)
8
+ def initialize(top_limit: DEFAULT_TOP_LIMIT, follow_symlinks: false, excludes: [])
9
9
  @top_limit = top_limit
10
10
  @follow_symlinks = follow_symlinks
11
+ @excludes = Array(excludes).map(&:to_s).reject(&:empty?)
11
12
  reset!
12
13
  end
13
14
 
@@ -16,6 +17,8 @@ module FileTreeVisualizer
16
17
  expanded_path = File.expand_path(path.to_s)
17
18
  raise ArgumentError, "Path is not a directory: #{expanded_path}" unless File.directory?(expanded_path)
18
19
 
20
+ @root_path = expanded_path
21
+
19
22
  @progress_callback = progress
20
23
  notify_counting_progress(force: true)
21
24
  totals = count_totals(expanded_path)
@@ -57,6 +60,7 @@ module FileTreeVisualizer
57
60
  @processed_directories = 0
58
61
  @counted_files = 0
59
62
  @counted_directories = 0
63
+ @root_path = nil
60
64
  end
61
65
 
62
66
  def scan_directory(path)
@@ -78,6 +82,11 @@ module FileTreeVisualizer
78
82
  entries = Dir.children(path)
79
83
  entries.each do |entry_name|
80
84
  child_path = File.join(path, entry_name)
85
+ if excluded_path?(child_path)
86
+ @skipped_count += 1
87
+ next
88
+ end
89
+
81
90
  process_child_node(child_path, entry_name, node)
82
91
  rescue StandardError
83
92
  @skipped_count += 1
@@ -142,6 +151,7 @@ module FileTreeVisualizer
142
151
  entries = Dir.children(path)
143
152
  entries.each do |entry_name|
144
153
  child_path = File.join(path, entry_name)
154
+ next if excluded_path?(child_path)
145
155
 
146
156
  begin
147
157
  if File.symlink?(child_path) && !@follow_symlinks
@@ -165,6 +175,22 @@ module FileTreeVisualizer
165
175
  totals
166
176
  end
167
177
 
178
+ def excluded_path?(path)
179
+ return false if @excludes.empty?
180
+
181
+ basename = File.basename(path)
182
+ relative = relative_path(path)
183
+ flags = File::FNM_PATHNAME | File::FNM_DOTMATCH | File::FNM_EXTGLOB
184
+
185
+ @excludes.any? do |pattern|
186
+ File.fnmatch?(pattern, basename, flags) || File.fnmatch?(pattern, relative, flags)
187
+ end
188
+ end
189
+
190
+ def relative_path(path)
191
+ path.delete_prefix("#{@root_path}/")
192
+ end
193
+
168
194
  def notify_progress
169
195
  return unless @progress_callback
170
196
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module FileTreeVisualizer
4
- VERSION = '0.1.0'
4
+ VERSION = '0.2.1'
5
5
  end
metadata CHANGED
@@ -1,19 +1,33 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: file_tree_visualizer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
- - jbidwell1
7
+ - John Bidwell
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
  date: 2026-04-04 00:00:00.000000000 Z
12
- dependencies: []
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: csv
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.3'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.3'
13
27
  description: Scans a directory recursively, computes file/directory sizes, and generates
14
28
  an HTML report rendered with React.
15
29
  email:
16
- - devnull@example.com
30
+ - johnbidwellb@gmail.com
17
31
  executables:
18
32
  - file-tree-visualizer
19
33
  extensions: []
@@ -34,7 +48,8 @@ homepage: https://github.com/JohnBidwellB/file-tree-visualizer
34
48
  licenses:
35
49
  - MIT
36
50
  metadata:
37
- source_code_uri: https://github.com/JohnBidwellB/file-tree-visualizer
51
+ source_code_uri: https://github.com/JohnBidwellB/file-tree-visualizer/tree/main
52
+ bug_tracker_uri: https://github.com/JohnBidwellB/file-tree-visualizer/issues
38
53
  changelog_uri: https://github.com/JohnBidwellB/file-tree-visualizer/blob/main/CHANGELOG.md
39
54
  post_install_message:
40
55
  rdoc_options: []