gitingest 0.1.0 → 0.2.0

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: 472ca8e21d2bb9e48eeeada768679586b002087a9253f966eb164fd6118236d2
4
- data.tar.gz: 1dddc890f5c380fb7ca2ca93db050473569dd1dd75c307f2d532857fc0f9ceaa
3
+ metadata.gz: 65bac565322a3c782e5a3da91648fbe1aef905af80344b7ab81d8223e7a39c08
4
+ data.tar.gz: ae9c73bc2df91ba61b10a01e36a15c2de7238104627c296408cfcc273851e885
5
5
  SHA512:
6
- metadata.gz: 1105676c81a389ea20a80a7be5ed2ea25c52fa2460c1672b0d5c45e19d2daf92c552a3d551cc71c196a9d0e2cbf96d779dc8e6b04f81965d323b31fff374f66a
7
- data.tar.gz: 9b565545bfbfc1f983109cbdf08470b6399471f46dbcb651173ab5ab97a806b5ac992eb5affd1b58f71f2d71788d971aba9fde1aead94f779453636392253684
6
+ metadata.gz: ba151945b20e7c5b4ce51af89a724f8673ec4b8928700b8922eecc8aeb7089fbe86e172d41289d308caff4ce1e88603be87416b1f743537c6b3f4e64d21515de
7
+ data.tar.gz: ce1aaff5e55cca369d8eeb6e3fd68a92e63b5258f35b5edd8698b505c5c6d84363189eedeb483c5553d62ce2b9011ecf9b119f222dbc51e91a28b5f7e5e369e1
data/CHANGELOG.md CHANGED
@@ -2,6 +2,17 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## [0.2.0] - 2025-03-02
6
+ - Added support for quiet and verbose modes in the command-line interface
7
+ - Added the ability to specify a custom output file for the prompt
8
+ - Enhanced error handling with logging support
9
+ - Added logging functionality with custom loggers
10
+ - Introduced rate limit handling with retries for file fetching
11
+ - Added repository branch support
12
+ - Exclude specific file patterns via command-line arguments
13
+ - Enforced a 1000 file limit to prevent memory overload
14
+ - Updated version to 0.2.0
15
+
5
16
  ## [0.1.0] - 2025-03-02
6
17
 
7
18
  ### Added
@@ -15,4 +26,4 @@ All notable changes to this project will be documented in this file.
15
26
  - Automatic rate limit handling with retry mechanism
16
27
  - Repository prompt generation with file separation markers
17
28
  - Support for custom branch selection
18
- - Custom output file naming options
29
+ - Custom output file naming options
data/README.md CHANGED
@@ -24,7 +24,26 @@ bundle exec rake install
24
24
  ### Command Line
25
25
 
26
26
  ```bash
27
- gitingest --repository username/repo --token YOUR_GITHUB_TOKEN --output output.txt
27
+ # Basic usage (public repository)
28
+ gitingest --repository user/repo
29
+
30
+ # With GitHub token for private repositories
31
+ gitingest --repository user/repo --token YOUR_GITHUB_TOKEN
32
+
33
+ # Specify a custom output file
34
+ gitingest --repository user/repo --output my_prompt.txt
35
+
36
+ # Specify a different branch
37
+ gitingest --repository user/repo --branch develop
38
+
39
+ # Exclude additional patterns
40
+ gitingest --repository user/repo --exclude "*.md,docs/"
41
+
42
+ # Quiet mode
43
+ gitingest --repository user/repo --quiet
44
+
45
+ # Verbose mode
46
+ gitingest --repository user/repo --verbose
28
47
  ```
29
48
 
30
49
  #### Available Options
@@ -39,17 +58,32 @@ gitingest --repository username/repo --token YOUR_GITHUB_TOKEN --output output.t
39
58
  ### As a Library
40
59
 
41
60
  ```ruby
42
- require 'gitingest'
61
+ require "gitingest"
43
62
 
44
- options = {
45
- repository: 'davidesantangelo/gitingest',
46
- token: 'your_github_token', # Optional
47
- output_file: 'output.txt', # Optional
48
- branch: 'master', # Optional
49
- exclude: ['node_modules', '.*\.png$'] # Optional
50
- }
63
+ # Basic usage
64
+ generator = Gitingest::Generator.new(
65
+ repository: "user/repo",
66
+ token: "YOUR_GITHUB_TOKEN" # optional
67
+ )
68
+ generator.run
51
69
 
52
- generator = Gitingest::Generator.new(options)
70
+ # With custom options
71
+ generator = Gitingest::Generator.new(
72
+ repository: "user/repo",
73
+ token: "YOUR_GITHUB_TOKEN",
74
+ output_file: "my_prompt.txt",
75
+ branch: "develop",
76
+ exclude: ["*.md", "docs/"],
77
+ quiet: true # or verbose: true
78
+ )
79
+ generator.run
80
+
81
+ # With custom logger
82
+ custom_logger = Logger.new("gitingest.log")
83
+ generator = Gitingest::Generator.new(
84
+ repository: "user/repo",
85
+ logger: custom_logger
86
+ )
53
87
  generator.run
54
88
  ```
