ronin-core 0.1.0.beta1
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 +7 -0
- data/.document +5 -0
- data/.github/workflows/ruby.yml +41 -0
- data/.gitignore +12 -0
- data/.rspec +1 -0
- data/.rubocop.yml +160 -0
- data/.ruby-version +1 -0
- data/.yardopts +1 -0
- data/COPYING.txt +165 -0
- data/ChangeLog.md +11 -0
- data/Gemfile +30 -0
- data/README.md +299 -0
- data/Rakefile +34 -0
- data/examples/ruby_shell.rb +11 -0
- data/gemspec.yml +28 -0
- data/lib/ronin/core/class_registry.rb +246 -0
- data/lib/ronin/core/cli/command.rb +87 -0
- data/lib/ronin/core/cli/command_shell/command.rb +110 -0
- data/lib/ronin/core/cli/command_shell.rb +345 -0
- data/lib/ronin/core/cli/generator/options/author.rb +106 -0
- data/lib/ronin/core/cli/generator/options/description.rb +54 -0
- data/lib/ronin/core/cli/generator/options/reference.rb +60 -0
- data/lib/ronin/core/cli/generator/options/summary.rb +54 -0
- data/lib/ronin/core/cli/generator.rb +238 -0
- data/lib/ronin/core/cli/logging.rb +59 -0
- data/lib/ronin/core/cli/options/param.rb +68 -0
- data/lib/ronin/core/cli/options/values/arches.rb +45 -0
- data/lib/ronin/core/cli/options/values/oses.rb +32 -0
- data/lib/ronin/core/cli/printing/arch.rb +71 -0
- data/lib/ronin/core/cli/printing/metadata.rb +113 -0
- data/lib/ronin/core/cli/printing/os.rb +54 -0
- data/lib/ronin/core/cli/printing/params.rb +69 -0
- data/lib/ronin/core/cli/ruby_shell.rb +131 -0
- data/lib/ronin/core/cli/shell.rb +186 -0
- data/lib/ronin/core/git.rb +73 -0
- data/lib/ronin/core/home.rb +86 -0
- data/lib/ronin/core/metadata/authors/author.rb +241 -0
- data/lib/ronin/core/metadata/authors.rb +120 -0
- data/lib/ronin/core/metadata/description.rb +100 -0
- data/lib/ronin/core/metadata/id.rb +88 -0
- data/lib/ronin/core/metadata/references.rb +87 -0
- data/lib/ronin/core/metadata/summary.rb +78 -0
- data/lib/ronin/core/metadata/version.rb +74 -0
- data/lib/ronin/core/params/exceptions.rb +38 -0
- data/lib/ronin/core/params/mixin.rb +317 -0
- data/lib/ronin/core/params/param.rb +137 -0
- data/lib/ronin/core/params/types/boolean.rb +64 -0
- data/lib/ronin/core/params/types/enum.rb +107 -0
- data/lib/ronin/core/params/types/float.rb +68 -0
- data/lib/ronin/core/params/types/integer.rb +100 -0
- data/lib/ronin/core/params/types/numeric.rb +106 -0
- data/lib/ronin/core/params/types/regexp.rb +67 -0
- data/lib/ronin/core/params/types/string.rb +118 -0
- data/lib/ronin/core/params/types/type.rb +54 -0
- data/lib/ronin/core/params/types/uri.rb +72 -0
- data/lib/ronin/core/params/types.rb +62 -0
- data/lib/ronin/core/params.rb +19 -0
- data/lib/ronin/core/version.rb +24 -0
- data/ronin-core.gemspec +59 -0
- data/spec/class_registry_spec.rb +224 -0
- data/spec/cli/command_shell/command_spec.rb +113 -0
- data/spec/cli/command_shell_spec.rb +1114 -0
- data/spec/cli/command_spec.rb +16 -0
- data/spec/cli/fixtures/irb_command +8 -0
- data/spec/cli/fixtures/template/dir/file1.txt +1 -0
- data/spec/cli/fixtures/template/dir/file2.txt +1 -0
- data/spec/cli/fixtures/template/file.erb +1 -0
- data/spec/cli/fixtures/template/file.txt +1 -0
- data/spec/cli/generator/options/author_spec.rb +121 -0
- data/spec/cli/generator/options/description_spec.rb +45 -0
- data/spec/cli/generator/options/reference_spec.rb +53 -0
- data/spec/cli/generator/options/summary_spec.rb +45 -0
- data/spec/cli/generator_spec.rb +244 -0
- data/spec/cli/logging_spec.rb +95 -0
- data/spec/cli/options/param_spec.rb +67 -0
- data/spec/cli/options/values/arches_spec.rb +62 -0
- data/spec/cli/printing/arch_spec.rb +130 -0
- data/spec/cli/printing/metadata_spec.rb +211 -0
- data/spec/cli/printing/os_spec.rb +64 -0
- data/spec/cli/printing/params_spec.rb +63 -0
- data/spec/cli/ruby_shell.rb +99 -0
- data/spec/cli/shell_spec.rb +211 -0
- data/spec/fixtures/example_class_registry/base_class.rb +9 -0
- data/spec/fixtures/example_class_registry/classes/loaded_class.rb +9 -0
- data/spec/fixtures/example_class_registry/classes/name_mismatch.rb +9 -0
- data/spec/fixtures/example_class_registry/classes/no_module.rb +4 -0
- data/spec/fixtures/example_class_registry.rb +8 -0
- data/spec/git_spec.rb +58 -0
- data/spec/home_spec.rb +64 -0
- data/spec/metadata/authors/author_spec.rb +335 -0
- data/spec/metadata/authors_spec.rb +126 -0
- data/spec/metadata/description_spec.rb +74 -0
- data/spec/metadata/id_spec.rb +92 -0
- data/spec/metadata/references_spec.rb +100 -0
- data/spec/metadata/summary_spec.rb +74 -0
- data/spec/metadata/version_spec.rb +72 -0
- data/spec/params/mixin_spec.rb +484 -0
- data/spec/params/param_spec.rb +164 -0
- data/spec/params/types/boolean_spec.rb +56 -0
- data/spec/params/types/enum_spec.rb +94 -0
- data/spec/params/types/float_spec.rb +107 -0
- data/spec/params/types/integer_spec.rb +155 -0
- data/spec/params/types/numeric_spec.rb +138 -0
- data/spec/params/types/regexp_spec.rb +64 -0
- data/spec/params/types/string_spec.rb +174 -0
- data/spec/params/types/type_spec.rb +14 -0
- data/spec/params/types/uri_spec.rb +62 -0
- data/spec/spec_helper.rb +11 -0
- metadata +252 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'ronin/core/cli/command'
|
|
3
|
+
|
|
4
|
+
describe Ronin::Core::CLI::Command do
|
|
5
|
+
it "must inherit from CommandKit::Command" do
|
|
6
|
+
expect(described_class).to be < CommandKit::Command
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it "must include CommandKit::Help::Man" do
|
|
10
|
+
expect(described_class).to include(CommandKit::Help::Man)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
it "must include CommandKit::BugReport" do
|
|
14
|
+
expect(described_class).to include(CommandKit::BugReport)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
test1
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
test2
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
1 + 1 = <%= 1 + 1 -%>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
test
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'ronin/core/cli/generator/options/author'
|
|
3
|
+
require 'ronin/core/cli/command'
|
|
4
|
+
require 'ronin/core/cli/generator'
|
|
5
|
+
|
|
6
|
+
describe Ronin::Core::CLI::Generator::Options::Author do
|
|
7
|
+
module TestAuthorOption
|
|
8
|
+
class TestCommand < Ronin::Core::CLI::Command
|
|
9
|
+
include Ronin::Core::CLI::Generator
|
|
10
|
+
include Ronin::Core::CLI::Generator::Options::Author
|
|
11
|
+
|
|
12
|
+
template_dir 'test'
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
let(:command_class) { TestAuthorOption::TestCommand }
|
|
17
|
+
subject { command_class.new }
|
|
18
|
+
|
|
19
|
+
let(:name) { 'Foo Bar' }
|
|
20
|
+
let(:email) { 'foo.bar@example.com' }
|
|
21
|
+
|
|
22
|
+
describe ".defaultor_name" do
|
|
23
|
+
subject { described_class }
|
|
24
|
+
|
|
25
|
+
context "when `git config user.name` is set" do
|
|
26
|
+
before { allow(Ronin::Core::Git).to receive(:user_name).and_return(name) }
|
|
27
|
+
|
|
28
|
+
it "must use `git config user.name`" do
|
|
29
|
+
expect(subject.default_name).to eq(name)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
context "when `git config user.name` isn't set" do
|
|
34
|
+
before { allow(Ronin::Core::Git).to receive(:user_name).and_return(nil) }
|
|
35
|
+
|
|
36
|
+
it "must fallback to using the USERNAME environment variable" do
|
|
37
|
+
expect(subject.default_name).to eq(ENV['USERNAME'])
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
describe ".default_email" do
|
|
43
|
+
subject { described_class }
|
|
44
|
+
|
|
45
|
+
before { allow(Ronin::Core::Git).to receive(:user_email).and_return(email) }
|
|
46
|
+
|
|
47
|
+
it "must use `git config user.email`" do
|
|
48
|
+
expect(subject.default_email).to eq(email)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
describe ".included" do
|
|
53
|
+
subject { command_class }
|
|
54
|
+
|
|
55
|
+
it "must add a '-a,--author NAME' option" do
|
|
56
|
+
expect(subject.options[:author]).to_not be_nil
|
|
57
|
+
expect(subject.options[:author].short).to eq('-a')
|
|
58
|
+
expect(subject.options[:author].value).to_not be_nil
|
|
59
|
+
expect(subject.options[:author].value.default.call).to eq(described_class.default_name)
|
|
60
|
+
expect(subject.options[:author].value.type).to eq(String)
|
|
61
|
+
expect(subject.options[:author].value.usage).to eq('NAME')
|
|
62
|
+
|
|
63
|
+
if (default_name = described_class.default_name)
|
|
64
|
+
expect(subject.options[:author].desc).to eq("The name of the author (Default: #{default_name})")
|
|
65
|
+
else
|
|
66
|
+
expect(subject.options[:author].desc).to eq("The name of the author")
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
expect(subject.options[:author].block).to_not be_nil
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
it "must add a '-e,--author-email EMAIL' option" do
|
|
73
|
+
expect(subject.options[:author_email]).to_not be_nil
|
|
74
|
+
expect(subject.options[:author_email].short).to eq('-e')
|
|
75
|
+
expect(subject.options[:author_email].value).to_not be_nil
|
|
76
|
+
expect(subject.options[:author_email].value.default.call).to eq(described_class.default_email)
|
|
77
|
+
expect(subject.options[:author_email].value.type).to eq(String)
|
|
78
|
+
expect(subject.options[:author_email].value.usage).to eq('EMAIL')
|
|
79
|
+
|
|
80
|
+
if (default_email = described_class.default_email)
|
|
81
|
+
expect(subject.options[:author_email].desc).to eq("The email address of the author (Default: #{default_email})")
|
|
82
|
+
else
|
|
83
|
+
expect(subject.options[:author_email].desc).to eq("The email address of the author")
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
expect(subject.options[:author_email].block).to_not be_nil
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
describe "#initialize" do
|
|
91
|
+
it "must set #author_name to #{described_class}.default_name" do
|
|
92
|
+
expect(subject.author_name).to eq(described_class.default_name)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
it "must set #author_email to #{described_class}.default_email" do
|
|
96
|
+
expect(subject.author_email).to eq(described_class.default_email)
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
describe "#parse_options" do
|
|
101
|
+
context "when given '--author NAME'" do
|
|
102
|
+
let(:argv) { ['--author', name] }
|
|
103
|
+
|
|
104
|
+
before { subject.parse_options(argv) }
|
|
105
|
+
|
|
106
|
+
it "must set #uathor_name" do
|
|
107
|
+
expect(subject.author_name).to eq(name)
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
context "when given '--author-email NAME'" do
|
|
112
|
+
let(:argv) { ['--author-email', email] }
|
|
113
|
+
|
|
114
|
+
before { subject.parse_options(argv) }
|
|
115
|
+
|
|
116
|
+
it "must set #uathor_email" do
|
|
117
|
+
expect(subject.author_email).to eq(email)
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'ronin/core/cli/generator/options/description'
|
|
3
|
+
require 'ronin/core/cli/command'
|
|
4
|
+
require 'ronin/core/cli/generator'
|
|
5
|
+
|
|
6
|
+
describe Ronin::Core::CLI::Generator::Options::Description do
|
|
7
|
+
module TestDescriptionOption
|
|
8
|
+
class TestCommand < Ronin::Core::CLI::Command
|
|
9
|
+
include Ronin::Core::CLI::Generator
|
|
10
|
+
include Ronin::Core::CLI::Generator::Options::Description
|
|
11
|
+
|
|
12
|
+
template_dir 'test'
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
let(:command_class) { TestDescriptionOption::TestCommand }
|
|
17
|
+
subject { command_class.new }
|
|
18
|
+
|
|
19
|
+
let(:description) { 'Foo bar baz' }
|
|
20
|
+
|
|
21
|
+
describe ".included" do
|
|
22
|
+
subject { command_class }
|
|
23
|
+
|
|
24
|
+
it "must add a '-D,--description TEXT' option" do
|
|
25
|
+
expect(subject.options[:description]).to_not be_nil
|
|
26
|
+
expect(subject.options[:description].short).to eq('-D')
|
|
27
|
+
expect(subject.options[:description].value).to_not be_nil
|
|
28
|
+
expect(subject.options[:description].value.type).to eq(String)
|
|
29
|
+
expect(subject.options[:description].value.usage).to eq('TEXT')
|
|
30
|
+
expect(subject.options[:description].desc).to eq('A longer description')
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
describe "#parse_options" do
|
|
35
|
+
context "when given '--description TEXT'" do
|
|
36
|
+
let(:argv) { ['--description', description] }
|
|
37
|
+
|
|
38
|
+
before { subject.parse_options(argv) }
|
|
39
|
+
|
|
40
|
+
it "must set #description" do
|
|
41
|
+
expect(subject.description).to eq(description)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'ronin/core/cli/generator/options/reference'
|
|
3
|
+
require 'ronin/core/cli/command'
|
|
4
|
+
require 'ronin/core/cli/generator'
|
|
5
|
+
|
|
6
|
+
describe Ronin::Core::CLI::Generator::Options::Reference do
|
|
7
|
+
module TestReferenceOption
|
|
8
|
+
class TestCommand < Ronin::Core::CLI::Command
|
|
9
|
+
include Ronin::Core::CLI::Generator
|
|
10
|
+
include Ronin::Core::CLI::Generator::Options::Reference
|
|
11
|
+
|
|
12
|
+
template_dir 'test'
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
let(:command_class) { TestReferenceOption::TestCommand }
|
|
17
|
+
subject { command_class.new }
|
|
18
|
+
|
|
19
|
+
let(:url1) { 'https://example.com/link1' }
|
|
20
|
+
let(:url2) { 'https://example.com/link2' }
|
|
21
|
+
|
|
22
|
+
describe ".included" do
|
|
23
|
+
subject { command_class }
|
|
24
|
+
|
|
25
|
+
it "must add a '-R,--reference URL' option" do
|
|
26
|
+
expect(subject.options[:reference]).to_not be_nil
|
|
27
|
+
expect(subject.options[:reference].short).to eq('-R')
|
|
28
|
+
expect(subject.options[:reference].value).to_not be_nil
|
|
29
|
+
expect(subject.options[:reference].value.type).to eq(String)
|
|
30
|
+
expect(subject.options[:reference].value.usage).to eq('URL')
|
|
31
|
+
expect(subject.options[:reference].desc).to eq('Adds a reference URL')
|
|
32
|
+
expect(subject.options[:reference].block).to_not be_nil
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
describe "#initialize" do
|
|
37
|
+
it "must initialize #references to an empty Array" do
|
|
38
|
+
expect(subject.references).to eq([])
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
describe "#parse_options" do
|
|
43
|
+
context "when given '--reference URL'" do
|
|
44
|
+
let(:argv) { ['--reference', url1, '--reference', url2] }
|
|
45
|
+
|
|
46
|
+
before { subject.parse_options(argv) }
|
|
47
|
+
|
|
48
|
+
it "must append the URLs to #references" do
|
|
49
|
+
expect(subject.references).to eq([url1, url2])
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'ronin/core/cli/generator/options/summary'
|
|
3
|
+
require 'ronin/core/cli/command'
|
|
4
|
+
require 'ronin/core/cli/generator'
|
|
5
|
+
|
|
6
|
+
describe Ronin::Core::CLI::Generator::Options::Summary do
|
|
7
|
+
module TestSummaryOption
|
|
8
|
+
class TestCommand < Ronin::Core::CLI::Command
|
|
9
|
+
include Ronin::Core::CLI::Generator
|
|
10
|
+
include Ronin::Core::CLI::Generator::Options::Summary
|
|
11
|
+
|
|
12
|
+
template_dir 'test'
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
let(:command_class) { TestSummaryOption::TestCommand }
|
|
17
|
+
subject { command_class.new }
|
|
18
|
+
|
|
19
|
+
let(:summary) { 'Foo bar baz' }
|
|
20
|
+
|
|
21
|
+
describe ".included" do
|
|
22
|
+
subject { command_class }
|
|
23
|
+
|
|
24
|
+
it "must add a '-S,--summary TEXT' option" do
|
|
25
|
+
expect(subject.options[:summary]).to_not be_nil
|
|
26
|
+
expect(subject.options[:summary].short).to eq('-S')
|
|
27
|
+
expect(subject.options[:summary].value).to_not be_nil
|
|
28
|
+
expect(subject.options[:summary].value.type).to eq(String)
|
|
29
|
+
expect(subject.options[:summary].value.usage).to eq('TEXT')
|
|
30
|
+
expect(subject.options[:summary].desc).to eq('One sentence summary')
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
describe "#parse_options" do
|
|
35
|
+
context "when given '--summary TEXT'" do
|
|
36
|
+
let(:argv) { ['--summary', summary] }
|
|
37
|
+
|
|
38
|
+
before { subject.parse_options(argv) }
|
|
39
|
+
|
|
40
|
+
it "must set #summary" do
|
|
41
|
+
expect(subject.summary).to eq(summary)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'ronin/core/cli/generator'
|
|
3
|
+
|
|
4
|
+
describe Ronin::Core::CLI::Generator do
|
|
5
|
+
module TestGenerator
|
|
6
|
+
class WithoutTemplateDir < Ronin::Core::CLI::Command
|
|
7
|
+
include Ronin::Core::CLI::Generator
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
class WithTemplateDir < Ronin::Core::CLI::Command
|
|
11
|
+
|
|
12
|
+
include Ronin::Core::CLI::Generator
|
|
13
|
+
|
|
14
|
+
template_dir File.join(__dir__,'fixtures','template')
|
|
15
|
+
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
class InheritedTemplateDir < WithTemplateDir
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
let(:command_class) { TestGenerator::WithTemplateDir }
|
|
23
|
+
subject { command_class.new }
|
|
24
|
+
|
|
25
|
+
describe ".template_dir" do
|
|
26
|
+
context "when called without arguments" do
|
|
27
|
+
context "and the .template_dir has been perviously defined" do
|
|
28
|
+
let(:command_class) { TestGenerator::WithTemplateDir }
|
|
29
|
+
|
|
30
|
+
it "must set the previously set template_dir" do
|
|
31
|
+
expect(command_class.template_dir).to eq(File.join(__dir__,'fixtures','template'))
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
context "but the .template_dir has been defined in the superclass" do
|
|
36
|
+
let(:command_superclass) { TestGenerator::WithTemplateDir }
|
|
37
|
+
let(:command_class) { TestGenerator::InheritedTemplateDir }
|
|
38
|
+
|
|
39
|
+
it "must return the template_dir set in the superclass" do
|
|
40
|
+
expect(command_class.template_dir).to eq(command_superclass.template_dir)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
context "but the template_dir has not been defined" do
|
|
45
|
+
let(:command_class) { TestGenerator::WithoutTemplateDir }
|
|
46
|
+
|
|
47
|
+
it "must return nil" do
|
|
48
|
+
expect(command_class.template_dir).to be(nil)
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
context "when called with a String" do
|
|
54
|
+
let(:command_class) { TestGenerator::WithTemplateDir }
|
|
55
|
+
|
|
56
|
+
it "must set the template_dir" do
|
|
57
|
+
expect(command_class.template_dir).to eq(File.join(__dir__,'fixtures','template'))
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
describe "#initialize" do
|
|
63
|
+
context "when the template_dir has been previously defined" do
|
|
64
|
+
it "must set #template_dir to the class'es .template_dir" do
|
|
65
|
+
expect(subject.template_dir).to eq(command_class.template_dir)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
context "when the template_dir has not been previously defined" do
|
|
70
|
+
let(:command_class) { TestGenerator::WithoutTemplateDir }
|
|
71
|
+
|
|
72
|
+
it do
|
|
73
|
+
expect {
|
|
74
|
+
command_class.new
|
|
75
|
+
}.to raise_error(NotImplementedError,"#{command_class} did not define template_dir")
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
describe "#print_action" do
|
|
81
|
+
let(:stdout) { StringIO.new }
|
|
82
|
+
|
|
83
|
+
subject { command_class.new(stdout: stdout) }
|
|
84
|
+
|
|
85
|
+
context "when two arguments are given" do
|
|
86
|
+
let(:command) { 'touch' }
|
|
87
|
+
let(:dest) { 'path/to/file' }
|
|
88
|
+
|
|
89
|
+
context "and STDOUT is a TTY" do
|
|
90
|
+
let(:ansi) { CommandKit::Colors::ANSI }
|
|
91
|
+
|
|
92
|
+
before do
|
|
93
|
+
allow(stdout).to receive(:tty?).and_return(true)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
it "must output the command and dest highlighted in bold green" do
|
|
97
|
+
expect(stdout).to receive(:puts).with("\t#{ansi.bold(ansi.green(command))}\t#{ansi.green(dest)}")
|
|
98
|
+
|
|
99
|
+
subject.print_action(command,dest)
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
context "but STDOUT is not a TTY" do
|
|
104
|
+
it "must output the command and dest path separated by tabs" do
|
|
105
|
+
expect(stdout).to receive(:puts).with("\t#{command}\t#{dest}")
|
|
106
|
+
|
|
107
|
+
subject.print_action(command,dest)
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
context "when three arguments are given" do
|
|
113
|
+
let(:command) { 'cp -r' }
|
|
114
|
+
let(:source) { 'dir' }
|
|
115
|
+
let(:dest) { 'path/to/file' }
|
|
116
|
+
|
|
117
|
+
context "and STDOUT is a TTY" do
|
|
118
|
+
let(:ansi) { CommandKit::Colors::ANSI }
|
|
119
|
+
|
|
120
|
+
before do
|
|
121
|
+
allow(stdout).to receive(:tty?).and_return(true)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
it "must output the command, source, and dest highlighted in bold green" do
|
|
125
|
+
expect(stdout).to receive(:puts).with("\t#{ansi.bold(ansi.green(command))}\t#{ansi.green(source)}\t#{ansi.green(dest)}")
|
|
126
|
+
|
|
127
|
+
subject.print_action(command,source,dest)
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
context "but STDOUT is not a TTY" do
|
|
132
|
+
it "must output the command, source, and dest path separated by tabs" do
|
|
133
|
+
expect(stdout).to receive(:puts).with("\t#{command}\t#{source}\t#{dest}")
|
|
134
|
+
|
|
135
|
+
subject.print_action(command,source,dest)
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
describe "#mkdir" do
|
|
142
|
+
let(:dest) { 'path/to/new_dir' }
|
|
143
|
+
|
|
144
|
+
it "must call #print_action and call FileUtils.mkdir_p" do
|
|
145
|
+
expect(subject).to receive(:print_action).with('mkdir',dest)
|
|
146
|
+
expect(FileUtils).to receive(:mkdir_p).with(dest)
|
|
147
|
+
|
|
148
|
+
subject.mkdir(dest)
|
|
149
|
+
end
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
describe "#touch" do
|
|
153
|
+
let(:dest) { 'path/to/new_file' }
|
|
154
|
+
|
|
155
|
+
it "must call #print_action and call FileUtils.touch" do
|
|
156
|
+
expect(subject).to receive(:print_action).with('touch',dest)
|
|
157
|
+
expect(FileUtils).to receive(:touch).with(dest)
|
|
158
|
+
|
|
159
|
+
subject.touch(dest)
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
describe "#chmod" do
|
|
164
|
+
let(:dest) { 'path/to/new_file' }
|
|
165
|
+
let(:mode) { "+x" }
|
|
166
|
+
|
|
167
|
+
it "must call #print_action and call FileUtils.chmod" do
|
|
168
|
+
expect(subject).to receive(:print_action).with("chmod",dest)
|
|
169
|
+
expect(FileUtils).to receive(:chmod).with(mode,dest)
|
|
170
|
+
|
|
171
|
+
subject.chmod(mode,dest)
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
describe "#cp" do
|
|
176
|
+
let(:source) { 'file.txt' }
|
|
177
|
+
let(:dest) { 'path/to/root' }
|
|
178
|
+
|
|
179
|
+
it "must call #print_action and call FileUtils.cp" do
|
|
180
|
+
expect(subject).to receive(:print_action).with('cp',source,dest)
|
|
181
|
+
expect(FileUtils).to receive(:cp).with(
|
|
182
|
+
File.join(subject.template_dir,source), dest
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
subject.cp(source,dest)
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
describe "#cp_r" do
|
|
190
|
+
let(:source) { 'dir' }
|
|
191
|
+
let(:dest) { 'path/to/root' }
|
|
192
|
+
|
|
193
|
+
it "must call #print_action and call FileUtils.cp_r" do
|
|
194
|
+
expect(subject).to receive(:print_action).with('cp -r',source,dest)
|
|
195
|
+
expect(FileUtils).to receive(:cp_r).with(
|
|
196
|
+
File.join(subject.template_dir,source), dest
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
subject.cp_r(source,dest)
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
describe "#erb" do
|
|
204
|
+
let(:source) { 'file.erb' }
|
|
205
|
+
let(:dest) { 'path/to/new_file.txt' }
|
|
206
|
+
|
|
207
|
+
it "must call #print_action, render the ERB, and call File.write" do
|
|
208
|
+
expect(subject).to receive(:print_action).with('erb',source,dest)
|
|
209
|
+
expect(File).to receive(:write).with(
|
|
210
|
+
dest, "1 + 1 = 2"
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
subject.erb(source,dest)
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
context "when no destination path is given" do
|
|
217
|
+
it "must not call #print_action, but return the rendered result" do
|
|
218
|
+
expect(subject).to_not receive(:print_action).with('erb',source,dest)
|
|
219
|
+
expect(File).to_not receive(:write).with(
|
|
220
|
+
dest, "1 + 1 = 2"
|
|
221
|
+
)
|
|
222
|
+
|
|
223
|
+
expect(subject.erb(source)).to eq("1 + 1 = 2")
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
describe "#sh" do
|
|
229
|
+
let(:status) { double(:exit_status) }
|
|
230
|
+
|
|
231
|
+
let(:command) { 'cmd' }
|
|
232
|
+
let(:args) { %w[-a -b foo] }
|
|
233
|
+
|
|
234
|
+
it "must call #print_action and run the command" do
|
|
235
|
+
expect(subject).to receive(:print_action).with(
|
|
236
|
+
'run', [command,*args].join(' ')
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
expect(subject).to receive(:system).with(command,*args).and_return(status)
|
|
240
|
+
|
|
241
|
+
expect(subject.sh(command,*args)).to be(status)
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
end
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
require 'ronin/core/cli/logging'
|
|
3
|
+
require 'ronin/core/cli/command'
|
|
4
|
+
require 'stringio'
|
|
5
|
+
|
|
6
|
+
describe Ronin::Core::CLI::Logging do
|
|
7
|
+
module TestLogging
|
|
8
|
+
class TestCommand < Ronin::Core::CLI::Command
|
|
9
|
+
|
|
10
|
+
include Ronin::Core::CLI::Logging
|
|
11
|
+
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
let(:command_class) { TestLogging::TestCommand }
|
|
16
|
+
let(:stdout) { StringIO.new }
|
|
17
|
+
let(:stderr) { StringIO.new }
|
|
18
|
+
subject { command_class.new(stdout: stdout, stderr: stderr) }
|
|
19
|
+
|
|
20
|
+
let(:message) { "foo bar baz" }
|
|
21
|
+
|
|
22
|
+
let(:bright_green) { CommandKit::Colors::ANSI::BRIGHT_GREEN }
|
|
23
|
+
let(:bright_yellow) { CommandKit::Colors::ANSI::BRIGHT_YELLOW }
|
|
24
|
+
let(:bright_red) { CommandKit::Colors::ANSI::BRIGHT_RED }
|
|
25
|
+
let(:white) { CommandKit::Colors::ANSI::WHITE }
|
|
26
|
+
let(:bold) { CommandKit::Colors::ANSI::BOLD }
|
|
27
|
+
let(:reset_intensity) { CommandKit::Colors::ANSI::RESET_INTENSITY }
|
|
28
|
+
let(:reset_color) { CommandKit::Colors::ANSI::RESET_COLOR }
|
|
29
|
+
|
|
30
|
+
describe "#log_info" do
|
|
31
|
+
context "when stdout is a TTY" do
|
|
32
|
+
before { allow(stdout).to receive(:tty?).and_return(true) }
|
|
33
|
+
|
|
34
|
+
it "must print '>>> message' in bold-green and bold-white to stdout" do
|
|
35
|
+
subject.log_info(message)
|
|
36
|
+
|
|
37
|
+
expect(stdout.string).to eq(
|
|
38
|
+
"#{bold}#{bright_green}>>>#{reset_color}#{reset_intensity} #{bold}#{white}#{message}#{reset_color}#{reset_intensity}#{$/}"
|
|
39
|
+
)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
context "when stdout is not a TTY" do
|
|
44
|
+
it "must print '>>> message' to stdout" do
|
|
45
|
+
subject.log_info(message)
|
|
46
|
+
|
|
47
|
+
expect(stdout.string).to eq(">>> #{message}#{$/}")
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
describe "#log_warn" do
|
|
53
|
+
context "when stdout is a TTY" do
|
|
54
|
+
before { allow(stdout).to receive(:tty?).and_return(true) }
|
|
55
|
+
|
|
56
|
+
it "must print '*** message' in bold-yellow and bold-white to stdout" do
|
|
57
|
+
subject.log_warn(message)
|
|
58
|
+
|
|
59
|
+
expect(stdout.string).to eq(
|
|
60
|
+
"#{bold}#{bright_yellow}***#{reset_color}#{reset_intensity} #{bold}#{white}#{message}#{reset_color}#{reset_intensity}#{$/}"
|
|
61
|
+
)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
context "when stdout is not a TTY" do
|
|
66
|
+
it "must print '*** message' to stdout" do
|
|
67
|
+
subject.log_warn(message)
|
|
68
|
+
|
|
69
|
+
expect(stdout.string).to eq("*** #{message}#{$/}")
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
describe "#log_error" do
|
|
75
|
+
context "when stderr is a TTY" do
|
|
76
|
+
before { allow(stderr).to receive(:tty?).and_return(true) }
|
|
77
|
+
|
|
78
|
+
it "must print '!!! message' in bold-red and bold-white to stderr" do
|
|
79
|
+
subject.log_error(message)
|
|
80
|
+
|
|
81
|
+
expect(stderr.string).to eq(
|
|
82
|
+
"#{bold}#{bright_red}!!!#{reset_color}#{reset_intensity} #{bold}#{white}#{message}#{reset_color}#{reset_intensity}#{$/}"
|
|
83
|
+
)
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
context "when stdout is not a TTY" do
|
|
88
|
+
it "must print '!!! message' to stderr" do
|
|
89
|
+
subject.log_error(message)
|
|
90
|
+
|
|
91
|
+
expect(stderr.string).to eq("!!! #{message}#{$/}")
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|