hexx-cli 0.0.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 +7 -0
- data/.coveralls.yml +2 -0
- data/.gitignore +9 -0
- data/.metrics +5 -0
- data/.rspec +2 -0
- data/.rubocop.yml +2 -0
- data/.travis.yml +9 -0
- data/.yardopts +2 -0
- data/Gemfile +7 -0
- data/Guardfile +15 -0
- data/LICENSE +21 -0
- data/README.md +144 -0
- data/Rakefile +17 -0
- data/hexx-cli.gemspec +28 -0
- data/lib/hexx/cli/base/file.rb +87 -0
- data/lib/hexx/cli/base/folder.rb +72 -0
- data/lib/hexx/cli/base.rb +77 -0
- data/lib/hexx/cli/name.rb +152 -0
- data/lib/hexx/cli/version.rb +13 -0
- data/lib/hexx/cli.rb +13 -0
- data/lib/hexx-cli.rb +9 -0
- data/spec/fixtures/root/_.beta +1 -0
- data/spec/fixtures/root/__omega +0 -0
- data/spec/fixtures/root/delta.erb.erb +0 -0
- data/spec/fixtures/root/gamma.rb.erb +1 -0
- data/spec/fixtures/root/subfolder/alfa.yml +0 -0
- data/spec/spec_helper.rb +10 -0
- data/spec/tests/base_spec.rb +126 -0
- data/spec/tests/name_spec.rb +113 -0
- metadata +119 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 992bc17d56268132a6c94a6660bf1f2e7c3336a7
|
4
|
+
data.tar.gz: a0053e74af65bcbd321c145a02733567afc3753b
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 54ded2ec1c055afb1d4dc41a56206d490703a166f25bc5f8e2ab07cdcc927a2ec9524889622810fa40a5a69cb7ceda4b1d4ea3f996b22cbac1b8db8379213e17
|
7
|
+
data.tar.gz: c467529a9e719c1428cf4acfe649ed6ec258f1b950c8feb9979aa9685e0e9f1528336ec17ac922ca7f9f959e5435336f54b04908964ee1d51bde74d9f9c9ff96
|
data/.coveralls.yml
ADDED
data/.gitignore
ADDED
data/.metrics
ADDED
data/.rspec
ADDED
data/.rubocop.yml
ADDED
data/.travis.yml
ADDED
data/.yardopts
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
guard :rspec, cmd: "bundle exec rspec" do
|
4
|
+
|
5
|
+
watch("spec/tests/**/*_spec.rb")
|
6
|
+
|
7
|
+
watch(%r{^lib/hexx/(\w+)\.rb$}) do |m|
|
8
|
+
"spec/tests/#{ m[1] }_spec.rb"
|
9
|
+
end
|
10
|
+
|
11
|
+
watch("lib/hexx-cli.rb") { "spec" }
|
12
|
+
watch("spec/fixtures/**/*") { "spec" }
|
13
|
+
watch("spec/spec_helper.rb") { "spec" }
|
14
|
+
|
15
|
+
end # guard :rspec
|
data/LICENSE
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
The MIT License
|
2
|
+
|
3
|
+
Copyright (c) 2015 Andrew Kozin, andrew.kozin@gmail.com
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in
|
13
|
+
all copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
Hexx::CLI
|
2
|
+
=========
|
3
|
+
|
4
|
+
[][gem]
|
5
|
+
[][travis]
|
6
|
+
[][gemnasium]
|
7
|
+
[][codeclimate]
|
8
|
+
[][coveralls]
|
9
|
+
|
10
|
+
[codeclimate]: https://codeclimate.com/github/nepalez/hexx
|
11
|
+
[coveralls]: https://coveralls.io/r/nepalez/hexx
|
12
|
+
[gem]: https://rubygems.org/gems/hexx
|
13
|
+
[gemnasium]: https://gemnasium.com/nepalez/hexx
|
14
|
+
[travis]: https://travis-ci.org/nepalez/hexx
|
15
|
+
|
16
|
+
The module contains:
|
17
|
+
|
18
|
+
* `Hexx::CLI::Base` - the [Thor::Group]-based generator, extended by additional helper methods
|
19
|
+
* `Hexx::CLI::Name` - the parser for the generator argument or option.
|
20
|
+
|
21
|
+
[Thor::Group]: https://github.com/erikhuda/thor
|
22
|
+
|
23
|
+
Installation
|
24
|
+
------------
|
25
|
+
|
26
|
+
Add this line to your application's Gemfile:
|
27
|
+
|
28
|
+
```ruby
|
29
|
+
# Gemfile
|
30
|
+
group :development do
|
31
|
+
gem "hexx-cli", require: false
|
32
|
+
end
|
33
|
+
```
|
34
|
+
|
35
|
+
Then execute:
|
36
|
+
|
37
|
+
```
|
38
|
+
bundle
|
39
|
+
```
|
40
|
+
|
41
|
+
Or add it manually:
|
42
|
+
|
43
|
+
```
|
44
|
+
gem install hexx-cli
|
45
|
+
```
|
46
|
+
|
47
|
+
Usage
|
48
|
+
-----
|
49
|
+
|
50
|
+
## Hexx::CLI::Base
|
51
|
+
|
52
|
+
Create custom generator class, inherited from the `Hexx::CLI::Base`:
|
53
|
+
|
54
|
+
```ruby
|
55
|
+
class CLI < Hexx::CLI::Base
|
56
|
+
end
|
57
|
+
```
|
58
|
+
|
59
|
+
The generator includes `Thor::Actions` as well as private helper methods:
|
60
|
+
|
61
|
+
* source_path
|
62
|
+
* copy_folder
|
63
|
+
* from_template
|
64
|
+
|
65
|
+
### #source_path
|
66
|
+
|
67
|
+
The method returns the source path setting for the class.
|
68
|
+
|
69
|
+
### #copy_folder
|
70
|
+
|
71
|
+
The method recursively copies files from the source folder to the desinaton.
|
72
|
+
|
73
|
+
```ruby
|
74
|
+
copy_folder "source", "target", skip: true
|
75
|
+
```
|
76
|
+
|
77
|
+
Its behaviour differs from the Thor::Actions `directory` in two aspects:
|
78
|
+
|
79
|
+
* The leading underscore is authomatically removed from the filename. This makes it possible to copy dotfiles:
|
80
|
+
|
81
|
+
```
|
82
|
+
source/_.coveralls.yml --> target/.coveralls.yml
|
83
|
+
```
|
84
|
+
|
85
|
+
* If the source file has `.erb` extension, it is treated as the template. Such files are preprocessed by the ruby `ERB` parser and copied to the destination without `.erb` extension:
|
86
|
+
|
87
|
+
```
|
88
|
+
source/spec_helper.rb.erb --> target/spec_helper.rb
|
89
|
+
```
|
90
|
+
|
91
|
+
### #from_template
|
92
|
+
|
93
|
+
The method returns the content of `ERB`-preprocessed template.
|
94
|
+
|
95
|
+
```ruby
|
96
|
+
from_template "template.erb"
|
97
|
+
```
|
98
|
+
|
99
|
+
It can be used to append, prepend or inject the content from template to existing files:
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
append_to_file "filename", from_template("template.erb")
|
103
|
+
```
|
104
|
+
|
105
|
+
## Hexx::CLI::Name
|
106
|
+
|
107
|
+
The parser takes the string and decorates it with methods for naming conventions:
|
108
|
+
|
109
|
+
```ruby
|
110
|
+
name = Hexx::CLI::Name "mammals/carnivores-cats::wildcats.purr"
|
111
|
+
|
112
|
+
name.item
|
113
|
+
# => "wildcat"
|
114
|
+
name.items
|
115
|
+
# => "wildcats"
|
116
|
+
name.file
|
117
|
+
# => "mammals-carnivores-cats-wildcats.purr"
|
118
|
+
name.path
|
119
|
+
# => "mammals/carnivores/cats/wildcats.purr"
|
120
|
+
name.type
|
121
|
+
# => "Mammals::Carnivores::Cats::Wildcats.purr"
|
122
|
+
name.const
|
123
|
+
# => "Wildcats.purr"
|
124
|
+
name.namespaces
|
125
|
+
# => %w(Mammals Carnivores Cats)
|
126
|
+
```
|
127
|
+
|
128
|
+
Compatibility
|
129
|
+
-------------
|
130
|
+
|
131
|
+
Tested under rubies, compatible with MRI 2.0+:
|
132
|
+
|
133
|
+
* MRI 2.0+
|
134
|
+
* Rubinius 2+ (2.0 mode only)
|
135
|
+
* JRuby-head (2.0 mode only)
|
136
|
+
|
137
|
+
Uses [RSpec] 3.0+ and [hexx-rspec] settings for the test environment.
|
138
|
+
|
139
|
+
[RSpec]: http://rspec.info/
|
140
|
+
|
141
|
+
License
|
142
|
+
-------
|
143
|
+
|
144
|
+
See the [MIT LICENSE](LICENSE).
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
begin
|
3
|
+
require "bundler/setup"
|
4
|
+
rescue LoadError
|
5
|
+
puts "You must `gem install bundler` and `bundle install` to run rake tasks"
|
6
|
+
exit
|
7
|
+
end
|
8
|
+
|
9
|
+
# Loads bundler tasks
|
10
|
+
Bundler::GemHelper.install_tasks
|
11
|
+
|
12
|
+
# Loads the Hexx::Suit and its tasks
|
13
|
+
require "hexx-suit"
|
14
|
+
Hexx::Suit.install_tasks
|
15
|
+
|
16
|
+
# Sets the Hexx::Suit :test task to default
|
17
|
+
task default: :test
|
data/hexx-cli.gemspec
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
require "hexx/cli/version"
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
|
6
|
+
gem.name = "hexx-cli"
|
7
|
+
gem.version = Hexx::CLI::VERSION.dup
|
8
|
+
gem.author = "Andrew Kozin"
|
9
|
+
gem.email = "andrew.kozin@gmail.com"
|
10
|
+
gem.homepage = "https://github.com/nepalez/hexx-cli"
|
11
|
+
gem.description = "Base generator."
|
12
|
+
gem.summary = "Extends the Thor::Group generator with additional helpers."
|
13
|
+
gem.license = "MIT"
|
14
|
+
gem.platform = Gem::Platform::RUBY
|
15
|
+
|
16
|
+
gem.require_paths = ["lib"]
|
17
|
+
gem.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
|
18
|
+
gem.test_files = Dir["spec/**/*.rb"]
|
19
|
+
gem.extra_rdoc_files = Dir["README.md", "LICENSE"]
|
20
|
+
|
21
|
+
gem.required_ruby_version = ">= 2.0"
|
22
|
+
|
23
|
+
gem.add_runtime_dependency "extlib", "~> 0.9"
|
24
|
+
gem.add_runtime_dependency "thor", "~> 0.19"
|
25
|
+
|
26
|
+
gem.add_development_dependency "hexx-rspec", "~> 0.2"
|
27
|
+
|
28
|
+
end # Gem::Specification
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "pathname"
|
3
|
+
|
4
|
+
module Hexx
|
5
|
+
|
6
|
+
module CLI
|
7
|
+
|
8
|
+
# Utilities to copy files and folders in a scaffolder context
|
9
|
+
class Base < Thor::Group
|
10
|
+
|
11
|
+
# Copies a file from a source path to the target folder
|
12
|
+
#
|
13
|
+
# * Files, that have '.erb' extension, are pre-processed as erb templates.
|
14
|
+
# * The starting "_" symbol is removed from a file name.
|
15
|
+
#
|
16
|
+
# @api private
|
17
|
+
class File
|
18
|
+
|
19
|
+
# @!scope class
|
20
|
+
# @!method new(scaffolder, source, target, options = {})
|
21
|
+
# Constructs the processor for given scaffolder, source and target paths
|
22
|
+
#
|
23
|
+
# @param [Thor::Actions] scaffolder
|
24
|
+
# the decorated scaffolder
|
25
|
+
# @param [Pathname] source
|
26
|
+
# the source folder path to take file from
|
27
|
+
# @param [Pathname] target
|
28
|
+
# the target folder path to copy file to
|
29
|
+
# @param [Hash] options
|
30
|
+
# the list of options to copy file
|
31
|
+
#
|
32
|
+
# @return [Hexx::Processors::File]
|
33
|
+
def initialize(scaffolder, source, target, options = {})
|
34
|
+
@__scaffolder__ = scaffolder
|
35
|
+
@source = source
|
36
|
+
@target = target
|
37
|
+
@options = options
|
38
|
+
end
|
39
|
+
|
40
|
+
# Makes a copy of given source file
|
41
|
+
#
|
42
|
+
# @param [Pathname] source_file
|
43
|
+
#
|
44
|
+
# @return [self] itself
|
45
|
+
def copy(source_file)
|
46
|
+
@source_file = source_file
|
47
|
+
__scaffolder__.send(copy_method, source_path, target_path, options)
|
48
|
+
|
49
|
+
self
|
50
|
+
end
|
51
|
+
|
52
|
+
private
|
53
|
+
|
54
|
+
attr_reader :__scaffolder__, :source, :target, :options, :source_file
|
55
|
+
|
56
|
+
def source_root
|
57
|
+
@source_root ||= Pathname.new __scaffolder__.send(:source_root)
|
58
|
+
end
|
59
|
+
|
60
|
+
def copy_method
|
61
|
+
(source_file.extname == ".erb") ? :template : :copy_file
|
62
|
+
end
|
63
|
+
|
64
|
+
def source_path
|
65
|
+
source_file.relative_path_from(source_root).to_s
|
66
|
+
end
|
67
|
+
|
68
|
+
def target_path
|
69
|
+
(target_dirname + target_filename).to_s
|
70
|
+
end
|
71
|
+
|
72
|
+
def target_dirname
|
73
|
+
target + source_file.relative_path_from(source).dirname
|
74
|
+
end
|
75
|
+
|
76
|
+
def target_filename
|
77
|
+
basename = source_file.basename(".erb").to_s
|
78
|
+
basename[0] == "_" ? basename[1..-1].to_s : basename
|
79
|
+
end
|
80
|
+
|
81
|
+
end # class File
|
82
|
+
|
83
|
+
end # class Base
|
84
|
+
|
85
|
+
end # module CLI
|
86
|
+
|
87
|
+
end # module Hexx
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Hexx
|
2
|
+
|
3
|
+
module CLI
|
4
|
+
|
5
|
+
class Base < Thor::Group
|
6
|
+
|
7
|
+
# Copies all files from a source folder to the target one
|
8
|
+
#
|
9
|
+
# * Files, that have '.erb' extension, are pre-processed as erb templates.
|
10
|
+
# * The starting "_" symbol is removed from a file name.
|
11
|
+
#
|
12
|
+
# @api private
|
13
|
+
class Folder
|
14
|
+
|
15
|
+
# @!scope class
|
16
|
+
# @!method new(scaffolder)
|
17
|
+
# Constructs the processor for given scaffolder
|
18
|
+
#
|
19
|
+
# @param [Thor::Actions] scaffolder
|
20
|
+
#
|
21
|
+
# @return [Hexx::Processors::Folder]
|
22
|
+
def initialize(scaffolder)
|
23
|
+
@__scaffolder__ = scaffolder
|
24
|
+
end
|
25
|
+
|
26
|
+
# Copies a source folder content to the target folder
|
27
|
+
#
|
28
|
+
# @param [String] source
|
29
|
+
# The source folder path relative to the scaffolder's source_root
|
30
|
+
# @param [String] target
|
31
|
+
# The target folder path relative to the scaffolder's destination_root
|
32
|
+
# @param [Hash] options
|
33
|
+
#
|
34
|
+
# @return [self] itself
|
35
|
+
def copy(source, target, options = {})
|
36
|
+
@source, @target, @options = source, target, options
|
37
|
+
source_files.each { |file| file_processor.copy(file) }
|
38
|
+
|
39
|
+
self
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
attr_reader :__scaffolder__, :source, :target, :options
|
45
|
+
|
46
|
+
def source_files
|
47
|
+
source_paths.map(&Pathname.method(:new)).select(&:file?)
|
48
|
+
end
|
49
|
+
|
50
|
+
def file_processor
|
51
|
+
File.new __scaffolder__, source_folder, target_folder, options
|
52
|
+
end
|
53
|
+
|
54
|
+
def source_paths
|
55
|
+
::Dir[source_folder + "**/*"]
|
56
|
+
end
|
57
|
+
|
58
|
+
def source_folder
|
59
|
+
Pathname.new(__scaffolder__.send :source_root).join(source)
|
60
|
+
end
|
61
|
+
|
62
|
+
def target_folder
|
63
|
+
Pathname.new(__scaffolder__.send :destination_root).join(target)
|
64
|
+
end
|
65
|
+
|
66
|
+
end # class Folder
|
67
|
+
|
68
|
+
end # class Base
|
69
|
+
|
70
|
+
end # module CLI
|
71
|
+
|
72
|
+
end # module Hexx
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "thor"
|
3
|
+
|
4
|
+
module Hexx
|
5
|
+
|
6
|
+
module CLI
|
7
|
+
|
8
|
+
require_relative "base/file"
|
9
|
+
require_relative "base/folder"
|
10
|
+
|
11
|
+
# Base class for scaffolders
|
12
|
+
#
|
13
|
+
# Adds actions to the generator
|
14
|
+
#
|
15
|
+
# @example (see #from_template)
|
16
|
+
# @example (see #copy_folder)
|
17
|
+
class Base < Thor::Group
|
18
|
+
include Thor::Actions
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
# Returns source root defined for the class
|
23
|
+
#
|
24
|
+
# @return [String, Array<String>]
|
25
|
+
def source_root
|
26
|
+
self.class.send :source_root
|
27
|
+
end
|
28
|
+
|
29
|
+
# Returns content of source (relative to source root), preprocessed by ERB
|
30
|
+
#
|
31
|
+
# @example
|
32
|
+
# # source_root/file.erb
|
33
|
+
# <%= 2 * 2 %>
|
34
|
+
#
|
35
|
+
# scaffolder = Hexx::CLI::Base.new
|
36
|
+
# scaffolder.send :from_template, "file.erb"
|
37
|
+
# # => "4"
|
38
|
+
#
|
39
|
+
# @return [#to_s] source
|
40
|
+
#
|
41
|
+
# @api public
|
42
|
+
def from_template(source)
|
43
|
+
path = find_in_source_paths(source)
|
44
|
+
content = ::File.read(path)
|
45
|
+
ERB.new(content, nil, "-").result
|
46
|
+
end
|
47
|
+
|
48
|
+
# Copies files from source folder into the destination one
|
49
|
+
#
|
50
|
+
# Wherein:
|
51
|
+
#
|
52
|
+
# * Files with '.erb' extension are preprocessed by ERB.
|
53
|
+
# They saved under initial names without '.erb' extension.
|
54
|
+
#
|
55
|
+
# * The underscore symbol "_" in the beginning of filename is removed.
|
56
|
+
# You can copy dotfiles by underscoring them.
|
57
|
+
#
|
58
|
+
# @example
|
59
|
+
# scaffolder = Hexx::CLI::Base.new
|
60
|
+
#
|
61
|
+
# scaffolder.copy_folder "root", "spec", skip: true
|
62
|
+
# # root/_.settings --> spec/.settings
|
63
|
+
# # root/spec_helper.rb.erb --> spec/spec_helper.rb
|
64
|
+
# # root/tests/test_spec.rb --> spec/tests/test_spec.rb
|
65
|
+
#
|
66
|
+
# @return [undefined]
|
67
|
+
#
|
68
|
+
# @api public
|
69
|
+
def copy_folder(source, target = source, options = {})
|
70
|
+
Folder.new(self).copy(source, target, options)
|
71
|
+
end
|
72
|
+
|
73
|
+
end # class Base
|
74
|
+
|
75
|
+
end # module CLI
|
76
|
+
|
77
|
+
end # module Hexx
|
@@ -0,0 +1,152 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "extlib"
|
3
|
+
|
4
|
+
module Hexx
|
5
|
+
|
6
|
+
module CLI
|
7
|
+
|
8
|
+
# Decorates a string with conventional names
|
9
|
+
class Name
|
10
|
+
|
11
|
+
# @!scope class
|
12
|
+
# @!method new(string)
|
13
|
+
# Constructs the parser object
|
14
|
+
#
|
15
|
+
# @example
|
16
|
+
# Hexx::CLI::Name.new "MyGem::MyClass.methods.chain"
|
17
|
+
#
|
18
|
+
# @param [#to_s] string
|
19
|
+
# The string to be parsed
|
20
|
+
#
|
21
|
+
# @return [Hexx::CLI::Name]
|
22
|
+
def initialize(string)
|
23
|
+
@list = string.to_s.snake_case.gsub(/\:{2}|-/, "/").split(".")
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns the last part of the singular name
|
27
|
+
#
|
28
|
+
# @example
|
29
|
+
# source = "cats-wildcats/jaguars::PantherTiger.bite"
|
30
|
+
# name = Hexx::CLI::Name.new(source)
|
31
|
+
# name.item
|
32
|
+
# # => "panther_tiger"
|
33
|
+
#
|
34
|
+
# @return [String]
|
35
|
+
def item
|
36
|
+
@item ||= snakes.last.to_s.singular
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns the last part of the plural name
|
40
|
+
#
|
41
|
+
# @example
|
42
|
+
# source = "cats-wildcats/jaguars::PantherTiger.bite"
|
43
|
+
# name = Hexx::CLI::Name.new(source)
|
44
|
+
# name.items
|
45
|
+
# # => "panther_tigers"
|
46
|
+
#
|
47
|
+
# @return [String]
|
48
|
+
def items
|
49
|
+
@items ||= item.plural
|
50
|
+
end
|
51
|
+
|
52
|
+
# Returns the dashes-delimited name
|
53
|
+
#
|
54
|
+
# @example
|
55
|
+
# source = "cats-wildcats/jaguars::PantherTiger.bite"
|
56
|
+
# name = Hexx::CLI::Name.new(source)
|
57
|
+
# name.file
|
58
|
+
# # => "cats-wildcats-jaguars-panther_tiger.bite"
|
59
|
+
#
|
60
|
+
# @return [String]
|
61
|
+
def file
|
62
|
+
@file ||= [snakes.join("-"), method].compact.join(".")
|
63
|
+
end
|
64
|
+
|
65
|
+
# Returns the slash-delimited name
|
66
|
+
#
|
67
|
+
# @example
|
68
|
+
# source = "cats-wildcats/jaguars::PantherTiger.bite"
|
69
|
+
# name = Hexx::CLI::Name.new(source)
|
70
|
+
# name.path
|
71
|
+
# # => "cats/wildcats/jaguars/panther_tiger/bite"
|
72
|
+
#
|
73
|
+
# @return [String]
|
74
|
+
def path
|
75
|
+
@path ||= [snakes.join("/"), method].compact.join(".")
|
76
|
+
end
|
77
|
+
|
78
|
+
# Returns the name as a full constant
|
79
|
+
#
|
80
|
+
# @example
|
81
|
+
# source = "cats-wildcats/jaguars::PantherTiger.bite"
|
82
|
+
# name = Hexx::CLI::Name.new(source)
|
83
|
+
# name.type
|
84
|
+
# # => "Cats::Wildcats::Jaguars::PantherTiger.bite"
|
85
|
+
#
|
86
|
+
# @return [String]
|
87
|
+
def type
|
88
|
+
@type ||= [camels.join("::"), method].compact.join(".")
|
89
|
+
end
|
90
|
+
|
91
|
+
# Returns the name as a last part of constant
|
92
|
+
#
|
93
|
+
# @example
|
94
|
+
# source = "cats-wildcats/jaguars::PantherTiger.bite"
|
95
|
+
# name = Hexx::CLI::Name.new(source)
|
96
|
+
# name.const
|
97
|
+
# # => "PantherTiger.bite"
|
98
|
+
#
|
99
|
+
# @return [String]
|
100
|
+
def const
|
101
|
+
@const ||= [camels.last, method].compact.join(".")
|
102
|
+
end
|
103
|
+
|
104
|
+
# Returns the array of namespaces (module names) for the constant
|
105
|
+
#
|
106
|
+
# @example
|
107
|
+
# source = "cats-wildcats/jaguars::PantherTiger.bite"
|
108
|
+
# name = Hexx::CLI::Name.new(source)
|
109
|
+
# name.namespaces
|
110
|
+
# # => ["Cats", "Wildcats", "Jaguars"]
|
111
|
+
#
|
112
|
+
# @return [Array<String>]
|
113
|
+
def namespaces
|
114
|
+
@namespaces ||= camels[0..-2]
|
115
|
+
end
|
116
|
+
|
117
|
+
private
|
118
|
+
|
119
|
+
# String of chained methods
|
120
|
+
#
|
121
|
+
# @return [String]
|
122
|
+
# @return [nil]
|
123
|
+
# if source has no methods
|
124
|
+
#
|
125
|
+
# @api private
|
126
|
+
def method
|
127
|
+
@method ||= @list[1..-1] if @list.count > 1
|
128
|
+
end
|
129
|
+
|
130
|
+
# List of snake-cased parts of the constant
|
131
|
+
#
|
132
|
+
# @return [Array<String>]
|
133
|
+
#
|
134
|
+
# @api private
|
135
|
+
def snakes
|
136
|
+
@snakes ||= @list.first.to_s.split("/")
|
137
|
+
end
|
138
|
+
|
139
|
+
# List of camel-cased parts of the constant
|
140
|
+
#
|
141
|
+
# @return [Array<String>]
|
142
|
+
#
|
143
|
+
# @api private
|
144
|
+
def camels
|
145
|
+
@camels ||= snakes.map(&:camel_case)
|
146
|
+
end
|
147
|
+
|
148
|
+
end # class Name
|
149
|
+
|
150
|
+
end # module CLI
|
151
|
+
|
152
|
+
end # module Hexx
|
data/lib/hexx/cli.rb
ADDED
data/lib/hexx-cli.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
<%= 2 * 2 -%>
|
File without changes
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= 2 * 2 -%>
|
File without changes
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,126 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# See settings for :sandbox and :capture tags in `config/initializers` folder
|
4
|
+
describe Hexx::CLI::Base do
|
5
|
+
|
6
|
+
# source path is set to spec/fixtures
|
7
|
+
let(:fixtures) { ::File.expand_path "../../fixtures", __FILE__ }
|
8
|
+
before { allow(described_class).to receive(:source_root).and_return fixtures }
|
9
|
+
|
10
|
+
describe ".new" do
|
11
|
+
|
12
|
+
it "constructs Thor::Group instance" do
|
13
|
+
expect(subject).to be_kind_of Thor::Group
|
14
|
+
end
|
15
|
+
|
16
|
+
it "constructs Thor::Actions instance" do
|
17
|
+
expect(subject).to be_kind_of Thor::Actions
|
18
|
+
end
|
19
|
+
|
20
|
+
end # describe .new
|
21
|
+
|
22
|
+
describe "##source_root" do
|
23
|
+
|
24
|
+
it "returns a source root" do
|
25
|
+
expect(subject.send :source_root)
|
26
|
+
.to eq described_class.send(:source_root)
|
27
|
+
end
|
28
|
+
|
29
|
+
end # describe ##source_root
|
30
|
+
|
31
|
+
describe "#copy_folder", :sandbox, :capture do
|
32
|
+
|
33
|
+
shared_examples "copying files" do
|
34
|
+
|
35
|
+
# target should be described in context
|
36
|
+
|
37
|
+
it "[copy file as is]" do
|
38
|
+
expect("#{ target }/subfolder/alfa.yml").to be_present_in_sandbox
|
39
|
+
end
|
40
|
+
|
41
|
+
end # examples
|
42
|
+
|
43
|
+
shared_examples "removing last .erb only" do
|
44
|
+
|
45
|
+
# target should be described in context
|
46
|
+
|
47
|
+
it "[removes last .erb]" do
|
48
|
+
expect("#{ target }/gamma.rb").to be_present_in_sandbox
|
49
|
+
end
|
50
|
+
|
51
|
+
it "[leaves previous .erb]" do
|
52
|
+
expect("#{ target }/delta.erb").to be_present_in_sandbox
|
53
|
+
end
|
54
|
+
|
55
|
+
end # examples
|
56
|
+
|
57
|
+
shared_examples "removing first underscores only" do
|
58
|
+
|
59
|
+
it "[removes first _]" do
|
60
|
+
expect("#{ target }/.beta").to be_present_in_sandbox
|
61
|
+
end
|
62
|
+
|
63
|
+
it "[leaves later _]" do
|
64
|
+
expect("#{ target }/_omega").to be_present_in_sandbox
|
65
|
+
end
|
66
|
+
|
67
|
+
end # examples
|
68
|
+
|
69
|
+
shared_examples "preprocessing ERB only" do
|
70
|
+
|
71
|
+
# target should be described in context
|
72
|
+
|
73
|
+
it "[preprocesses erb]" do
|
74
|
+
content = read_in_sandbox("#{ target }/gamma.rb")
|
75
|
+
expect(content).not_to include "<%= 2 * 2 -%>"
|
76
|
+
expect(content).to include "4"
|
77
|
+
end
|
78
|
+
|
79
|
+
it "[leaves non-erb]" do
|
80
|
+
content = read_in_sandbox("#{ target }/.beta")
|
81
|
+
expect(content).to include "<%= 2 * 2 -%>"
|
82
|
+
expect(content).not_to include "4"
|
83
|
+
end
|
84
|
+
|
85
|
+
end # examples
|
86
|
+
|
87
|
+
context "when the target isn't set" do
|
88
|
+
|
89
|
+
let(:target) { "root" }
|
90
|
+
|
91
|
+
before { try_in_sandbox { subject.send :copy_folder, "root" } }
|
92
|
+
|
93
|
+
it_behaves_like "copying files"
|
94
|
+
it_behaves_like "removing last .erb only"
|
95
|
+
it_behaves_like "removing first underscores only"
|
96
|
+
it_behaves_like "preprocessing ERB only"
|
97
|
+
|
98
|
+
end # context
|
99
|
+
|
100
|
+
context "with the target is set" do
|
101
|
+
|
102
|
+
let(:target) { "spec" }
|
103
|
+
|
104
|
+
before { try_in_sandbox { subject.send :copy_folder, "root", target } }
|
105
|
+
|
106
|
+
it_behaves_like "copying files"
|
107
|
+
it_behaves_like "removing last .erb only"
|
108
|
+
it_behaves_like "removing first underscores only"
|
109
|
+
it_behaves_like "preprocessing ERB only"
|
110
|
+
|
111
|
+
end # context
|
112
|
+
|
113
|
+
end # describe ##copy_folder
|
114
|
+
|
115
|
+
describe "#from_template", :sandbox, :capture do
|
116
|
+
|
117
|
+
let(:content) { subject.send :from_template, "root/_.beta" }
|
118
|
+
|
119
|
+
it "returns the ERB-preprocessed content of the template" do
|
120
|
+
expect(content).not_to include "<%= 2 * 2 -%>"
|
121
|
+
expect(content).to include "4"
|
122
|
+
end
|
123
|
+
|
124
|
+
end # describe ##from_template
|
125
|
+
|
126
|
+
end # describe Hexx::Generator
|
@@ -0,0 +1,113 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
describe Hexx::CLI::Name do
|
4
|
+
|
5
|
+
describe ".new" do
|
6
|
+
|
7
|
+
it "requires an argument" do
|
8
|
+
expect { described_class.new }.to raise_error
|
9
|
+
expect { described_class.new "" }.not_to raise_error
|
10
|
+
expect { described_class.new "", "" }.to raise_error
|
11
|
+
end
|
12
|
+
|
13
|
+
end # describe .new
|
14
|
+
|
15
|
+
let(:a) { described_class.new nil }
|
16
|
+
let(:b) { described_class.new "cats" }
|
17
|
+
let(:c) { described_class.new "cats.names" }
|
18
|
+
let(:d) { described_class.new "cats-wildcats/jaguars::PantherTiger" }
|
19
|
+
let(:e) { described_class.new "cats-wildcats/jaguars::PantherTigers" }
|
20
|
+
let(:f) { described_class.new "cats-wildcats/jaguars::PantherTiger.a.B.c" }
|
21
|
+
|
22
|
+
describe "#item" do
|
23
|
+
|
24
|
+
it "returns a proper value" do
|
25
|
+
expect(a.item).to eq ""
|
26
|
+
expect(b.item).to eq "cat"
|
27
|
+
expect(c.item).to eq "cat"
|
28
|
+
expect(d.item).to eq "panther_tiger"
|
29
|
+
expect(e.item).to eq "panther_tiger"
|
30
|
+
expect(f.item).to eq "panther_tiger"
|
31
|
+
end
|
32
|
+
|
33
|
+
end # describe #item
|
34
|
+
|
35
|
+
describe "#items" do
|
36
|
+
|
37
|
+
it "returns a proper value" do
|
38
|
+
expect(a.items).to eq ""
|
39
|
+
expect(b.items).to eq "cats"
|
40
|
+
expect(c.items).to eq "cats"
|
41
|
+
expect(d.items).to eq "panther_tigers"
|
42
|
+
expect(e.items).to eq "panther_tigers"
|
43
|
+
expect(f.items).to eq "panther_tigers"
|
44
|
+
end
|
45
|
+
|
46
|
+
end # describe #items
|
47
|
+
|
48
|
+
describe "#file" do
|
49
|
+
|
50
|
+
it "returns a proper value" do
|
51
|
+
expect(a.file).to eq ""
|
52
|
+
expect(b.file).to eq "cats"
|
53
|
+
expect(c.file).to eq "cats.names"
|
54
|
+
expect(d.file).to eq "cats-wildcats-jaguars-panther_tiger"
|
55
|
+
expect(e.file).to eq "cats-wildcats-jaguars-panther_tigers"
|
56
|
+
expect(f.file).to eq "cats-wildcats-jaguars-panther_tiger.a.b.c"
|
57
|
+
end
|
58
|
+
|
59
|
+
end # describe #file
|
60
|
+
|
61
|
+
describe "#path" do
|
62
|
+
|
63
|
+
it "returns a proper value" do
|
64
|
+
expect(a.path).to eq ""
|
65
|
+
expect(b.path).to eq "cats"
|
66
|
+
expect(c.path).to eq "cats.names"
|
67
|
+
expect(d.path).to eq "cats/wildcats/jaguars/panther_tiger"
|
68
|
+
expect(e.path).to eq "cats/wildcats/jaguars/panther_tigers"
|
69
|
+
expect(f.path).to eq "cats/wildcats/jaguars/panther_tiger.a.b.c"
|
70
|
+
end
|
71
|
+
|
72
|
+
end # describe #path
|
73
|
+
|
74
|
+
describe "#type" do
|
75
|
+
|
76
|
+
it "returns a proper value" do
|
77
|
+
expect(a.type).to eq ""
|
78
|
+
expect(b.type).to eq "Cats"
|
79
|
+
expect(c.type).to eq "Cats.names"
|
80
|
+
expect(d.type).to eq "Cats::Wildcats::Jaguars::PantherTiger"
|
81
|
+
expect(e.type).to eq "Cats::Wildcats::Jaguars::PantherTigers"
|
82
|
+
expect(f.type).to eq "Cats::Wildcats::Jaguars::PantherTiger.a.b.c"
|
83
|
+
end
|
84
|
+
|
85
|
+
end # describe #type
|
86
|
+
|
87
|
+
describe "#const" do
|
88
|
+
|
89
|
+
it "returns a proper value" do
|
90
|
+
expect(a.const).to eq ""
|
91
|
+
expect(b.const).to eq "Cats"
|
92
|
+
expect(c.const).to eq "Cats.names"
|
93
|
+
expect(d.const).to eq "PantherTiger"
|
94
|
+
expect(e.const).to eq "PantherTigers"
|
95
|
+
expect(f.const).to eq "PantherTiger.a.b.c"
|
96
|
+
end
|
97
|
+
|
98
|
+
end # describe #const
|
99
|
+
|
100
|
+
describe "#namespaces" do
|
101
|
+
|
102
|
+
it "returns a proper value" do
|
103
|
+
expect(a.namespaces).to eq %w()
|
104
|
+
expect(b.namespaces).to eq %w()
|
105
|
+
expect(c.namespaces).to eq %w()
|
106
|
+
expect(d.namespaces).to eq %w(Cats Wildcats Jaguars)
|
107
|
+
expect(e.namespaces).to eq %w(Cats Wildcats Jaguars)
|
108
|
+
expect(f.namespaces).to eq %w(Cats Wildcats Jaguars)
|
109
|
+
end
|
110
|
+
|
111
|
+
end # describe #namespaces
|
112
|
+
|
113
|
+
end # describe Hexx::Name
|
metadata
ADDED
@@ -0,0 +1,119 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: hexx-cli
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Andrew Kozin
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-03-14 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: extlib
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.9'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.9'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: thor
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0.19'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0.19'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: hexx-rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0.2'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0.2'
|
55
|
+
description: Base generator.
|
56
|
+
email: andrew.kozin@gmail.com
|
57
|
+
executables: []
|
58
|
+
extensions: []
|
59
|
+
extra_rdoc_files:
|
60
|
+
- README.md
|
61
|
+
- LICENSE
|
62
|
+
files:
|
63
|
+
- ".coveralls.yml"
|
64
|
+
- ".gitignore"
|
65
|
+
- ".metrics"
|
66
|
+
- ".rspec"
|
67
|
+
- ".rubocop.yml"
|
68
|
+
- ".travis.yml"
|
69
|
+
- ".yardopts"
|
70
|
+
- Gemfile
|
71
|
+
- Guardfile
|
72
|
+
- LICENSE
|
73
|
+
- README.md
|
74
|
+
- Rakefile
|
75
|
+
- hexx-cli.gemspec
|
76
|
+
- lib/hexx-cli.rb
|
77
|
+
- lib/hexx/cli.rb
|
78
|
+
- lib/hexx/cli/base.rb
|
79
|
+
- lib/hexx/cli/base/file.rb
|
80
|
+
- lib/hexx/cli/base/folder.rb
|
81
|
+
- lib/hexx/cli/name.rb
|
82
|
+
- lib/hexx/cli/version.rb
|
83
|
+
- spec/fixtures/root/_.beta
|
84
|
+
- spec/fixtures/root/__omega
|
85
|
+
- spec/fixtures/root/delta.erb.erb
|
86
|
+
- spec/fixtures/root/gamma.rb.erb
|
87
|
+
- spec/fixtures/root/subfolder/alfa.yml
|
88
|
+
- spec/spec_helper.rb
|
89
|
+
- spec/tests/base_spec.rb
|
90
|
+
- spec/tests/name_spec.rb
|
91
|
+
homepage: https://github.com/nepalez/hexx-cli
|
92
|
+
licenses:
|
93
|
+
- MIT
|
94
|
+
metadata: {}
|
95
|
+
post_install_message:
|
96
|
+
rdoc_options: []
|
97
|
+
require_paths:
|
98
|
+
- lib
|
99
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '2.0'
|
104
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - ">="
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
109
|
+
requirements: []
|
110
|
+
rubyforge_project:
|
111
|
+
rubygems_version: 2.4.6
|
112
|
+
signing_key:
|
113
|
+
specification_version: 4
|
114
|
+
summary: Extends the Thor::Group generator with additional helpers.
|
115
|
+
test_files:
|
116
|
+
- spec/spec_helper.rb
|
117
|
+
- spec/tests/base_spec.rb
|
118
|
+
- spec/tests/name_spec.rb
|
119
|
+
has_rdoc:
|