55
89
 
@@ -64,19 +98,30 @@ generator.run
64
98
 
65
99
  ## Default Exclusion Patterns
66
100
 
67
- By default, Gitingest excludes the following files and directories:
101
+ By default, the generator excludes files and directories commonly ignored in repositories, such as:
102
+
103
+ - Version control files (`.git/`, `.svn/`)
104
+ - System files (`.DS_Store`, `Thumbs.db`)
105
+ - Log files (`*.log`, `*.bak`)
106
+ - Images and media files (`*.png`, `*.jpg`, `*.mp3`)
107
+ - Archives (`*.zip`, `*.tar.gz`)
108
+ - Dependency directories (`node_modules/`, `vendor/`)
109
+ - Compiled and binary files (`*.pyc`, `*.class`, `*.exe`)
68
110
 
69
- - `.git/`, `.github/`, `.gitignore`, `.DS_Store`
70
- - Log files: `.*\.log$`
71
- - Image files: `.*\.png$`, `.*\.jpg$`, `.*\.jpeg$`, `.*\.gif$`, `.*\.svg$`
72
- - Document files: `.*\.pdf$`
73
- - Archive files: `.*\.zip$`, `.*\.tar\.gz$`
74
- - Dependency directories: `node_modules/`, `vendor/`
111
+ ## Limitations
112
+
113
+ - To prevent memory overload, only the first 1000 files will be processed
114
+ - API requests are subject to GitHub limits (60 requests/hour without token, 5000 requests/hour with token)
115
+ - Private repositories require a GitHub personal access token
75
116
 
76
117
  ## Contributing
77
118
 
78
119
  Bug reports and pull requests are welcome on GitHub at https://github.com/davidesantangelo/gitingest.
79
120
 
