tacape 0.0.3
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.
- data/.gitignore +3 -0
- data/.rspec +1 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +53 -0
- data/Rakefile +7 -0
- data/Readme.md +23 -0
- data/bin/tacape +5 -0
- data/config/locales/en.yml +11 -0
- data/config/locales/pt-BR.yml +11 -0
- data/config/tacape.yml +1 -0
- data/lib/tacape.rb +62 -0
- data/lib/tacape/belt.rb +30 -0
- data/lib/tacape/cli.rb +89 -0
- data/lib/tacape/oses/fedora.rb +50 -0
- data/lib/tacape/oses/os_exceptions.rb +10 -0
- data/lib/tacape/oses/osx.rb +48 -0
- data/lib/tacape/tools/helpers/json_config.rb +70 -0
- data/lib/tacape/tools/helpers/os_support.rb +23 -0
- data/lib/tacape/version.rb +8 -0
- data/logo.gif +0 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/support/exit_with_code.rb +26 -0
- data/spec/support/have_tag.rb +115 -0
- data/spec/support/helper.rb +18 -0
- data/spec/support/shared.rb +53 -0
- data/spec/tacape.rb +4 -0
- data/tacape.gemspec +33 -0
- data/templates/tools/sample.rb +20 -0
- metadata +242 -0
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color --format documentation
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
tacape (0.0.1)
|
5
|
+
activesupport
|
6
|
+
i18n
|
7
|
+
notifier
|
8
|
+
os
|
9
|
+
thor
|
10
|
+
|
11
|
+
GEM
|
12
|
+
remote: https://rubygems.org/
|
13
|
+
specs:
|
14
|
+
activesupport (3.2.12)
|
15
|
+
i18n (~> 0.6)
|
16
|
+
multi_json (~> 1.0)
|
17
|
+
coderay (1.0.9)
|
18
|
+
diff-lcs (1.2.4)
|
19
|
+
i18n (0.6.4)
|
20
|
+
method_source (0.8.1)
|
21
|
+
multi_json (1.7.4)
|
22
|
+
notifier (0.4.1)
|
23
|
+
os (0.9.6)
|
24
|
+
pry (0.9.12.2)
|
25
|
+
coderay (~> 1.0.5)
|
26
|
+
method_source (~> 0.8)
|
27
|
+
slop (~> 3.4)
|
28
|
+
pry-nav (0.2.3)
|
29
|
+
pry (~> 0.9.10)
|
30
|
+
rake (10.0.4)
|
31
|
+
rspec (2.13.0)
|
32
|
+
rspec-core (~> 2.13.0)
|
33
|
+
rspec-expectations (~> 2.13.0)
|
34
|
+
rspec-mocks (~> 2.13.0)
|
35
|
+
rspec-core (2.13.1)
|
36
|
+
rspec-expectations (2.13.0)
|
37
|
+
diff-lcs (>= 1.1.3, < 2.0)
|
38
|
+
rspec-mocks (2.13.1)
|
39
|
+
slop (3.4.5)
|
40
|
+
test_notifier (1.0.1)
|
41
|
+
notifier
|
42
|
+
thor (0.18.1)
|
43
|
+
|
44
|
+
PLATFORMS
|
45
|
+
ruby
|
46
|
+
|
47
|
+
DEPENDENCIES
|
48
|
+
pry
|
49
|
+
pry-nav
|
50
|
+
rake
|
51
|
+
rspec
|
52
|
+
tacape!
|
53
|
+
test_notifier
|
data/Rakefile
ADDED
data/Readme.md
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
[](https://codeclimate.com/github/lucasmartins/tacape) [](https://travis-ci.org/lucasmartins/tacape) [](https://gemnasium.com/lucasmartins/tacape)
|
2
|
+
|
3
|
+
Tacape
|
4
|
+
======
|
5
|
+
|
6
|
+
This is a work in progrees, I would wait until I have the testing suite implemented to publish this but time is slipping away from me, maybe you can help!
|
7
|
+
|
8
|
+
Just fork [Tacape Tools]((https://github.com/lucasmartins/tacape-tools)), add your tool, and make a pull request.
|
9
|
+
|
10
|
+
You can test your tools locally just throwing them at the `~/.tacape/tools` folder.
|
11
|
+
|
12
|
+
Take a look at the code of the tools already implemented.
|
13
|
+
|
14
|
+
All I did was to get the code of scripts I made for myself and put them togheter in a better organized way, this is not the kind of code you should publish, but I believe this is gonna force me to make it better.
|
15
|
+
|
16
|
+
Have fun!
|
17
|
+
|
18
|
+
This repo is used by [Tacape](https://github.com/lucasmartins/tacape)
|
19
|
+
|
20
|
+
License
|
21
|
+
=======
|
22
|
+
|
23
|
+
Tacape Tools is free software under the [MIT license](http://lucasmartins.mit-license.org).
|
data/bin/tacape
ADDED
@@ -0,0 +1,11 @@
|
|
1
|
+
en:
|
2
|
+
greeting: "This is Tacape, a command-line tool that gathers years of personal crafting, don't use it too seriously thou."
|
3
|
+
tools:
|
4
|
+
gitrepo:
|
5
|
+
bless:
|
6
|
+
desc: 'Blesses the current folder to a remote repository'
|
7
|
+
list:
|
8
|
+
desc: 'Lists the remote repositories'
|
9
|
+
dns:
|
10
|
+
check_names:
|
11
|
+
desc: 'Checks a list of names for availability through DNS Lookup'
|
@@ -0,0 +1,11 @@
|
|
1
|
+
pt-BR:
|
2
|
+
greeting: 'Este é o Tacape, um utilitário para linha de comando que junta anos de hacking pessoal, no entanto, não leve muito a sério.'
|
3
|
+
tools:
|
4
|
+
gitrepo:
|
5
|
+
bless:
|
6
|
+
desc: '"Abençoa" a pasta atual para um repositório remoto'
|
7
|
+
list:
|
8
|
+
desc: 'Lista os repositórios remotos'
|
9
|
+
dns:
|
10
|
+
check_names:
|
11
|
+
desc: 'Verifica a disponibilidade de domínios através de uma lista de nomes utilizando DNS Lookup'
|
data/config/tacape.yml
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--
|
data/lib/tacape.rb
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'active_support/all'
|
2
|
+
require 'digest/md5'
|
3
|
+
require 'erb'
|
4
|
+
require 'logger'
|
5
|
+
require 'notifier'
|
6
|
+
require 'tempfile'
|
7
|
+
require 'pathname'
|
8
|
+
require 'thor'
|
9
|
+
require 'thor/group'
|
10
|
+
require 'yaml'
|
11
|
+
require 'os'
|
12
|
+
require 'i18n'
|
13
|
+
require 'pry'
|
14
|
+
require 'pry-nav'
|
15
|
+
|
16
|
+
Encoding.default_internal = "utf-8"
|
17
|
+
Encoding.default_external = "utf-8"
|
18
|
+
|
19
|
+
#Adds a way to retrieve Submodules of a Module, used for CustomContentParsers
|
20
|
+
class Module
|
21
|
+
def submodules
|
22
|
+
constants.collect {|const_name| const_get(const_name)}.select {|const| const.class == Module}
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
module Tacape
|
27
|
+
ROOT = Pathname.new(File.dirname(__FILE__) + "/..")
|
28
|
+
|
29
|
+
autoload :Cli, "tacape/cli"
|
30
|
+
autoload :Version, "tacape/version"
|
31
|
+
load "tacape/belt.rb"
|
32
|
+
|
33
|
+
def self.config(root_dir = nil)
|
34
|
+
root_dir ||= Pathname.new(Dir.pwd)
|
35
|
+
path = root_dir.join("config/tacape.yml")
|
36
|
+
|
37
|
+
raise "Invalid Tacape directory; couldn't found config/tacape.yml file." unless File.file?(path)
|
38
|
+
content = File.read(path)
|
39
|
+
erb = ERB.new(content).result
|
40
|
+
YAML.load(erb).with_indifferent_access
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.locale
|
44
|
+
I18n.load_path = Dir['config/locales/*.yml']
|
45
|
+
I18n.backend.load_translations
|
46
|
+
|
47
|
+
@locale ||= Belt.current_os.locale
|
48
|
+
case @locale
|
49
|
+
when 'pt_BR'
|
50
|
+
I18n.locale = :"pt-BR"
|
51
|
+
else
|
52
|
+
I18n.locale = :en
|
53
|
+
end
|
54
|
+
return @locale
|
55
|
+
end
|
56
|
+
Tacape.locale
|
57
|
+
|
58
|
+
def self.logger
|
59
|
+
@logger ||= Logger.new(File.open("/tmp/tacape.log", "a"))
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
data/lib/tacape/belt.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
module Tacape
|
2
|
+
load "tacape/oses/osx.rb"
|
3
|
+
load "tacape/oses/fedora.rb"
|
4
|
+
load "tacape/oses/os_exceptions.rb"
|
5
|
+
|
6
|
+
class Belt
|
7
|
+
def self.os_families
|
8
|
+
#msoft: [windows: Windows]
|
9
|
+
{:mac=> {:osx=>Tacape::Os::Osx}, :linux=> {:fedora=>Tacape::Os::Fedora}}
|
10
|
+
end
|
11
|
+
|
12
|
+
#Returns the current OS class
|
13
|
+
def self.current_os
|
14
|
+
current_os=:unknown
|
15
|
+
current_os=self.os_families[:mac][:osx] if OS.osx?
|
16
|
+
current_os=self.os_families[:msoft][:windows] if OS.windows?
|
17
|
+
if OS.linux?
|
18
|
+
Belt.os_families[:linux].each do |k,v|
|
19
|
+
current_os=v.identify if v.identify!=nil
|
20
|
+
end
|
21
|
+
end
|
22
|
+
if current_os==nil
|
23
|
+
raise OSLayerNotImplemented, "Sorry, no goodies for you for now, we only support there OSes:\n#{Tacape::Belt.os_families}"
|
24
|
+
else
|
25
|
+
return current_os
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
data/lib/tacape/cli.rb
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
module Tacape
|
3
|
+
load "tacape/tools/helpers/json_config.rb"
|
4
|
+
load "tacape/tools/helpers/os_support.rb"
|
5
|
+
|
6
|
+
class Cli < Thor
|
7
|
+
Dir["#{Tacape::Belt.current_os.tool_folder}/**/*.rb"].each do |tool|
|
8
|
+
load tool
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(*args)
|
12
|
+
super
|
13
|
+
@current_os=Tacape::Belt.current_os
|
14
|
+
create_folder_structure
|
15
|
+
puts I18n.t('greeting')
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.exit_on_failure?
|
19
|
+
true
|
20
|
+
end
|
21
|
+
|
22
|
+
desc "version", "Shows version"
|
23
|
+
map %w(-v --version) => :version
|
24
|
+
def version
|
25
|
+
say "Tacape version #{Version::STRING}"
|
26
|
+
end
|
27
|
+
|
28
|
+
desc "check", "Checks for system dependencies"
|
29
|
+
map %w(-c --check) => :check
|
30
|
+
def check
|
31
|
+
if `which ffmpeg`.include? 'ffmpeg'
|
32
|
+
ffmpeg=''
|
33
|
+
end
|
34
|
+
say "FFMPEG #{ffmpeg}"
|
35
|
+
end
|
36
|
+
|
37
|
+
desc "update", "Updates the Tools local repository"
|
38
|
+
map %w(-u --update) => :update
|
39
|
+
def update
|
40
|
+
update_tools
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
def config
|
45
|
+
YAML.load_file(config_path).with_indifferent_access
|
46
|
+
end
|
47
|
+
|
48
|
+
def config_path
|
49
|
+
root_dir.join("config/tacape.yml")
|
50
|
+
end
|
51
|
+
|
52
|
+
def root_dir
|
53
|
+
@root ||= Pathname.new(Dir.pwd)
|
54
|
+
end
|
55
|
+
|
56
|
+
def color(text, color)
|
57
|
+
color? ? shell.set_color(text, color) : text
|
58
|
+
end
|
59
|
+
|
60
|
+
def color?
|
61
|
+
shell.instance_of?(Thor::Shell::Color)
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.load_tools
|
65
|
+
Dir["#{Tacape::Belt.current_os.tool_folder}/**/*.rb"].each do |tool|
|
66
|
+
load tool
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def update_tools
|
71
|
+
#Should the tools be updated at each command?
|
72
|
+
Thread.new {
|
73
|
+
`cd #{@current_os.tool_folder} && git pull`
|
74
|
+
}
|
75
|
+
end
|
76
|
+
|
77
|
+
def create_folder_structure
|
78
|
+
unless File.exists? @current_os.config_folder
|
79
|
+
FileUtils.mkdir_p(@current_os.config_folder)
|
80
|
+
end
|
81
|
+
unless File.exists? @current_os.tool_folder
|
82
|
+
`git clone git@bitbucket.org:lucasmartins/tacape-tools.git #{@current_os.tool_folder}`
|
83
|
+
else
|
84
|
+
update_tools
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module Tacape
|
2
|
+
module Os
|
3
|
+
class Fedora
|
4
|
+
def initialize
|
5
|
+
Tacape.logger.info 'Building OS class...'
|
6
|
+
@version = Tacape::Fedora.version
|
7
|
+
@config_folder = Tacape::Fedora.config_folder
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.locale
|
11
|
+
puts 'Retrieving locale thorugh LANG environment variable...'
|
12
|
+
return ENV['LANG'].split('.').first
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.config_folder
|
16
|
+
return "#{ENV['HOME']}/.tacape/config"
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.tool_folder
|
20
|
+
return "#{ENV['HOME']}/.tacape/tools"
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.identify
|
24
|
+
if self.issue_info.include? 'Fedora'
|
25
|
+
puts "Creating folder structure for Fedora"
|
26
|
+
return Tacape::Belt.os_families[:linux][:fedora]
|
27
|
+
else
|
28
|
+
return nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.version
|
33
|
+
if issue_info.include? 'Fedora'
|
34
|
+
return issue_info.split(' ')[2]
|
35
|
+
else
|
36
|
+
raise WrongOSException,'Expecting Fedora'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
protected
|
41
|
+
def self.issue_info
|
42
|
+
id_file='/etc/issue'
|
43
|
+
if File.exists?(id_file)
|
44
|
+
return File.read(id_file)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Tacape
|
2
|
+
module Os
|
3
|
+
class Osx
|
4
|
+
def initialize
|
5
|
+
Tacape.logger.info 'Building OS class...'
|
6
|
+
@version = Tacape::Fedora.version
|
7
|
+
@config_folder = Tacape::Fedora.config_folder
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.locale
|
11
|
+
return ENV['LANG'].split('.').first
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.config_folder
|
15
|
+
return "#{ENV['HOME']}/.tacape/config"
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.tool_folder
|
19
|
+
return "#{ENV['HOME']}/.tacape/tools"
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.identify
|
23
|
+
if OS.osx?
|
24
|
+
return Tacape::Belt.os_families[:mac][:osx]
|
25
|
+
else
|
26
|
+
return nil
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.version
|
31
|
+
if OS.osx?
|
32
|
+
return `sw_vers -productVersion`.chomp
|
33
|
+
else
|
34
|
+
raise WrongOSException,'Expecting OSX'
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
protected
|
39
|
+
def issue_info
|
40
|
+
id_file='/etc/issue'
|
41
|
+
if File.exists?(id_file)
|
42
|
+
return File.read(id_file)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Tacape
|
2
|
+
module Tools
|
3
|
+
module Helpers
|
4
|
+
module JsonConfig
|
5
|
+
module InstanceMethods
|
6
|
+
def setup
|
7
|
+
@config={}
|
8
|
+
@config_template.each do |k,v|
|
9
|
+
tip=' use comma, no spaces' if v.class==Array
|
10
|
+
if @config_template[k]!=nil && @config_template[k]!=''
|
11
|
+
question = "#{k} [default=#{@config_template[k]}]#{tip}:"
|
12
|
+
else
|
13
|
+
question = "#{k}#{tip}:"
|
14
|
+
end
|
15
|
+
|
16
|
+
input = ask(question)
|
17
|
+
|
18
|
+
unless input.empty?
|
19
|
+
case v
|
20
|
+
when String
|
21
|
+
@config[k]=input
|
22
|
+
when Array
|
23
|
+
@config[k]=input.split(',')
|
24
|
+
else
|
25
|
+
puts "Bailed on #{v.class}"
|
26
|
+
end
|
27
|
+
if k.include?('folder') || k.include?('file')
|
28
|
+
if File.dirname(@config[k]) == '.'
|
29
|
+
@config[k]="#{ENV['HOME']}/#{@config[k]}"
|
30
|
+
end
|
31
|
+
unless File.exist?(File.dirname(@config[k]))
|
32
|
+
FileUtils.mkdir_p(File.dirname(@config[k]))
|
33
|
+
end
|
34
|
+
end
|
35
|
+
else
|
36
|
+
@config[k]=@config_template[k]
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
save_config
|
41
|
+
end
|
42
|
+
|
43
|
+
def load_config
|
44
|
+
if File.exist? @config_file
|
45
|
+
@config = JSON.parse(File.read(@config_file))
|
46
|
+
unless @config.class==Hash
|
47
|
+
raise 'Corrupt JSON file!'
|
48
|
+
end
|
49
|
+
return
|
50
|
+
else
|
51
|
+
setup
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def save_config
|
56
|
+
unless File.exist? File.dirname(@config_file)
|
57
|
+
FileUtils.mkdir_p(File.dirname(@config_file))
|
58
|
+
end
|
59
|
+
|
60
|
+
File.open(@config_file, 'w') {|f| f.write(@config.to_json) }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.included(receiver)
|
65
|
+
receiver.send :include, InstanceMethods
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Tacape
|
2
|
+
module Tools
|
3
|
+
module Helpers
|
4
|
+
module OsSupport
|
5
|
+
module InstanceMethods
|
6
|
+
def check_os_support
|
7
|
+
raise(OSLayerNotImplemented,'tool should have @os_support=[Tacepe::Os::SomeOs,...]') if @os_support==nil
|
8
|
+
@current_os=Tacape::Belt.current_os if @current_os==nil
|
9
|
+
unless @os_support.include? @current_os
|
10
|
+
raise UnsupportedOS, "This Tacape Tool does not support your OS."
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.included(receiver)
|
17
|
+
receiver.send :include, InstanceMethods
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/logo.gif
ADDED
Binary file
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require "tacape"
|
2
|
+
require "pathname"
|
3
|
+
require "test_notifier/runner/rspec"
|
4
|
+
|
5
|
+
SPECDIR = Pathname.new(File.dirname(__FILE__))
|
6
|
+
TMPDIR = SPECDIR.join("tmp")
|
7
|
+
|
8
|
+
Dir[File.dirname(__FILE__) + "/support/**/*.rb"].each {|r| require r}
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
config.include(SpecHelper)
|
12
|
+
config.include(Matchers)
|
13
|
+
|
14
|
+
config.before { FileUtils.mkdir_p(TMPDIR) }
|
15
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
RSpec::Matchers.define :exit_with_code do |code|
|
2
|
+
actual = nil
|
3
|
+
|
4
|
+
match do |block|
|
5
|
+
begin
|
6
|
+
block.call
|
7
|
+
rescue SystemExit => e
|
8
|
+
actual = e.status
|
9
|
+
end
|
10
|
+
|
11
|
+
actual && actual == code
|
12
|
+
end
|
13
|
+
|
14
|
+
failure_message_for_should do |block|
|
15
|
+
"expected block to call exit(#{code}) but exit" +
|
16
|
+
(actual ? "(#{actual}) was called" : " not called")
|
17
|
+
end
|
18
|
+
|
19
|
+
failure_message_for_should_not do |block|
|
20
|
+
"expected block not to call exit(#{code})"
|
21
|
+
end
|
22
|
+
|
23
|
+
description do
|
24
|
+
"expect block to call exit(#{code})"
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
module Matchers
|
2
|
+
def have_tag(selector, options = {}, &block)
|
3
|
+
HaveTag.new(:html, selector, options, &block)
|
4
|
+
end
|
5
|
+
|
6
|
+
def have_node(selector, options = {}, &block)
|
7
|
+
HaveTag.new(:xml, selector, options, &block)
|
8
|
+
end
|
9
|
+
|
10
|
+
class HaveTag
|
11
|
+
attr_reader :options, :selector, :actual, :actual_count, :doc, :type
|
12
|
+
|
13
|
+
def initialize(type, selector, options = {}, &block)
|
14
|
+
@selector = selector
|
15
|
+
@type = type
|
16
|
+
|
17
|
+
case options
|
18
|
+
when Hash
|
19
|
+
@options = options
|
20
|
+
when Numeric
|
21
|
+
@options = {:count => options}
|
22
|
+
else
|
23
|
+
@options = {:text => options}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def doc_for(input)
|
28
|
+
engine = type == :xml ? Nokogiri::XML : Nokogiri::HTML
|
29
|
+
|
30
|
+
if input.respond_to?(:body)
|
31
|
+
engine.parse(input.body.to_s)
|
32
|
+
elsif Nokogiri::XML::Element === input
|
33
|
+
input
|
34
|
+
else
|
35
|
+
engine.parse(input.to_s)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def matches?(actual, &block)
|
40
|
+
@actual = actual
|
41
|
+
@doc = doc_for(actual)
|
42
|
+
|
43
|
+
matches = doc.css(selector)
|
44
|
+
|
45
|
+
return options[:count] == 0 if matches.empty?
|
46
|
+
matches = filter_on_inner_text(matches) if options[:text]
|
47
|
+
matches = filter_on_nested_expectations(matches, block) if block
|
48
|
+
|
49
|
+
@actual_count = matches.size
|
50
|
+
|
51
|
+
return false if not acceptable_count?(actual_count)
|
52
|
+
|
53
|
+
!matches.empty?
|
54
|
+
end
|
55
|
+
|
56
|
+
def description
|
57
|
+
"have tag #{selector.inspect} with #{options.inspect}"
|
58
|
+
end
|
59
|
+
|
60
|
+
def failure_message
|
61
|
+
explanation = actual_count ? "but found #{actual_count}" : "but did not"
|
62
|
+
"expected\n#{doc.to_s}\nto have #{failure_count_phrase} #{failure_selector_phrase}, #{explanation}"
|
63
|
+
end
|
64
|
+
|
65
|
+
def negative_failure_message
|
66
|
+
explanation = actual_count ? "but found #{actual_count}" : "but did"
|
67
|
+
"expected\n#{doc.to_s}\nnot to have #{failure_count_phrase} #{failure_selector_phrase}, #{explanation}"
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
def filter_on_inner_text(elements)
|
72
|
+
elements.select do |el|
|
73
|
+
next(el.inner_text =~ options[:text]) if options[:text].is_a?(Regexp)
|
74
|
+
el.inner_text == options[:text]
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def filter_on_nested_expectations(elements, block)
|
79
|
+
elements.select do |el|
|
80
|
+
begin
|
81
|
+
block[el]
|
82
|
+
rescue RSpec::Expectations::ExpectationNotMetError
|
83
|
+
false
|
84
|
+
else
|
85
|
+
true
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
def acceptable_count?(count)
|
91
|
+
return false unless options[:count] === count if options[:count]
|
92
|
+
return false unless count >= options[:minimum] if options[:minimum]
|
93
|
+
return false unless count <= options[:maximum] if options[:maximum]
|
94
|
+
true
|
95
|
+
end
|
96
|
+
|
97
|
+
def failure_count_phrase
|
98
|
+
if options[:count]
|
99
|
+
"#{options[:count]} elements matching"
|
100
|
+
elsif options[:minimum] || options[:maximum]
|
101
|
+
count_explanations = []
|
102
|
+
count_explanations << "at least #{options[:minimum]}" if options[:minimum]
|
103
|
+
count_explanations << "at most #{options[:maximum]}" if options[:maximum]
|
104
|
+
"#{count_explanations.join(' and ')} elements matching"
|
105
|
+
else
|
106
|
+
"an element matching"
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
def failure_selector_phrase
|
111
|
+
phrase = selector.inspect
|
112
|
+
phrase << (options[:text] ? " with inner text #{options[:text].inspect}" : "")
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module SpecHelper
|
2
|
+
def tmpdir
|
3
|
+
TMPDIR
|
4
|
+
end
|
5
|
+
|
6
|
+
def capture(stream)
|
7
|
+
begin
|
8
|
+
stream = stream.to_s
|
9
|
+
eval "$#{stream} = StringIO.new"
|
10
|
+
yield
|
11
|
+
result = eval("$#{stream}").string
|
12
|
+
ensure
|
13
|
+
eval("$#{stream} = #{stream.upcase}")
|
14
|
+
end
|
15
|
+
|
16
|
+
result
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
shared_examples_for "e-book" do
|
2
|
+
let(:mybook) { tmpdir.join("mybook") }
|
3
|
+
|
4
|
+
it "generates e-book" do
|
5
|
+
mybook.should be_directory
|
6
|
+
end
|
7
|
+
|
8
|
+
it "creates images directory" do
|
9
|
+
mybook.join("images").should be_directory
|
10
|
+
end
|
11
|
+
|
12
|
+
it "creates text directory" do
|
13
|
+
mybook.join("text").should be_directory
|
14
|
+
end
|
15
|
+
|
16
|
+
it "creates code directory" do
|
17
|
+
mybook.join("code").should be_directory
|
18
|
+
end
|
19
|
+
|
20
|
+
it "creates template directory" do
|
21
|
+
mybook.join("templates").should be_directory
|
22
|
+
end
|
23
|
+
|
24
|
+
it "creates configuration file" do
|
25
|
+
mybook.join("config/kitabu.yml").should be_file
|
26
|
+
end
|
27
|
+
|
28
|
+
it "creates helper file" do
|
29
|
+
mybook.join("config/helper.rb").should be_file
|
30
|
+
end
|
31
|
+
|
32
|
+
it "copies sample page" do
|
33
|
+
mybook.join("text/01_Welcome.md")
|
34
|
+
end
|
35
|
+
|
36
|
+
it "copies Guardfile" do
|
37
|
+
mybook.join("Guardfile")
|
38
|
+
end
|
39
|
+
|
40
|
+
it "copies html template files" do
|
41
|
+
mybook.join("templates/html/user.css").should be_file
|
42
|
+
mybook.join("templates/html/layout.css").should be_file
|
43
|
+
mybook.join("templates/html/layout.erb").should be_file
|
44
|
+
mybook.join("templates/html/syntax.css").should be_file
|
45
|
+
end
|
46
|
+
|
47
|
+
it "copies epub template files" do
|
48
|
+
mybook.join("templates/epub/user.css").should be_file
|
49
|
+
mybook.join("templates/epub/cover.erb").should be_file
|
50
|
+
mybook.join("templates/epub/cover.png").should be_file
|
51
|
+
mybook.join("templates/epub/page.erb").should be_file
|
52
|
+
end
|
53
|
+
end
|
data/spec/tacape.rb
ADDED
data/tacape.gemspec
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "tacape/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "tacape"
|
7
|
+
s.version = Tacape::Version::STRING
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.required_ruby_version = ">= 1.9"
|
10
|
+
s.authors = ["Lucas Martins"]
|
11
|
+
s.email = ["lucasmartins@railsnapraia.com"]
|
12
|
+
#s.homepage = "http://rubygems.org/gems/tacape"
|
13
|
+
s.summary = "A command-line tool that gathers some years of personal crafting."
|
14
|
+
s.description = s.summary
|
15
|
+
s.license = "MIT"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_dependency "activesupport"
|
23
|
+
s.add_dependency "i18n"
|
24
|
+
s.add_dependency "thor"
|
25
|
+
s.add_dependency "notifier"
|
26
|
+
s.add_dependency "os"
|
27
|
+
|
28
|
+
s.add_development_dependency "rspec"
|
29
|
+
s.add_development_dependency "test_notifier"
|
30
|
+
s.add_development_dependency "rake"
|
31
|
+
s.add_development_dependency "pry"
|
32
|
+
s.add_development_dependency "pry-nav"
|
33
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#You must add -> load "tacape/tools/sample.rb" to cli.rb
|
2
|
+
module Tacape
|
3
|
+
module Tools
|
4
|
+
class Sample < Thor
|
5
|
+
namespace 'sample'
|
6
|
+
|
7
|
+
desc 'test','This is just a sample'
|
8
|
+
def test
|
9
|
+
puts "Implement your tool like this, pay attention to the namespace so it doesn't clash with other tools."
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
#Redefining the Cli to use this Tool
|
16
|
+
class Cli < Thor
|
17
|
+
desc 'sample','Defines a Tacape tool'
|
18
|
+
subcommand 'sample', Tools::Sample
|
19
|
+
end
|
20
|
+
end
|
metadata
ADDED
@@ -0,0 +1,242 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: tacape
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.3
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Lucas Martins
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-06-12 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activesupport
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: i18n
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: thor
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: notifier
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: os
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :runtime
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: rspec
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: test_notifier
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: rake
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
type: :development
|
135
|
+
prerelease: false
|
136
|
+
version_requirements: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
- !ruby/object:Gem::Dependency
|
143
|
+
name: pry
|
144
|
+
requirement: !ruby/object:Gem::Requirement
|
145
|
+
none: false
|
146
|
+
requirements:
|
147
|
+
- - ! '>='
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
type: :development
|
151
|
+
prerelease: false
|
152
|
+
version_requirements: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ! '>='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
158
|
+
- !ruby/object:Gem::Dependency
|
159
|
+
name: pry-nav
|
160
|
+
requirement: !ruby/object:Gem::Requirement
|
161
|
+
none: false
|
162
|
+
requirements:
|
163
|
+
- - ! '>='
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
type: :development
|
167
|
+
prerelease: false
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
none: false
|
170
|
+
requirements:
|
171
|
+
- - ! '>='
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
description: A command-line tool that gathers some years of personal crafting.
|
175
|
+
email:
|
176
|
+
- lucasmartins@railsnapraia.com
|
177
|
+
executables:
|
178
|
+
- tacape
|
179
|
+
extensions: []
|
180
|
+
extra_rdoc_files: []
|
181
|
+
files:
|
182
|
+
- .gitignore
|
183
|
+
- .rspec
|
184
|
+
- Gemfile
|
185
|
+
- Gemfile.lock
|
186
|
+
- Rakefile
|
187
|
+
- Readme.md
|
188
|
+
- bin/tacape
|
189
|
+
- config/locales/en.yml
|
190
|
+
- config/locales/pt-BR.yml
|
191
|
+
- config/tacape.yml
|
192
|
+
- lib/tacape.rb
|
193
|
+
- lib/tacape/belt.rb
|
194
|
+
- lib/tacape/cli.rb
|
195
|
+
- lib/tacape/oses/fedora.rb
|
196
|
+
- lib/tacape/oses/os_exceptions.rb
|
197
|
+
- lib/tacape/oses/osx.rb
|
198
|
+
- lib/tacape/tools/helpers/json_config.rb
|
199
|
+
- lib/tacape/tools/helpers/os_support.rb
|
200
|
+
- lib/tacape/version.rb
|
201
|
+
- logo.gif
|
202
|
+
- spec/spec_helper.rb
|
203
|
+
- spec/support/exit_with_code.rb
|
204
|
+
- spec/support/have_tag.rb
|
205
|
+
- spec/support/helper.rb
|
206
|
+
- spec/support/shared.rb
|
207
|
+
- spec/tacape.rb
|
208
|
+
- tacape.gemspec
|
209
|
+
- templates/tools/sample.rb
|
210
|
+
homepage:
|
211
|
+
licenses:
|
212
|
+
- MIT
|
213
|
+
post_install_message:
|
214
|
+
rdoc_options: []
|
215
|
+
require_paths:
|
216
|
+
- lib
|
217
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
218
|
+
none: false
|
219
|
+
requirements:
|
220
|
+
- - ! '>='
|
221
|
+
- !ruby/object:Gem::Version
|
222
|
+
version: '1.9'
|
223
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
224
|
+
none: false
|
225
|
+
requirements:
|
226
|
+
- - ! '>='
|
227
|
+
- !ruby/object:Gem::Version
|
228
|
+
version: '0'
|
229
|
+
requirements: []
|
230
|
+
rubyforge_project:
|
231
|
+
rubygems_version: 1.8.23
|
232
|
+
signing_key:
|
233
|
+
specification_version: 3
|
234
|
+
summary: A command-line tool that gathers some years of personal crafting.
|
235
|
+
test_files:
|
236
|
+
- spec/spec_helper.rb
|
237
|
+
- spec/support/exit_with_code.rb
|
238
|
+
- spec/support/have_tag.rb
|
239
|
+
- spec/support/helper.rb
|
240
|
+
- spec/support/shared.rb
|
241
|
+
- spec/tacape.rb
|
242
|
+
has_rdoc:
|