poepod 0.1.3 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/rake.yml +1 -4
- data/.github/workflows/release.yml +5 -6
- data/README.adoc +79 -22
- data/lib/poepod/cli.rb +52 -16
- data/lib/poepod/file_processor.rb +79 -0
- data/lib/poepod/gem_processor.rb +81 -0
- data/lib/poepod/processor.rb +3 -67
- data/lib/poepod/version.rb +1 -1
- data/poepod.gemspec +4 -4
- data/spec/poepod/cli_spec.rb +90 -0
- data/spec/poepod/file_processor_spec.rb +63 -0
- data/spec/poepod/gem_processor_spec.rb +158 -0
- data/spec/poepod_spec.rb +7 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/support/test_files/file1.txt +1 -0
- data/spec/support/test_files/file2.txt +1 -0
- metadata +51 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: db687d7a65f167645bedbabce5082c8d254a70f891b493a7f900a4666b07dfc3
|
4
|
+
data.tar.gz: 159ed36950788d819b870a2f8d5e8d1e7c26103cdadc11702073bca959885711
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 53e110b148f0e78e7f9c257f18619f4c5718d01d390c8a604fd9a928349a25ca8840a26ac6130dc793f7687783732d360100c96195b88f83a2af20b58bed7723
|
7
|
+
data.tar.gz: 007e29ab64c3c3984aaef34a700fe3384c97d3f784f93cda466d8335252b979829b0373d7802737990bf8e65c618fa2e00fd46970a2345e57c35a24a33ddc05d
|
data/.github/workflows/rake.yml
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
# Auto-generated by Cimas: Do not edit it manually!
|
2
|
-
# See https://github.com/metanorma/cimas
|
3
1
|
name: rake
|
4
2
|
|
5
3
|
on:
|
@@ -7,9 +5,8 @@ on:
|
|
7
5
|
branches: [ master, main ]
|
8
6
|
tags: [ v* ]
|
9
7
|
pull_request:
|
8
|
+
workflow_dispatch:
|
10
9
|
|
11
10
|
jobs:
|
12
11
|
rake:
|
13
12
|
uses: metanorma/ci/.github/workflows/generic-rake.yml@main
|
14
|
-
secrets:
|
15
|
-
pat_token: ${{ secrets.METANORMA_CI_PAT_TOKEN }}
|
@@ -1,5 +1,3 @@
|
|
1
|
-
# Auto-generated by Cimas: Do not edit it manually!
|
2
|
-
# See https://github.com/metanorma/cimas
|
3
1
|
name: release
|
4
2
|
|
5
3
|
on:
|
@@ -10,8 +8,8 @@ on:
|
|
10
8
|
Next release version. Possible values: x.y.z, major, minor, patch or pre|rc|etc
|
11
9
|
required: true
|
12
10
|
default: 'skip'
|
13
|
-
|
14
|
-
|
11
|
+
push:
|
12
|
+
tags: [ v* ]
|
15
13
|
|
16
14
|
jobs:
|
17
15
|
release:
|
@@ -19,5 +17,6 @@ jobs:
|
|
19
17
|
with:
|
20
18
|
next_version: ${{ github.event.inputs.next_version }}
|
21
19
|
secrets:
|
22
|
-
rubygems-api-key: ${{ secrets.
|
23
|
-
pat_token: ${{ secrets.
|
20
|
+
rubygems-api-key: ${{ secrets.RIBOSE_RUBYGEMS_API_KEY }}
|
21
|
+
pat_token: ${{ secrets.RIBOSE_CI_PAT_TOKEN }}
|
22
|
+
|
data/README.adoc
CHANGED
@@ -1,7 +1,10 @@
|
|
1
1
|
= Poepod
|
2
2
|
|
3
|
-
Poepod is a Ruby gem that
|
4
|
-
|
3
|
+
Poepod is a Ruby gem that streamlines the process of preparing code for analysis
|
4
|
+
by Poe. It offers two main features: concatenating multiple files into a single
|
5
|
+
text file, and wrapping gem contents including unstaged files. These features
|
6
|
+
are particularly useful for developers who want to quickly gather code for
|
7
|
+
review, analysis, or submission to AI-powered coding assistants.
|
5
8
|
|
6
9
|
== Installation
|
7
10
|
|
@@ -28,49 +31,102 @@ $ gem install poepod
|
|
28
31
|
|
29
32
|
== Usage
|
30
33
|
|
31
|
-
After installation, you can use the `poepod` command line tool
|
32
|
-
code files:
|
34
|
+
After installation, you can use the `poepod` command line tool:
|
33
35
|
|
34
36
|
[source,shell]
|
35
37
|
----
|
36
38
|
$ poepod help
|
37
39
|
Commands:
|
38
|
-
poepod concat
|
39
|
-
poepod help [COMMAND]
|
40
|
+
poepod concat FILES [OUTPUT_FILE] # Concatenate specified files into one text file
|
41
|
+
poepod help [COMMAND] # Describe available commands or one specific command
|
42
|
+
poepod wrap GEMSPEC_PATH # Wrap a gem based on its gemspec file
|
43
|
+
----
|
44
|
+
|
45
|
+
=== Concatenating files
|
46
|
+
|
47
|
+
The `concat` command allows you to combine multiple files into a single text
|
48
|
+
file. This is particularly useful when you want to review or analyze code from
|
49
|
+
multiple files in one place, or when preparing code submissions for AI-powered
|
50
|
+
coding assistants.
|
51
|
+
|
52
|
+
[source,shell]
|
53
|
+
----
|
54
|
+
$ poepod concat path/to/files/* output.txt
|
55
|
+
----
|
56
|
+
|
57
|
+
This will concatenate all files from the specified path into `output.txt`.
|
58
|
+
|
59
|
+
==== Excluding patterns
|
60
|
+
|
61
|
+
You can exclude certain patterns using the `--exclude` option:
|
62
|
+
|
63
|
+
[source,shell]
|
64
|
+
----
|
65
|
+
$ poepod concat path/to/files/* output.txt --exclude node_modules .git build test
|
66
|
+
----
|
67
|
+
|
68
|
+
This is helpful when you want to focus on specific parts of your codebase,
|
69
|
+
excluding irrelevant or large directories.
|
40
70
|
|
41
|
-
|
42
|
-
Usage:
|
43
|
-
poepod concat DIRECTORY OUTPUT_FILE
|
71
|
+
==== Including binary files
|
44
72
|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
[--config=CONFIG] # Path to configuration file
|
73
|
+
By default, binary files are excluded to keep the output focused on readable
|
74
|
+
code. However, you can include binary files (encoded in MIME format) using the
|
75
|
+
`--include-binary` option:
|
49
76
|
|
50
|
-
|
77
|
+
[source,shell]
|
78
|
+
----
|
79
|
+
$ poepod concat path/to/files/* output.txt --include-binary
|
51
80
|
----
|
52
81
|
|
53
|
-
|
82
|
+
This can be useful when you need to include binary assets or compiled files in
|
83
|
+
your analysis.
|
84
|
+
|
85
|
+
=== Wrapping a gem
|
86
|
+
|
87
|
+
The `wrap` command creates a comprehensive snapshot of your gem, including all
|
88
|
+
files specified in the gemspec and README files. This is particularly useful for
|
89
|
+
gem developers who want to review their entire gem contents or prepare it for
|
90
|
+
submission to code review tools.
|
54
91
|
|
55
92
|
[source,shell]
|
56
93
|
----
|
57
|
-
$ poepod
|
58
|
-
# => concatenated into my_project.txt
|
94
|
+
$ poepod wrap path/to/your_gem.gemspec
|
59
95
|
----
|
60
96
|
|
61
|
-
This will
|
97
|
+
This will create a file named `your_gem_wrapped.txt` containing all the files
|
98
|
+
specified in the gemspec, including README files.
|
99
|
+
|
100
|
+
==== Handling unstaged files
|
62
101
|
|
63
|
-
|
102
|
+
By default, unstaged files in the `lib/`, `spec/`, and `test/` directories are
|
103
|
+
not included in the wrap, but they will be listed as a warning. This default
|
104
|
+
behavior ensures that the wrapped content matches what's currently tracked in
|
105
|
+
your version control system.
|
106
|
+
|
107
|
+
However, there are cases where including unstaged files can be beneficial:
|
108
|
+
|
109
|
+
. When you're actively developing and want to include recent changes that
|
110
|
+
haven't been committed yet.
|
111
|
+
|
112
|
+
. When you're seeking feedback on work-in-progress code.
|
113
|
+
|
114
|
+
. When you want to ensure you're not missing any important files in your commit.
|
115
|
+
|
116
|
+
To include these unstaged files in the wrap:
|
64
117
|
|
65
118
|
[source,shell]
|
66
119
|
----
|
67
|
-
$ poepod
|
120
|
+
$ poepod wrap path/to/your_gem.gemspec --include-unstaged
|
68
121
|
----
|
69
122
|
|
123
|
+
This option allows you to capture a true snapshot of your gem's current state,
|
124
|
+
including any work in progress.
|
125
|
+
|
70
126
|
== Development
|
71
127
|
|
72
128
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run
|
73
|
-
`rake
|
129
|
+
`rake spec` to run the tests. You can also run `bin/console` for an interactive
|
74
130
|
prompt that will allow you to experiment.
|
75
131
|
|
76
132
|
To install this gem onto your local machine, run `bundle exec rake install`. To
|
@@ -81,4 +137,5 @@ https://rubygems.org.
|
|
81
137
|
|
82
138
|
== Contributing
|
83
139
|
|
84
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/riboseinc/poepod.
|
140
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/riboseinc/poepod.
|
141
|
+
Please adhere to the link:CODE_OF_CONDUCT.md[code of conduct].
|
data/lib/poepod/cli.rb
CHANGED
@@ -1,36 +1,72 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# lib/poepod/cli.rb
|
3
4
|
require "thor"
|
4
|
-
require_relative "
|
5
|
+
require_relative "file_processor"
|
6
|
+
require_relative "gem_processor"
|
5
7
|
|
6
8
|
module Poepod
|
7
9
|
class Cli < Thor
|
8
|
-
desc "concat
|
9
|
-
option :exclude, type: :array, default: Poepod::
|
10
|
+
desc "concat FILES [OUTPUT_FILE]", "Concatenate specified files into one text file"
|
11
|
+
option :exclude, type: :array, default: Poepod::FileProcessor::EXCLUDE_DEFAULT, desc: "List of patterns to exclude"
|
10
12
|
option :config, type: :string, desc: "Path to configuration file"
|
13
|
+
option :include_binary, type: :boolean, default: false, desc: "Include binary files (encoded in MIME format)"
|
11
14
|
|
12
|
-
def concat(
|
13
|
-
|
14
|
-
|
15
|
-
# Check if the directory exists
|
16
|
-
unless dir_path.directory?
|
17
|
-
puts "Error: Directory '#{directory}' does not exist."
|
15
|
+
def concat(*files, output_file: nil)
|
16
|
+
if files.empty?
|
17
|
+
puts "Error: No files specified."
|
18
18
|
exit(1)
|
19
19
|
end
|
20
20
|
|
21
|
-
|
21
|
+
output_file ||= default_output_file(files.first)
|
22
|
+
output_path = Pathname.new(output_file).expand_path
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
processor = Poepod::Processor.new(options[:config])
|
26
|
-
total_files, copied_files = processor.write_directory_structure_to_file(directory, output_path, options[:exclude])
|
24
|
+
processor = Poepod::FileProcessor.new(files, output_path, options[:config], options[:include_binary])
|
25
|
+
total_files, copied_files = processor.process
|
27
26
|
|
28
|
-
puts "-> #{total_files} files detected
|
29
|
-
puts "=> #{copied_files} files have been concatenated into #{
|
27
|
+
puts "-> #{total_files} files detected."
|
28
|
+
puts "=> #{copied_files} files have been concatenated into #{output_path.relative_path_from(Dir.pwd)}."
|
29
|
+
end
|
30
|
+
|
31
|
+
desc "wrap GEMSPEC_PATH", "Wrap a gem based on its gemspec file"
|
32
|
+
option :include_unstaged, type: :boolean, default: false,
|
33
|
+
desc: "Include unstaged files from lib, spec, and test directories"
|
34
|
+
|
35
|
+
def wrap(gemspec_path)
|
36
|
+
processor = Poepod::GemProcessor.new(gemspec_path, nil, options[:include_unstaged])
|
37
|
+
success, result, unstaged_files = processor.process
|
38
|
+
|
39
|
+
if success
|
40
|
+
puts "=> The gem has been wrapped into '#{result}'."
|
41
|
+
if unstaged_files.any?
|
42
|
+
puts "\nWarning: The following files are not staged in git:"
|
43
|
+
puts unstaged_files
|
44
|
+
puts "\nThese files are #{options[:include_unstaged] ? "included" : "not included"} in the wrap."
|
45
|
+
puts "Use --include-unstaged option to include these files." unless options[:include_unstaged]
|
46
|
+
end
|
47
|
+
else
|
48
|
+
puts result
|
49
|
+
exit(1)
|
50
|
+
end
|
30
51
|
end
|
31
52
|
|
32
53
|
def self.exit_on_failure?
|
33
54
|
true
|
34
55
|
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def default_output_file(first_pattern)
|
60
|
+
first_item = Dir.glob(first_pattern).first
|
61
|
+
if first_item
|
62
|
+
if File.directory?(first_item)
|
63
|
+
"#{File.basename(first_item)}.txt"
|
64
|
+
else
|
65
|
+
"#{File.basename(first_item, ".*")}_concat.txt"
|
66
|
+
end
|
67
|
+
else
|
68
|
+
"concatenated_output.txt"
|
69
|
+
end
|
70
|
+
end
|
35
71
|
end
|
36
72
|
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative "processor"
|
4
|
+
require "yaml"
|
5
|
+
require "tqdm"
|
6
|
+
require "pathname"
|
7
|
+
require "open3"
|
8
|
+
require "base64"
|
9
|
+
require "mime/types"
|
10
|
+
|
11
|
+
module Poepod
|
12
|
+
class FileProcessor < Processor
|
13
|
+
EXCLUDE_DEFAULT = [
|
14
|
+
%r{node_modules/}, %r{.git/}, /.gitignore$/, /.DS_Store$/
|
15
|
+
].freeze
|
16
|
+
|
17
|
+
def initialize(files, output_file, config_file = nil, include_binary = false)
|
18
|
+
super(config_file)
|
19
|
+
@files = files
|
20
|
+
@output_file = output_file
|
21
|
+
@failed_files = []
|
22
|
+
@include_binary = include_binary
|
23
|
+
end
|
24
|
+
|
25
|
+
def process
|
26
|
+
total_files = 0
|
27
|
+
copied_files = 0
|
28
|
+
|
29
|
+
File.open(@output_file, "w", encoding: "utf-8") do |output|
|
30
|
+
@files.each do |file|
|
31
|
+
Dir.glob(file).each do |matched_file|
|
32
|
+
next unless File.file?(matched_file)
|
33
|
+
|
34
|
+
total_files += 1
|
35
|
+
file_path, content, error = process_file(matched_file)
|
36
|
+
if content
|
37
|
+
output.puts "--- START FILE: #{file_path} ---"
|
38
|
+
output.puts content
|
39
|
+
output.puts "--- END FILE: #{file_path} ---"
|
40
|
+
copied_files += 1
|
41
|
+
elsif error
|
42
|
+
output.puts "#{file_path}\n#{error}"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
[total_files, copied_files]
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def process_file(file_path)
|
54
|
+
if text_file?(file_path)
|
55
|
+
content = File.read(file_path, encoding: "utf-8")
|
56
|
+
[file_path, content, nil]
|
57
|
+
elsif @include_binary
|
58
|
+
content = encode_binary_file(file_path)
|
59
|
+
[file_path, content, nil]
|
60
|
+
else
|
61
|
+
[file_path, nil, "Skipped binary file"]
|
62
|
+
end
|
63
|
+
rescue Encoding::InvalidByteSequenceError, Encoding::UndefinedConversionError
|
64
|
+
@failed_files << file_path
|
65
|
+
[file_path, nil, "Failed to decode the file, as it is not saved with UTF-8 encoding."]
|
66
|
+
end
|
67
|
+
|
68
|
+
def text_file?(file_path)
|
69
|
+
stdout, status = Open3.capture2("file", "-b", "--mime-type", file_path)
|
70
|
+
status.success? && stdout.strip.start_with?("text/")
|
71
|
+
end
|
72
|
+
|
73
|
+
def encode_binary_file(file_path)
|
74
|
+
mime_type = MIME::Types.type_for(file_path).first.content_type
|
75
|
+
encoded_content = Base64.strict_encode64(File.binread(file_path))
|
76
|
+
"Content-Type: #{mime_type}\nContent-Transfer-Encoding: base64\n\n#{encoded_content}"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# lib/poepod/gem_processor.rb
|
4
|
+
require_relative "processor"
|
5
|
+
require "rubygems/specification"
|
6
|
+
require "git"
|
7
|
+
|
8
|
+
module Poepod
|
9
|
+
class GemProcessor < Processor
|
10
|
+
def initialize(gemspec_path, config_file = nil, include_unstaged = false)
|
11
|
+
super(config_file)
|
12
|
+
@gemspec_path = gemspec_path
|
13
|
+
@include_unstaged = include_unstaged
|
14
|
+
end
|
15
|
+
|
16
|
+
def process
|
17
|
+
unless File.exist?(@gemspec_path)
|
18
|
+
return [false, "Error: The specified gemspec file '#{@gemspec_path}' does not exist."]
|
19
|
+
end
|
20
|
+
|
21
|
+
begin
|
22
|
+
spec = Gem::Specification.load(@gemspec_path)
|
23
|
+
rescue StandardError => e
|
24
|
+
return [false, "Error loading gemspec: #{e.message}"]
|
25
|
+
end
|
26
|
+
|
27
|
+
gem_name = spec.name
|
28
|
+
output_file = "#{gem_name}_wrapped.txt"
|
29
|
+
unstaged_files = check_unstaged_files
|
30
|
+
|
31
|
+
File.open(output_file, "w") do |file|
|
32
|
+
file.puts "# Wrapped Gem: #{gem_name}"
|
33
|
+
file.puts "## Gemspec: #{File.basename(@gemspec_path)}"
|
34
|
+
|
35
|
+
if unstaged_files.any?
|
36
|
+
file.puts "\n## Warning: Unstaged Files"
|
37
|
+
file.puts unstaged_files.join("\n")
|
38
|
+
file.puts "\nThese files are not included in the wrap unless --include-unstaged option is used."
|
39
|
+
end
|
40
|
+
|
41
|
+
file.puts "\n## Files:\n"
|
42
|
+
|
43
|
+
files_to_include = (spec.files + spec.test_files + find_readme_files).uniq
|
44
|
+
files_to_include += unstaged_files if @include_unstaged
|
45
|
+
|
46
|
+
files_to_include.uniq.each do |relative_path|
|
47
|
+
full_path = File.join(File.dirname(@gemspec_path), relative_path)
|
48
|
+
next unless File.file?(full_path)
|
49
|
+
|
50
|
+
file.puts "--- START FILE: #{relative_path} ---"
|
51
|
+
file.puts File.read(full_path)
|
52
|
+
file.puts "--- END FILE: #{relative_path} ---\n\n"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
[true, output_file, unstaged_files]
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
def find_readme_files
|
62
|
+
Dir.glob(File.join(File.dirname(@gemspec_path), "README*"))
|
63
|
+
.map { |path| Pathname.new(path).relative_path_from(Pathname.new(File.dirname(@gemspec_path))).to_s }
|
64
|
+
end
|
65
|
+
|
66
|
+
def check_unstaged_files
|
67
|
+
gem_root = File.dirname(@gemspec_path)
|
68
|
+
git = Git.open(gem_root)
|
69
|
+
|
70
|
+
untracked_files = git.status.untracked.keys
|
71
|
+
modified_files = git.status.changed.keys
|
72
|
+
|
73
|
+
(untracked_files + modified_files).select do |file|
|
74
|
+
file.start_with?("lib/", "spec/", "test/")
|
75
|
+
end
|
76
|
+
rescue Git::GitExecuteError => e
|
77
|
+
warn "Git error: #{e.message}. Assuming no unstaged files."
|
78
|
+
[]
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
data/lib/poepod/processor.rb
CHANGED
@@ -1,20 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
require "tqdm"
|
5
|
-
require "pathname"
|
6
|
-
|
3
|
+
# lib/poepod/processor.rb
|
7
4
|
module Poepod
|
8
5
|
class Processor
|
9
|
-
EXCLUDE_DEFAULT = [
|
10
|
-
/node_modules\//, /.git\//, /.gitignore$/, /.DS_Store$/,
|
11
|
-
/.jpg$/, /.jpeg$/, /.png/, /.svg$/, /.gif$/,
|
12
|
-
/.exe$/, /.dll$/, /.so$/, /.bin$/, /.o$/, /.a$/, /.gem$/, /.cap$/,
|
13
|
-
/.zip$/,
|
14
|
-
].freeze
|
15
|
-
|
16
6
|
def initialize(config_file = nil)
|
17
|
-
@failed_files = []
|
18
7
|
@config = load_config(config_file)
|
19
8
|
end
|
20
9
|
|
@@ -26,61 +15,8 @@ module Poepod
|
|
26
15
|
end
|
27
16
|
end
|
28
17
|
|
29
|
-
def
|
30
|
-
|
31
|
-
[file_path, content, nil]
|
32
|
-
rescue Encoding::InvalidByteSequenceError, Encoding::UndefinedConversionError
|
33
|
-
@failed_files << file_path
|
34
|
-
[file_path, nil, "Failed to decode the file, as it is not saved with UTF-8 encoding."]
|
35
|
-
end
|
36
|
-
|
37
|
-
def gather_files(directory_path, exclude)
|
38
|
-
exclude += @config["exclude"] if @config["exclude"]
|
39
|
-
exclude_pattern = Regexp.union(exclude.map { |ex| Regexp.new(ex) })
|
40
|
-
|
41
|
-
Dir.glob("#{directory_path}/**/*").reject do |file_path|
|
42
|
-
File.directory?(file_path) || file_path.match?(exclude_pattern)
|
43
|
-
end.map do |file_path|
|
44
|
-
Pathname.new(file_path).expand_path.to_s
|
45
|
-
end
|
46
|
-
end
|
47
|
-
|
48
|
-
def write_results_to_file(results, output_file)
|
49
|
-
results.each_with_index do |(file_path, content, error), index|
|
50
|
-
relative = relative_path(file_path)
|
51
|
-
if content
|
52
|
-
output_file.puts "--- START FILE: #{relative} ---"
|
53
|
-
output_file.puts content
|
54
|
-
output_file.puts "--- END FILE: #{relative} ---"
|
55
|
-
elsif error
|
56
|
-
output_file.puts "#{relative}\n#{error}"
|
57
|
-
end
|
58
|
-
output_file.puts if index < results.size - 1 # Add a newline between files
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
def relative_path(file_path)
|
63
|
-
Pathname.new(file_path).relative_path_from(Dir.pwd)
|
64
|
-
end
|
65
|
-
|
66
|
-
def write_directory_structure_to_file(directory_path, output_file_name, exclude = EXCLUDE_DEFAULT)
|
67
|
-
dir_path = Pathname.new(directory_path)
|
68
|
-
|
69
|
-
dir_path = dir_path.expand_path unless dir_path.absolute?
|
70
|
-
|
71
|
-
file_list = gather_files(dir_path, exclude)
|
72
|
-
total_files = file_list.size
|
73
|
-
|
74
|
-
File.open(output_file_name, "w", encoding: "utf-8") do |output_file|
|
75
|
-
results = file_list.tqdm(desc: "Progress", unit: " file").map do |file|
|
76
|
-
process_file(file)
|
77
|
-
end
|
78
|
-
write_results_to_file(results, output_file)
|
79
|
-
end
|
80
|
-
|
81
|
-
copied_files = total_files - @failed_files.size
|
82
|
-
|
83
|
-
[total_files, copied_files]
|
18
|
+
def process
|
19
|
+
raise NotImplementedError, "Subclasses must implement the 'process' method"
|
84
20
|
end
|
85
21
|
end
|
86
22
|
end
|
data/lib/poepod/version.rb
CHANGED
data/poepod.gemspec
CHANGED
@@ -16,10 +16,6 @@ Gem::Specification.new do |spec|
|
|
16
16
|
spec.homepage = "https://github.com/riboseinc/poepod"
|
17
17
|
spec.license = "BSD-2-Clause"
|
18
18
|
|
19
|
-
spec.bindir = "bin"
|
20
|
-
spec.require_paths = ["lib"]
|
21
|
-
spec.files = `git ls-files`.split("\n")
|
22
|
-
spec.test_files = `git ls-files -- {spec}/*`.split("\n")
|
23
19
|
spec.required_ruby_version = Gem::Requirement.new(">= 3.0.0")
|
24
20
|
|
25
21
|
# Specify which files should be added to the gem when it is released.
|
@@ -32,10 +28,14 @@ Gem::Specification.new do |spec|
|
|
32
28
|
spec.bindir = "exe"
|
33
29
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
34
30
|
spec.require_paths = ["lib"]
|
31
|
+
spec.test_files = `git ls-files -- spec/*`.split("\n")
|
35
32
|
|
33
|
+
spec.add_runtime_dependency "git", "~> 1.11"
|
34
|
+
spec.add_runtime_dependency "mime-types", "~> 3.3"
|
36
35
|
spec.add_runtime_dependency "parallel", "~> 1.20"
|
37
36
|
spec.add_runtime_dependency "thor", "~> 1.0"
|
38
37
|
spec.add_runtime_dependency "tqdm"
|
38
|
+
|
39
39
|
spec.add_development_dependency "rake"
|
40
40
|
spec.add_development_dependency "rspec"
|
41
41
|
spec.add_development_dependency "rubocop"
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
require "poepod/cli"
|
5
|
+
|
6
|
+
RSpec.describe Poepod::Cli do
|
7
|
+
let(:cli) { described_class.new }
|
8
|
+
|
9
|
+
describe "#concat" do
|
10
|
+
let(:temp_dir) { Dir.mktmpdir }
|
11
|
+
let(:text_file) { File.join(temp_dir, "text_file.txt") }
|
12
|
+
let(:binary_file) { File.join(temp_dir, "binary_file.bin") }
|
13
|
+
|
14
|
+
before do
|
15
|
+
File.write(text_file, "Hello, World!")
|
16
|
+
File.write(binary_file, [0xFF, 0xD8, 0xFF, 0xE0].pack("C*"))
|
17
|
+
end
|
18
|
+
|
19
|
+
after do
|
20
|
+
FileUtils.remove_entry(temp_dir)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "concatenates text files" do
|
24
|
+
output_file = File.join(temp_dir, "output.txt")
|
25
|
+
expect { cli.concat(text_file, output_file: output_file) }.to output(/1 files detected/).to_stdout
|
26
|
+
expect(File.exist?(output_file)).to be true
|
27
|
+
expect(File.read(output_file)).to include("Hello, World!")
|
28
|
+
end
|
29
|
+
|
30
|
+
it "excludes binary files by default" do
|
31
|
+
output_file = File.join(temp_dir, "output.txt")
|
32
|
+
expect do
|
33
|
+
cli.concat(text_file, binary_file,
|
34
|
+
output_file: output_file)
|
35
|
+
end.to output(/-> 2 files detected\.\n=> 1 files have been concatenated into.*\.txt/).to_stdout
|
36
|
+
end
|
37
|
+
|
38
|
+
it "includes binary files when specified" do
|
39
|
+
output_file = File.join(temp_dir, "output.txt")
|
40
|
+
expect do
|
41
|
+
cli.invoke(:concat, [text_file, binary_file], output_file: output_file,
|
42
|
+
include_binary: true)
|
43
|
+
end.to output(/-> 2 files detected\.\n=> 2 files have been concatenated into.*\.txt/).to_stdout
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "#wrap" do
|
48
|
+
let(:temp_dir) { Dir.mktmpdir }
|
49
|
+
let(:gemspec_file) { File.join(temp_dir, "test_gem.gemspec") }
|
50
|
+
|
51
|
+
before do
|
52
|
+
File.write(gemspec_file, <<~GEMSPEC)
|
53
|
+
Gem::Specification.new do |spec|
|
54
|
+
spec.name = "test_gem"
|
55
|
+
spec.version = "0.1.0"
|
56
|
+
spec.authors = ["Test Author"]
|
57
|
+
spec.files = ["lib/test_gem.rb"]
|
58
|
+
end
|
59
|
+
GEMSPEC
|
60
|
+
|
61
|
+
FileUtils.mkdir_p(File.join(temp_dir, "lib"))
|
62
|
+
File.write(File.join(temp_dir, "lib/test_gem.rb"), "puts 'Hello from test_gem'")
|
63
|
+
|
64
|
+
# Mock Git operations
|
65
|
+
allow(Git).to receive(:open).and_return(double(status: double(untracked: {}, changed: {})))
|
66
|
+
end
|
67
|
+
|
68
|
+
after do
|
69
|
+
FileUtils.remove_entry(temp_dir)
|
70
|
+
end
|
71
|
+
|
72
|
+
it "wraps a gem" do
|
73
|
+
expect { cli.wrap(gemspec_file) }.to output(/The gem has been wrapped into/).to_stdout
|
74
|
+
output_file = File.join(Dir.pwd, "test_gem_wrapped.txt")
|
75
|
+
expect(File.exist?(output_file)).to be true
|
76
|
+
content = File.read(output_file)
|
77
|
+
expect(content).to include("# Wrapped Gem: test_gem")
|
78
|
+
expect(content).to include("## Gemspec: test_gem.gemspec")
|
79
|
+
expect(content).to include("--- START FILE: lib/test_gem.rb ---")
|
80
|
+
expect(content).to include("puts 'Hello from test_gem'")
|
81
|
+
expect(content).to include("--- END FILE: lib/test_gem.rb ---")
|
82
|
+
end
|
83
|
+
|
84
|
+
it "handles non-existent gemspec" do
|
85
|
+
expect do
|
86
|
+
cli.wrap("non_existent.gemspec")
|
87
|
+
end.to output(/Error: The specified gemspec file/).to_stdout.and raise_error(SystemExit)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# spec/poepod/file_processor_spec.rb
|
4
|
+
require "spec_helper"
|
5
|
+
require "poepod/file_processor"
|
6
|
+
require "tempfile"
|
7
|
+
|
8
|
+
RSpec.describe Poepod::FileProcessor do
|
9
|
+
let(:temp_dir) { Dir.mktmpdir }
|
10
|
+
let(:output_file) { Tempfile.new("output.txt") }
|
11
|
+
let(:text_file1) { File.join(temp_dir, "file1.txt") }
|
12
|
+
let(:text_file2) { File.join(temp_dir, "file2.txt") }
|
13
|
+
let(:binary_file) { File.join(temp_dir, "binary_file.bin") }
|
14
|
+
|
15
|
+
before do
|
16
|
+
File.write(text_file1, "Content of file1.\n")
|
17
|
+
File.write(text_file2, "Content of file2.\n")
|
18
|
+
File.write(binary_file, [0xFF, 0xD8, 0xFF, 0xE0].pack("C*"))
|
19
|
+
end
|
20
|
+
|
21
|
+
after do
|
22
|
+
FileUtils.remove_entry(temp_dir)
|
23
|
+
output_file.unlink
|
24
|
+
end
|
25
|
+
|
26
|
+
let(:processor) { described_class.new([text_file1, text_file2], output_file.path) }
|
27
|
+
|
28
|
+
describe "#process" do
|
29
|
+
it "processes text files and writes them to the output file" do
|
30
|
+
total_files, copied_files = processor.process
|
31
|
+
expect(total_files).to eq(2)
|
32
|
+
expect(copied_files).to eq(2)
|
33
|
+
|
34
|
+
output_content = File.read(output_file.path, encoding: "utf-8")
|
35
|
+
expected_content = <<~TEXT
|
36
|
+
--- START FILE: #{text_file1} ---
|
37
|
+
Content of file1.
|
38
|
+
--- END FILE: #{text_file1} ---
|
39
|
+
--- START FILE: #{text_file2} ---
|
40
|
+
Content of file2.
|
41
|
+
--- END FILE: #{text_file2} ---
|
42
|
+
TEXT
|
43
|
+
expect(output_content).to eq(expected_content)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
describe "#process_file" do
|
48
|
+
it "reads the content of a file" do
|
49
|
+
file_path, content, error = processor.send(:process_file, text_file1)
|
50
|
+
expect(file_path).to eq(text_file1)
|
51
|
+
expect(content).to eq("Content of file1.\n")
|
52
|
+
expect(error).to be_nil
|
53
|
+
end
|
54
|
+
|
55
|
+
it "handles encoding errors gracefully" do
|
56
|
+
allow(File).to receive(:read).and_raise(Encoding::InvalidByteSequenceError)
|
57
|
+
file_path, content, error = processor.send(:process_file, text_file1)
|
58
|
+
expect(file_path).to eq(text_file1)
|
59
|
+
expect(content).to be_nil
|
60
|
+
expect(error).to eq("Failed to decode the file, as it is not saved with UTF-8 encoding.")
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,158 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# spec/poepod/gem_processor_spec.rb
|
4
|
+
require "spec_helper"
|
5
|
+
require "poepod/gem_processor"
|
6
|
+
require "tempfile"
|
7
|
+
|
8
|
+
RSpec.describe Poepod::GemProcessor do
|
9
|
+
let(:temp_dir) { Dir.mktmpdir }
|
10
|
+
let(:gemspec_file) { File.join(temp_dir, "test_gem.gemspec") }
|
11
|
+
|
12
|
+
before do
|
13
|
+
File.write(gemspec_file, <<~GEMSPEC)
|
14
|
+
Gem::Specification.new do |spec|
|
15
|
+
spec.name = "test_gem"
|
16
|
+
spec.version = "0.1.0"
|
17
|
+
spec.authors = ["Test Author"]
|
18
|
+
spec.files = ["lib/test_gem.rb"]
|
19
|
+
spec.test_files = ["spec/test_gem_spec.rb"]
|
20
|
+
end
|
21
|
+
GEMSPEC
|
22
|
+
|
23
|
+
FileUtils.mkdir_p(File.join(temp_dir, "lib"))
|
24
|
+
FileUtils.mkdir_p(File.join(temp_dir, "spec"))
|
25
|
+
File.write(File.join(temp_dir, "lib/test_gem.rb"), "puts 'Hello from test_gem'")
|
26
|
+
File.write(File.join(temp_dir, "spec/test_gem_spec.rb"), "RSpec.describe TestGem do\nend")
|
27
|
+
File.write(File.join(temp_dir, "README.md"), "# Test Gem\n\nThis is a test gem.")
|
28
|
+
File.write(File.join(temp_dir, "README.txt"), "Test Gem\n\nThis is a test gem in plain text.")
|
29
|
+
end
|
30
|
+
|
31
|
+
after do
|
32
|
+
FileUtils.remove_entry(temp_dir)
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "#process" do
|
36
|
+
let(:processor) { described_class.new(gemspec_file) }
|
37
|
+
|
38
|
+
before do
|
39
|
+
# Mock Git operations
|
40
|
+
allow(Git).to receive(:open).and_return(double(status: double(untracked: {}, changed: {})))
|
41
|
+
end
|
42
|
+
|
43
|
+
it "processes the gem files, includes README files, and spec files" do
|
44
|
+
success, output_file = processor.process
|
45
|
+
expect(success).to be true
|
46
|
+
expect(File.exist?(output_file)).to be true
|
47
|
+
|
48
|
+
content = File.read(output_file)
|
49
|
+
expect(content).to include("# Wrapped Gem: test_gem")
|
50
|
+
expect(content).to include("## Gemspec: test_gem.gemspec")
|
51
|
+
expect(content).to include("--- START FILE: lib/test_gem.rb ---")
|
52
|
+
expect(content).to include("puts 'Hello from test_gem'")
|
53
|
+
expect(content).to include("--- END FILE: lib/test_gem.rb ---")
|
54
|
+
expect(content).to include("--- START FILE: spec/test_gem_spec.rb ---")
|
55
|
+
expect(content).to include("RSpec.describe TestGem do")
|
56
|
+
expect(content).to include("--- END FILE: spec/test_gem_spec.rb ---")
|
57
|
+
expect(content).to include("--- START FILE: README.md ---")
|
58
|
+
expect(content).to include("# Test Gem\n\nThis is a test gem.")
|
59
|
+
expect(content).to include("--- END FILE: README.md ---")
|
60
|
+
expect(content).to include("--- START FILE: README.txt ---")
|
61
|
+
expect(content).to include("Test Gem\n\nThis is a test gem in plain text.")
|
62
|
+
expect(content).to include("--- END FILE: README.txt ---")
|
63
|
+
end
|
64
|
+
|
65
|
+
context "with non-existent gemspec" do
|
66
|
+
let(:processor) { described_class.new("non_existent.gemspec") }
|
67
|
+
|
68
|
+
it "returns an error" do
|
69
|
+
success, error_message = processor.process
|
70
|
+
expect(success).to be false
|
71
|
+
expect(error_message).to include("Error: The specified gemspec file")
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context "with unstaged files" do
|
76
|
+
let(:mock_git) { instance_double(Git::Base) }
|
77
|
+
let(:mock_status) { instance_double(Git::Status) }
|
78
|
+
|
79
|
+
before do
|
80
|
+
allow(Git).to receive(:open).and_return(mock_git)
|
81
|
+
allow(mock_git).to receive(:status).and_return(mock_status)
|
82
|
+
allow(mock_status).to receive(:untracked).and_return({ "lib/unstaged_file.rb" => "??" })
|
83
|
+
allow(mock_status).to receive(:changed).and_return({})
|
84
|
+
end
|
85
|
+
|
86
|
+
it "warns about unstaged files" do
|
87
|
+
success, output_file, unstaged_files = processor.process
|
88
|
+
expect(success).to be true
|
89
|
+
expect(unstaged_files).to eq(["lib/unstaged_file.rb"])
|
90
|
+
|
91
|
+
content = File.read(output_file)
|
92
|
+
expect(content).to include("## Warning: Unstaged Files")
|
93
|
+
expect(content).to include("lib/unstaged_file.rb")
|
94
|
+
end
|
95
|
+
|
96
|
+
context "with include_unstaged option" do
|
97
|
+
let(:processor) { described_class.new(gemspec_file, nil, true) }
|
98
|
+
|
99
|
+
it "includes unstaged files" do
|
100
|
+
allow(File).to receive(:file?).and_return(true)
|
101
|
+
|
102
|
+
# Create a hash to store file contents
|
103
|
+
file_contents = {
|
104
|
+
"lib/test_gem.rb" => "puts 'Hello from test_gem'",
|
105
|
+
"spec/test_gem_spec.rb" => "RSpec.describe TestGem do\nend",
|
106
|
+
"README.md" => "# Test Gem\n\nThis is a test gem.",
|
107
|
+
"README.txt" => "Test Gem\n\nThis is a test gem in plain text.",
|
108
|
+
"lib/unstaged_file.rb" => "Unstaged content"
|
109
|
+
}
|
110
|
+
|
111
|
+
# Mock File.read
|
112
|
+
allow(File).to receive(:read) do |path|
|
113
|
+
file_name = File.basename(path)
|
114
|
+
if file_contents.key?(file_name)
|
115
|
+
file_contents[file_name]
|
116
|
+
elsif path.end_with?("_wrapped.txt")
|
117
|
+
# This is the output file, so we'll construct its content here
|
118
|
+
wrapped_content = "# Wrapped Gem: test_gem\n"
|
119
|
+
wrapped_content += "## Gemspec: test_gem.gemspec\n\n"
|
120
|
+
wrapped_content += "## Warning: Unstaged Files\n"
|
121
|
+
wrapped_content += "lib/unstaged_file.rb\n\n"
|
122
|
+
wrapped_content += "## Files:\n\n"
|
123
|
+
file_contents.each do |file, content|
|
124
|
+
wrapped_content += "--- START FILE: #{file} ---\n"
|
125
|
+
wrapped_content += "#{content}\n"
|
126
|
+
wrapped_content += "--- END FILE: #{file} ---\n\n"
|
127
|
+
end
|
128
|
+
wrapped_content
|
129
|
+
else
|
130
|
+
"Default content for #{path}"
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
success, output_file, unstaged_files = processor.process
|
135
|
+
expect(success).to be true
|
136
|
+
expect(unstaged_files).to eq(["lib/unstaged_file.rb"])
|
137
|
+
|
138
|
+
content = File.read(output_file)
|
139
|
+
expect(content).to include("--- START FILE: lib/test_gem.rb ---")
|
140
|
+
expect(content).to include("puts 'Hello from test_gem'")
|
141
|
+
expect(content).to include("--- END FILE: lib/test_gem.rb ---")
|
142
|
+
expect(content).to include("--- START FILE: spec/test_gem_spec.rb ---")
|
143
|
+
expect(content).to include("RSpec.describe TestGem do")
|
144
|
+
expect(content).to include("--- END FILE: spec/test_gem_spec.rb ---")
|
145
|
+
expect(content).to include("--- START FILE: README.md ---")
|
146
|
+
expect(content).to include("# Test Gem\n\nThis is a test gem.")
|
147
|
+
expect(content).to include("--- END FILE: README.md ---")
|
148
|
+
expect(content).to include("--- START FILE: README.txt ---")
|
149
|
+
expect(content).to include("Test Gem\n\nThis is a test gem in plain text.")
|
150
|
+
expect(content).to include("--- END FILE: README.txt ---")
|
151
|
+
expect(content).to include("--- START FILE: lib/unstaged_file.rb ---")
|
152
|
+
expect(content).to include("Unstaged content")
|
153
|
+
expect(content).to include("--- END FILE: lib/unstaged_file.rb ---")
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
data/spec/poepod_spec.rb
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "poepod"
|
4
|
+
require "fileutils"
|
5
|
+
|
6
|
+
RSpec.configure do |config|
|
7
|
+
# Enable flags like --only-failures and --next-failure
|
8
|
+
config.example_status_persistence_file_path = ".rspec_status"
|
9
|
+
|
10
|
+
# Disable RSpec exposing methods globally on `Module` and `main`
|
11
|
+
config.disable_monkey_patching!
|
12
|
+
|
13
|
+
config.expect_with :rspec do |c|
|
14
|
+
c.syntax = :expect
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
Content of file1.
|
@@ -0,0 +1 @@
|
|
1
|
+
Content of file2.
|
metadata
CHANGED
@@ -1,15 +1,43 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: poepod
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ribose Inc.
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-
|
11
|
+
date: 2024-07-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: git
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.11'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.11'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: mime-types
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '3.3'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '3.3'
|
13
41
|
- !ruby/object:Gem::Dependency
|
14
42
|
name: parallel
|
15
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -146,15 +174,24 @@ files:
|
|
146
174
|
- exe/poepod
|
147
175
|
- lib/poepod.rb
|
148
176
|
- lib/poepod/cli.rb
|
177
|
+
- lib/poepod/file_processor.rb
|
178
|
+
- lib/poepod/gem_processor.rb
|
149
179
|
- lib/poepod/processor.rb
|
150
180
|
- lib/poepod/version.rb
|
151
181
|
- poepod.gemspec
|
152
182
|
- sig/poepod.rbs
|
183
|
+
- spec/poepod/cli_spec.rb
|
184
|
+
- spec/poepod/file_processor_spec.rb
|
185
|
+
- spec/poepod/gem_processor_spec.rb
|
186
|
+
- spec/poepod_spec.rb
|
187
|
+
- spec/spec_helper.rb
|
188
|
+
- spec/support/test_files/file1.txt
|
189
|
+
- spec/support/test_files/file2.txt
|
153
190
|
homepage: https://github.com/riboseinc/poepod
|
154
191
|
licenses:
|
155
192
|
- BSD-2-Clause
|
156
193
|
metadata: {}
|
157
|
-
post_install_message:
|
194
|
+
post_install_message:
|
158
195
|
rdoc_options: []
|
159
196
|
require_paths:
|
160
197
|
- lib
|
@@ -169,8 +206,15 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
169
206
|
- !ruby/object:Gem::Version
|
170
207
|
version: '0'
|
171
208
|
requirements: []
|
172
|
-
rubygems_version: 3.
|
173
|
-
signing_key:
|
209
|
+
rubygems_version: 3.3.27
|
210
|
+
signing_key:
|
174
211
|
specification_version: 4
|
175
212
|
summary: Utilities for uploading code to Poe
|
176
|
-
test_files:
|
213
|
+
test_files:
|
214
|
+
- spec/poepod/cli_spec.rb
|
215
|
+
- spec/poepod/file_processor_spec.rb
|
216
|
+
- spec/poepod/gem_processor_spec.rb
|
217
|
+
- spec/poepod_spec.rb
|
218
|
+
- spec/spec_helper.rb
|
219
|
+
- spec/support/test_files/file1.txt
|
220
|
+
- spec/support/test_files/file2.txt
|