121
+ ## Acknowledgements
122
+
123
+ Inspired by [`cyclotruc/gitingest`](https://github.com/cyclotruc/gitingest).
124
+
80
125
  ## License
81
126
 
82
127
  The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/bin/gitingest CHANGED
@@ -6,15 +6,38 @@ require "gitingest"
6
6
 
7
7
  options = {}
8
8
  parser = OptionParser.new do |opts|
9
- opts.banner = "Usage: gitingest [options]"
9
+ opts.banner = "Usage: gitingest [OPTIONS]"
10
+ opts.separator ""
11
+ opts.separator "Options:"
12
+
13
+ opts.on("-r", "--repository REPO", "GitHub repository (username/repo) [Required]") do |repo|
14
+ options[:repository] = repo
15
+ end
16
+
17
+ opts.on("-t", "--token TOKEN", "GitHub personal access token") do |token|
18
+ options[:token] = token
19
+ end
20
+
21
+ opts.on("-o", "--output FILE", "Output file for the prompt") do |file|
22
+ options[:output_file] = file
23
+ end
24
+
25
+ opts.on("-b", "--branch BRANCH", "Repository branch") do |branch|
26
+ options[:branch] = branch
27
+ end
10
28
 
11
- opts.on("-r", "--repository REPO", "GitHub repository (username/repo)") { |repo| options[:repository] = repo }
12
- opts.on("-t", "--token TOKEN", "GitHub personal access token") { |token| options[:token] = token }
13
- opts.on("-o", "--output FILE", "Output file for the prompt") { |file| options[:output_file] = file }
14
29
  opts.on("-e", "--exclude PATTERN", "File patterns to exclude (comma separated)") do |pattern|
15
- options[:exclude] = pattern.split(",").map(&:strip)
30
+ options[:exclude] = pattern.split(",")
16
31
  end
17
- opts.on("-b", "--branch BRANCH", "Repository branch (default: main)") { |branch| options[:branch] = branch }
32
+
33
+ opts.on("-q", "--quiet", "Disable all output except errors") do
34
+ options[:quiet] = true
35
+ end
36
+
37
+ opts.on("-v", "--verbose", "Enable verbose output") do
38
+ options[:verbose] = true
39
+ end
40
+
18
41
  opts.on("-h", "--help", "Show this help message") do
19
42
  puts opts
20
43
  exit
@@ -23,9 +46,16 @@ end
23
46
 
24
47
  begin
25
48
  parser.parse!
49
+
50
+ if options[:repository].nil?
51
+ puts "Error: Repository option is required"
52
+ puts parser
53
+ exit 1
54
+ end
55
+
26
56
  generator = Gitingest::Generator.new(options)
27
57
  generator.run
28
- rescue ArgumentError => e
58
+ rescue OptionParser::InvalidOption => e
29
59
  puts "Error: #{e.message}"
30
60
  puts parser
31
61
  exit 1
@@ -4,6 +4,7 @@ require "octokit"
4
4
  require "base64"
5
5
  require "fileutils"
6
6
  require "concurrent"
7
+ require "logger"
7
8
 
8
9
  module Gitingest
9
10
  class Generator
@@ -67,17 +68,31 @@ module Gitingest
67
68
  # Maximum number of files to process to prevent memory overload
68
69
  MAX_FILES = 1000
69
70
 
70
- attr_reader :options, :client, :repo_files, :excluded_patterns
71
+ attr_reader :options, :client, :repo_files, :excluded_patterns, :logger
71
72
 
72
73
  def initialize(options = {})
73
74
  @options = options
74
75
  @repo_files = []
75
76
  @excluded_patterns = []
77
+ setup_logger
76
78
  validate_options
77
79
  configure_client
78
80
  compile_excluded_patterns
79
81
  end
80
82
 
83
+ def setup_logger
84
+ @logger = @options[:logger] || Logger.new($stdout)
85
+ @logger.level = if @options[:quiet]
86
+ Logger::ERROR
87
+ elsif @options[:verbose]
88
+ Logger::DEBUG
89
+ else
90
+ Logger::INFO
91
+ end
92
+ # Semplifica il formato del logger per la riga di comando
93
+ @logger.formatter = proc { |severity, _, _, msg| "#{severity == "INFO" ? "" : "[#{severity}] "}#{msg}\n" }
94
+ end
95
+
81
96
  ### Option Validation
82
97
  def validate_options
83
98
  raise ArgumentError, "Repository is required" unless @options[:repository]
@@ -93,10 +108,10 @@ module Gitingest
93
108
  @client = @options[:token] ? Octokit::Client.new(access_token: @options[:token]) : Octokit::Client.new
94
109
 
95
110
  if @options[:token]
96
- puts "Using provided GitHub token for authentication"
111
+ @logger.info "Using provided GitHub token for authentication"
97
112
  else
98
- puts "Warning: No token provided. API rate limits will be restricted and private repositories will be inaccessible."
99
- puts "For better results, provide a GitHub token with the --token option."
113
+ @logger.warn "Warning: No token provided. API rate limits will be restricted and private repositories will be inaccessible."
114
+ @logger.warn "For better results, provide a GitHub token with the --token option."
100
115
  end
101
116
  end
102
117
 
@@ -106,7 +121,7 @@ module Gitingest
106
121
 
107
122
  ### Fetch Repository Contents
108
123
  def fetch_repository_contents
109
- puts "Fetching repository: #{@options[:repository]} (branch: #{@options[:branch]})"
124
+ @logger.info "Fetching repository: #{@options[:repository]} (branch: #{@options[:branch]})"
110
125
  begin
111
126
  # First validate authentication and repository access
112
127
  validate_repository_access
@@ -115,10 +130,10 @@ module Gitingest
115
130
  @repo_files = repo_tree.tree.select { |item| item.type == "blob" && !excluded_file?(item.path) }
116
131
 
117
132
  if @repo_files.size > MAX_FILES
118
- puts "Warning: Found #{@repo_files.size} files, limited to #{MAX_FILES}."
133
+ @logger.warn "Warning: Found #{@repo_files.size} files, limited to #{MAX_FILES}."
119
134
  @repo_files = @repo_files.first(MAX_FILES)
120
135
  end
121
- puts "Found #{@repo_files.size} files after exclusion filters"
136
+ @logger.info "Found #{@repo_files.size} files after exclusion filters"
122
137
  rescue Octokit::Unauthorized
123
138
  raise "Authentication error: Invalid or expired GitHub token. Please provide a valid token."
124
139
  rescue Octokit::NotFound
@@ -154,7 +169,7 @@ module Gitingest
154
169
 
155
170
  ### Generate Prompt
156
171
  def generate_prompt
157
- puts "Generating prompt..."
172
+ @logger.info "Generating prompt..."
158
173
  Concurrent::Array.new(@repo_files)
159
174
  buffer = []
160
175
  buffer_size = 100 # Write every 100 files to reduce I/O
@@ -177,14 +192,14 @@ module Gitingest
177
192
  write_buffer(file, buffer) if buffer.size >= buffer_size
178
193
  print "\rProcessing: #{index + 1}/#{@repo_files.size} files"
179
194
  rescue Octokit::Error => e
180
- puts "\nError fetching #{repo_file.path}: #{e.message}"
195
+ @logger.error "Error fetching #{repo_file.path}: #{e.message}"
181
196
  end
182
197
  end
183
198
  pool.shutdown
184
199
  pool.wait_for_termination
185
200
  write_buffer(file, buffer) unless buffer.empty?
186
201
  end
187
- puts "\nPrompt generated and saved to #{@options[:output_file]}"
202
+ @logger.info "\nPrompt generated and saved to #{@options[:output_file]}"
188
203
  end
189
204
 
190
205
  def fetch_file_content_with_retry(path, retries = 3)
@@ -194,7 +209,7 @@ module Gitingest
194
209
  raise unless retries.positive?
195
210
 
196
211
  sleep_time = 60 / retries
197
- puts "Rate limit exceeded, waiting #{sleep_time} seconds..."
212
+ @logger.warn "Rate limit exceeded, waiting #{sleep_time} seconds..."
198
213
  sleep(sleep_time)
199
214
  fetch_file_content_with_retry(path, retries - 1)
200
215
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Gitingest
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gitingest
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Davide Santangelo