tacape 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
[![Code Climate](https://codeclimate.com/github/lucasmartins/tacape.png)](https://codeclimate.com/github/lucasmartins/tacape) [![Build Status](https://secure.travis-ci.org/lucasmartins/tacape.png?branch=master)](https://travis-ci.org/lucasmartins/tacape) [![Dependency Status](https://gemnasium.com/lucasmartins/tacape.png)](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:
|