shepherd 0.1.0 → 0.1.2
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 +6 -0
- data/CHANGELOG.md +14 -0
- data/Gemfile +2 -12
- data/README.md +41 -14
- data/Rakefile +1 -54
- data/bin/shep +16 -0
- data/lib/shepherd/cli.rb +121 -0
- data/lib/shepherd/command.rb +65 -0
- data/lib/shepherd/commands/init.rb +51 -0
- data/lib/shepherd/counter.rb +140 -0
- data/lib/shepherd/db.rb +40 -0
- data/lib/shepherd/version.rb +7 -7
- data/lib/shepherd.rb +9 -0
- data/lib/trollop.rb +782 -0
- data/shepherd.gemspec +19 -52
- metadata +33 -44
- data/.document +0 -5
- data/Gemfile.lock +0 -20
- data/test/helper.rb +0 -18
- data/test/test_shepherd.rb +0 -7
data/.gitignore
ADDED
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# shepherd 0.1.2 (18-07-2011)
|
|
2
|
+
|
|
3
|
+
+ Make the `Counter` class
|
|
4
|
+
+ The `init` command works-but-not-really - it's not saving projects at the moment
|
|
5
|
+
+ Provide `Db` connector
|
|
6
|
+
|
|
7
|
+
# shepherd 0.1.1 (04-07-2011)
|
|
8
|
+
|
|
9
|
+
+ Ease in creating your own commands!
|
|
10
|
+
+ Let be t'e `Cli`!
|
|
11
|
+
|
|
12
|
+
# shepherd 0.1.0 (18-06-2011)
|
|
13
|
+
|
|
14
|
+
+ Birthday!
|
data/Gemfile
CHANGED
|
@@ -1,13 +1,3 @@
|
|
|
1
|
-
source
|
|
2
|
-
# Add dependencies required to use your gem here.
|
|
3
|
-
# Example:
|
|
4
|
-
# gem "activesupport", ">= 2.3.5"
|
|
1
|
+
source :gemcutter
|
|
5
2
|
|
|
6
|
-
|
|
7
|
-
# Include everything needed to run rake, tests, features, etc.
|
|
8
|
-
group :development do
|
|
9
|
-
gem "shoulda", ">= 0"
|
|
10
|
-
gem "bundler", "~> 1.0.0"
|
|
11
|
-
gem "jeweler", "~> 1.6.1"
|
|
12
|
-
gem "rcov", ">= 0"
|
|
13
|
-
end
|
|
3
|
+
gemspec
|
data/README.md
CHANGED
|
@@ -1,13 +1,40 @@
|
|
|
1
|
-
|
|
1
|
+
Shepherd
|
|
2
|
+
========
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
4
|
+
<table>
|
|
5
|
+
<tr>
|
|
6
|
+
<td><b>Homepage</b></td>
|
|
7
|
+
<td><a href="http://semahawk.github.com/shepherd">http://semahawk.github.com/shepherd</a></td>
|
|
8
|
+
</tr>
|
|
9
|
+
<tr>
|
|
10
|
+
<td><b>Author</b></td>
|
|
11
|
+
<td>Szymon Urbaś (szymon dot urbas at yahoo dot com)</td>
|
|
12
|
+
</tr>
|
|
13
|
+
<tr>
|
|
14
|
+
<td><b>Copyright</b></td>
|
|
15
|
+
<td>2011</td>
|
|
16
|
+
</tr>
|
|
17
|
+
<tr>
|
|
18
|
+
<td><b>License</b></td>
|
|
19
|
+
<td>MIT</td>
|
|
20
|
+
</tr>
|
|
21
|
+
<tr>
|
|
22
|
+
<td> </td>
|
|
23
|
+
<td> </td>
|
|
24
|
+
</tr>
|
|
25
|
+
<tr>
|
|
26
|
+
<td><b>Latest version</b></td>
|
|
27
|
+
<td>0.1.1</td>
|
|
28
|
+
</tr>
|
|
29
|
+
<tr>
|
|
30
|
+
<td><b>Release date</b></td>
|
|
31
|
+
<td>July 4th, 2011</td>
|
|
32
|
+
</tr>
|
|
33
|
+
<tr>
|
|
34
|
+
<td><b>Stage</b></td>
|
|
35
|
+
<td><i>Development</i></td>
|
|
36
|
+
</tr>
|
|
37
|
+
</table>
|
|
11
38
|
|
|
12
39
|
## A bit about
|
|
13
40
|
|
|
@@ -16,13 +43,13 @@ You just know, if your project got few kilobytes more on weight, how many more f
|
|
|
16
43
|
|
|
17
44
|
## Features
|
|
18
45
|
|
|
19
|
-
|
|
46
|
+
+ Easy own command creation.
|
|
47
|
+
|
|
48
|
+
## Dependencies
|
|
20
49
|
|
|
21
|
-
|
|
50
|
+
+ [sqlite3](http://rubygems.org/gems/sqlite3) (~> 1.3.0)
|
|
22
51
|
|
|
23
|
-
|
|
24
|
-
* Uh.. Emm...
|
|
25
|
-
* Yeah..
|
|
52
|
+
Shepherd also uses `cat` and `wc` UNIX commands, so if you are on UNIX(-like) system there should be no problem.
|
|
26
53
|
|
|
27
54
|
## Oh, NO - a BUG!
|
|
28
55
|
|
data/Rakefile
CHANGED
|
@@ -1,54 +1 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
require 'rubygems'
|
|
4
|
-
require 'bundler'
|
|
5
|
-
begin
|
|
6
|
-
Bundler.setup(:default, :development)
|
|
7
|
-
rescue Bundler::BundlerError => e
|
|
8
|
-
$stderr.puts e.message
|
|
9
|
-
$stderr.puts "Run `bundle install` to install missing gems"
|
|
10
|
-
exit e.status_code
|
|
11
|
-
end
|
|
12
|
-
require 'rake'
|
|
13
|
-
|
|
14
|
-
require 'jeweler'
|
|
15
|
-
require './lib/shepherd/version'
|
|
16
|
-
Jeweler::Tasks.new do |gem|
|
|
17
|
-
gem.name = "shepherd"
|
|
18
|
-
gem.homepage = "http://github.com/semahawk/shepherd"
|
|
19
|
-
gem.license = "MIT"
|
|
20
|
-
gem.summary = %Q{Be a shepherd to your projects!}
|
|
21
|
-
gem.description = %Q{*BETA* Be a shepherd to your projects! Check out whether they grow up, get larger or something-else-shepherds-do!}
|
|
22
|
-
gem.version = Shepherd::Version::STRING
|
|
23
|
-
gem.email = "szymon.urbas@yahoo.com"
|
|
24
|
-
gem.authors = ["Szymon Urbaś"]
|
|
25
|
-
# dependencies defined in Gemfile
|
|
26
|
-
end
|
|
27
|
-
Jeweler::RubygemsDotOrgTasks.new
|
|
28
|
-
|
|
29
|
-
require 'rake/testtask'
|
|
30
|
-
Rake::TestTask.new(:test) do |test|
|
|
31
|
-
test.libs << 'lib' << 'test'
|
|
32
|
-
test.pattern = 'test/**/test_*.rb'
|
|
33
|
-
test.verbose = true
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
require 'rcov/rcovtask'
|
|
37
|
-
Rcov::RcovTask.new do |test|
|
|
38
|
-
test.libs << 'test'
|
|
39
|
-
test.pattern = 'test/**/test_*.rb'
|
|
40
|
-
test.verbose = true
|
|
41
|
-
test.rcov_opts << '--exclude "gems/*"'
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
task :default => :test
|
|
45
|
-
|
|
46
|
-
require 'rake/rdoctask'
|
|
47
|
-
Rake::RDocTask.new do |rdoc|
|
|
48
|
-
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
|
49
|
-
|
|
50
|
-
rdoc.rdoc_dir = 'rdoc'
|
|
51
|
-
rdoc.title = "shepherd #{version}"
|
|
52
|
-
rdoc.rdoc_files.include('README*')
|
|
53
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
|
54
|
-
end
|
|
1
|
+
require 'bundler/gem_tasks'
|
data/bin/shep
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# encoding: utf-8
|
|
3
|
+
|
|
4
|
+
# Add the lib directory to $LOAD_PATH
|
|
5
|
+
lib = File.expand_path(File.dirname(__FILE__) + '/../lib')
|
|
6
|
+
$LOAD_PATH.unshift(lib) if File.directory?(lib) && !$LOAD_PATH.include?(lib)
|
|
7
|
+
|
|
8
|
+
# Require needed files
|
|
9
|
+
require 'shepherd'
|
|
10
|
+
require 'shepherd/cli'
|
|
11
|
+
|
|
12
|
+
# We make the --help option the default (if no command passed, show help)
|
|
13
|
+
ARGV << '--help' if ARGV.empty? && $stdin.tty?
|
|
14
|
+
|
|
15
|
+
# Run Shepherd, ruuun!
|
|
16
|
+
Shepherd::Cli.new.run!
|
data/lib/shepherd/cli.rb
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
require "trollop"
|
|
2
|
+
|
|
3
|
+
module Shepherd
|
|
4
|
+
|
|
5
|
+
# Command Line Interface class
|
|
6
|
+
class Cli
|
|
7
|
+
|
|
8
|
+
# Kinda self explanatory
|
|
9
|
+
class UnknownCommand < RuntimeError; end
|
|
10
|
+
|
|
11
|
+
# A command which is about to be run
|
|
12
|
+
attr_accessor :command
|
|
13
|
+
|
|
14
|
+
# Require *all* command files
|
|
15
|
+
Dir[File.join(File.dirname(__FILE__), "commands", "*.rb")].each do |all_command_files|
|
|
16
|
+
require all_command_files
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Handle the commands list
|
|
20
|
+
#
|
|
21
|
+
# @return [Array] all available commands
|
|
22
|
+
COMMANDS = Command.constants.select { |c| Class === Command.const_get(c) }
|
|
23
|
+
|
|
24
|
+
# Get a list of available commands to be printed. (Almost) every line is separated by new line mark - \n
|
|
25
|
+
#
|
|
26
|
+
# @return [String] list of all available commands
|
|
27
|
+
def commands_list
|
|
28
|
+
out = ""
|
|
29
|
+
# If there are no commands set
|
|
30
|
+
if COMMANDS.empty?
|
|
31
|
+
out << " ooops! commands are not here!"
|
|
32
|
+
else
|
|
33
|
+
# Get the longest command's name, so we can output it nice 'n' clean
|
|
34
|
+
# This '+ int' at the end is a distance (in spaces) from the longest
|
|
35
|
+
# command to descriptions
|
|
36
|
+
longest = COMMANDS.max_by(&:size).size + 8
|
|
37
|
+
COMMANDS.each do |cmd|
|
|
38
|
+
# Calc, calc.
|
|
39
|
+
spaces = longest - cmd.size
|
|
40
|
+
# Check if there is a 'desc' method
|
|
41
|
+
desc = if eval "Command::#{cmd}.new.respond_to? 'desc'"
|
|
42
|
+
# If there is - execute it
|
|
43
|
+
eval "Command::#{cmd}.new.desc"
|
|
44
|
+
else
|
|
45
|
+
# If there is not
|
|
46
|
+
"~ no description provided ~"
|
|
47
|
+
end
|
|
48
|
+
out << " " << cmd.downcase.to_s << " " * spaces << desc
|
|
49
|
+
# If this command is the last one, don't make a new line
|
|
50
|
+
unless cmd == COMMANDS.last
|
|
51
|
+
out << "\n"
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
out
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# Check if command really exists
|
|
59
|
+
#
|
|
60
|
+
# @return [Boolean] whether the command exists or not
|
|
61
|
+
def command_exists?
|
|
62
|
+
COMMANDS.include? @command
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Rruns t'e Cli!
|
|
66
|
+
def run!
|
|
67
|
+
|
|
68
|
+
# Nice, cool 'n' AWESOME --options parsing with Trollop[http://trollop.rubyforge.org/]!
|
|
69
|
+
#
|
|
70
|
+
# @return [Hash] array full of options
|
|
71
|
+
$opts = Trollop::options do
|
|
72
|
+
version "Shepherd be t'e version #{Version::STRING}"
|
|
73
|
+
banner <<-EOB
|
|
74
|
+
usage: shep [options] <command>
|
|
75
|
+
|
|
76
|
+
commands are:
|
|
77
|
+
|
|
78
|
+
#{Cli.new.commands_list}
|
|
79
|
+
|
|
80
|
+
shep <command> --help for more info about specified command
|
|
81
|
+
|
|
82
|
+
options are:
|
|
83
|
+
EOB
|
|
84
|
+
|
|
85
|
+
opt :version, "show version and exit", :short => '-v'
|
|
86
|
+
opt :help, "show me and exit", :short => '-h'
|
|
87
|
+
|
|
88
|
+
stop_on COMMANDS.collect { |e| e.downcase.to_s }
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Get the command
|
|
92
|
+
@command = ARGV.shift.capitalize.to_sym
|
|
93
|
+
|
|
94
|
+
begin
|
|
95
|
+
execute @command
|
|
96
|
+
exit 0
|
|
97
|
+
rescue UnknownCommand => e
|
|
98
|
+
puts e.message
|
|
99
|
+
exit 1
|
|
100
|
+
rescue Db::DatabaseNotFound => e
|
|
101
|
+
puts e.message
|
|
102
|
+
exit 1
|
|
103
|
+
rescue Interrupt
|
|
104
|
+
puts "\n\n~> interrupted"
|
|
105
|
+
exit 1
|
|
106
|
+
end
|
|
107
|
+
end # run!:Method
|
|
108
|
+
|
|
109
|
+
# Executes a command
|
|
110
|
+
#
|
|
111
|
+
# @return [Object] command to execute
|
|
112
|
+
# @raise [UnknownCommand] if there is no such a command
|
|
113
|
+
def execute command
|
|
114
|
+
if command_exists?
|
|
115
|
+
eval "Command::#{command}.new.init"
|
|
116
|
+
else
|
|
117
|
+
raise UnknownCommand, "Error: unknown command '#{command.downcase.to_s}'.\nTry --help for help."
|
|
118
|
+
end
|
|
119
|
+
end # execute_command:Method
|
|
120
|
+
end # Cli:Class
|
|
121
|
+
end # Shepherd:Module
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
module Shepherd
|
|
2
|
+
|
|
3
|
+
# A (actually, very) simple class, which is used to determine whether is this class a command, or not.
|
|
4
|
+
#
|
|
5
|
+
# == Creating a command
|
|
6
|
+
# A Shepherd's command is just a class, which is kept inside +Shepherd::Command+.
|
|
7
|
+
# Just create a ruby file inside +lib/shepherd/commands/+ called however you like, eg. foo.rb.
|
|
8
|
+
# This file should look kinda like this stuff:
|
|
9
|
+
#
|
|
10
|
+
# module Shepherd::Command
|
|
11
|
+
# class Foobar # this is the commands name; that would be: shep foobar
|
|
12
|
+
# def init # when you call: shep <command>, init method here is executed.
|
|
13
|
+
# puts "foobarinize!"
|
|
14
|
+
# end
|
|
15
|
+
# end
|
|
16
|
+
# end
|
|
17
|
+
#
|
|
18
|
+
# You can also specify some other method than +init+ (eg. ahoy) and then use an +alias+ method:
|
|
19
|
+
#
|
|
20
|
+
# module Shepherd::Command
|
|
21
|
+
# class Pirate
|
|
22
|
+
# def ahoy
|
|
23
|
+
# puts "Ahoy, aad'enturre!"
|
|
24
|
+
# end
|
|
25
|
+
# alias :init :ahoy
|
|
26
|
+
# end
|
|
27
|
+
# end
|
|
28
|
+
#
|
|
29
|
+
# == Options parsing
|
|
30
|
+
# For --options parsing, Shepherd uses Trollop[http://trollop.rubyforge.org/] (which by the way is AWESOME!):
|
|
31
|
+
#
|
|
32
|
+
# module Shepherd::Command
|
|
33
|
+
# class Foobar
|
|
34
|
+
# def init
|
|
35
|
+
# opts = Trollop::options do
|
|
36
|
+
# opt :monkey, "Use monkey mode" # flag --monkey, default false
|
|
37
|
+
# opt :goat, "Use goat mode", :default => true # flag --goat, default true
|
|
38
|
+
# opt :num_limbs, "Number of limbs", :default => 4 # integer --num-limbs <i>, default to 4
|
|
39
|
+
# opt :num_thumbs, "Number of thumbs", :type => :int # integer --num-thumbs <i>, default nil
|
|
40
|
+
# end
|
|
41
|
+
# end
|
|
42
|
+
# end
|
|
43
|
+
# end
|
|
44
|
+
#
|
|
45
|
+
# You can of course use for example +OptionParser+, if you want. But.. Trollop[http://trollop.rubyforge.org/] is AWESOME! THAT's why wise Shepherd is using it ;)
|
|
46
|
+
#
|
|
47
|
+
# == Multiple commands
|
|
48
|
+
# Also, yau can create more than one command inside one file:
|
|
49
|
+
#
|
|
50
|
+
# module Shepherd::Command
|
|
51
|
+
# class Foobar
|
|
52
|
+
# def init
|
|
53
|
+
# puts "foobarinize!"
|
|
54
|
+
# end
|
|
55
|
+
# end
|
|
56
|
+
#
|
|
57
|
+
# class Barbaz
|
|
58
|
+
# def init
|
|
59
|
+
# puts "barbazinize!"
|
|
60
|
+
# end
|
|
61
|
+
# end
|
|
62
|
+
# end
|
|
63
|
+
#
|
|
64
|
+
module Command; end
|
|
65
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module Shepherd::Command
|
|
2
|
+
class Init
|
|
3
|
+
def init
|
|
4
|
+
@opts = Trollop::options do
|
|
5
|
+
banner <<-EOB
|
|
6
|
+
usage: shep [options] init [-h|--help]
|
|
7
|
+
|
|
8
|
+
options are:
|
|
9
|
+
EOB
|
|
10
|
+
opt :path, "a root path to the project", :default => Dir.pwd
|
|
11
|
+
opt :name, "set a projects name (default: a top directory name from --path will be taken)", :type => :string
|
|
12
|
+
opt :quiet, "don't show what's going on"
|
|
13
|
+
opt :help, "show me and exit", :short => '-h'
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
@state = {}
|
|
17
|
+
# delete the last '/' in path if present
|
|
18
|
+
@state[:path] = @opts[:path].chomp "/"
|
|
19
|
+
# use this top directory name unless --name is set
|
|
20
|
+
@state[:name] = @opts[:name] ? @opts[:name] : @opts[:path].split("/").last
|
|
21
|
+
|
|
22
|
+
Shepherd::Counter.new(@state[:path]) do |count|
|
|
23
|
+
@state[:files] = count.files
|
|
24
|
+
@state[:lines] = count.lines
|
|
25
|
+
@state[:chars] = count.chars
|
|
26
|
+
@state[:bytes] = count.bytes
|
|
27
|
+
@state[:rawbytes] = count.rawbytes
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
puts "Our brave-hearted Shepherd initializes a new project!
|
|
31
|
+
|
|
32
|
+
path: \e[1;34m#{@state[:path]}\e[0;0m
|
|
33
|
+
name: \e[1;32m#{@state[:name]}\e[0;0m
|
|
34
|
+
|
|
35
|
+
state: #{@state[:files].size} files
|
|
36
|
+
#{@state[:lines]} lines
|
|
37
|
+
#{@state[:chars]} chars
|
|
38
|
+
|
|
39
|
+
#{@state[:bytes]} (#{@state[:rawbytes]} bytes)
|
|
40
|
+
|
|
41
|
+
" unless @opts[:quiet]
|
|
42
|
+
|
|
43
|
+
# TODO: save to database
|
|
44
|
+
# Shepherd::Db.new.execute "inserting query"
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def desc
|
|
48
|
+
"initialize a new project"
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
require "find"
|
|
2
|
+
|
|
3
|
+
module Shepherd
|
|
4
|
+
|
|
5
|
+
# A simple class that counts all the needed data (like files, lines, bytes and so-on) in given destination path.
|
|
6
|
+
#
|
|
7
|
+
# == Usage
|
|
8
|
+
#
|
|
9
|
+
# Without using a block:
|
|
10
|
+
# module Shepherd
|
|
11
|
+
# count = Counter.new(/path/to/destination/dir)
|
|
12
|
+
# count.files #=> 26
|
|
13
|
+
# count.lines #=> 2319
|
|
14
|
+
# count.chars #=> 79240
|
|
15
|
+
# end
|
|
16
|
+
#
|
|
17
|
+
# With a block:
|
|
18
|
+
# module Shepherd
|
|
19
|
+
# Counter.new(/path/to/destination/dir) do |count|
|
|
20
|
+
# count.files #=> 26
|
|
21
|
+
# count.lines #=> 2319
|
|
22
|
+
# count.chars #=> 79240
|
|
23
|
+
# end
|
|
24
|
+
# end
|
|
25
|
+
#
|
|
26
|
+
# Inside a +Shepherd::Command::Klass+ you should use it like so:
|
|
27
|
+
# module Shepherd::Command
|
|
28
|
+
# class Klass
|
|
29
|
+
# Shepherd::Counter.new(/path/to/destination/dir) do |count|
|
|
30
|
+
# count.files #=> 26
|
|
31
|
+
# count.lines #=> 2319
|
|
32
|
+
# count.chars #=> 79240
|
|
33
|
+
# end
|
|
34
|
+
# end
|
|
35
|
+
# end
|
|
36
|
+
#
|
|
37
|
+
# @return [Shepherd::Counter] a new instance of +Shepherd::Counter+
|
|
38
|
+
# @yield [Shepherd::Counter] a new instance of +Shepherd::Counter+
|
|
39
|
+
#
|
|
40
|
+
class Counter
|
|
41
|
+
# A new instance of +Shepherd::Counter+
|
|
42
|
+
#
|
|
43
|
+
# @param [String] path a path to the project
|
|
44
|
+
# @return [Shepherd::Counter] a new instance of +Shepherd::Counter+
|
|
45
|
+
# @yield [Shepherd::Counter] a new instance of +Shepherd::Counter+
|
|
46
|
+
def initialize path
|
|
47
|
+
# delete the last '/' in path if present, just to make sure :)
|
|
48
|
+
@path = path.chomp "/"
|
|
49
|
+
|
|
50
|
+
yield self if block_given?
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Convert bytes into more human readable format.
|
|
54
|
+
# Found nice resolution here[http://www.ruby-forum.com/topic/119703] which was originally written by {Jeff Emminger}[http://www.ruby-forum.com/user/show/jemminger] and I just add this part to automaticly set the unit. Thank you!
|
|
55
|
+
#
|
|
56
|
+
# @param [Integer] number a number to be formatted
|
|
57
|
+
# @return [String] a formatted number
|
|
58
|
+
def nice_bytes number
|
|
59
|
+
units = {:b => 1,
|
|
60
|
+
:kb => 2**10,
|
|
61
|
+
:mb => 2**20,
|
|
62
|
+
:gb => 2**30,
|
|
63
|
+
:tb => 2**40}
|
|
64
|
+
|
|
65
|
+
unit = :b
|
|
66
|
+
case number
|
|
67
|
+
when 1...2**10
|
|
68
|
+
unit = :b
|
|
69
|
+
when 2**10...2**20
|
|
70
|
+
unit = :kb
|
|
71
|
+
when 2**20...2**30
|
|
72
|
+
unit = :mb
|
|
73
|
+
when 2**30...2**40
|
|
74
|
+
unit = :gb
|
|
75
|
+
when 2**40...2**50
|
|
76
|
+
unit = :tb
|
|
77
|
+
end
|
|
78
|
+
"#{sprintf("%.#{0}f", number / units[unit.to_s.downcase.to_sym])} #{unit.to_s.upcase}"
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Count the files (excluding dotfiles).
|
|
82
|
+
#
|
|
83
|
+
# @return [Array] list of all files (dotfiles are not included)
|
|
84
|
+
def files
|
|
85
|
+
@files = []
|
|
86
|
+
Find.find(@path) do |path|
|
|
87
|
+
if File.directory? path
|
|
88
|
+
if File.basename(path)[0] == ?.
|
|
89
|
+
Find.prune # don't look any further into this directory.
|
|
90
|
+
else
|
|
91
|
+
next
|
|
92
|
+
end
|
|
93
|
+
else
|
|
94
|
+
@files << path
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
@files
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Count the lines.
|
|
101
|
+
#
|
|
102
|
+
# @return [Integer] lines amount
|
|
103
|
+
def lines
|
|
104
|
+
@lines = 0
|
|
105
|
+
@files.each do |file|
|
|
106
|
+
@lines += `cat '#{file}' | wc -l`.to_i
|
|
107
|
+
end
|
|
108
|
+
@lines
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Count the characters.
|
|
112
|
+
#
|
|
113
|
+
# @return [Integer] characters amount
|
|
114
|
+
def chars
|
|
115
|
+
@chars = 0
|
|
116
|
+
@files.each do |file|
|
|
117
|
+
@chars += `cat '#{file}' | wc -m`.to_i
|
|
118
|
+
end
|
|
119
|
+
@chars
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
# Count the bytes. This *wont* be converted all the time.
|
|
123
|
+
#
|
|
124
|
+
# @return [Integer] bytes amount
|
|
125
|
+
def rawbytes
|
|
126
|
+
@rawbytes = 0
|
|
127
|
+
@files.each do |file|
|
|
128
|
+
@rawbytes += File.new("#{file}").size
|
|
129
|
+
end
|
|
130
|
+
@rawbytes
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# Count the bytes. This *will* be formatted into something like: 2898 KB
|
|
134
|
+
#
|
|
135
|
+
# @return [String] formatted bytes
|
|
136
|
+
def bytes
|
|
137
|
+
@bytes = nice_bytes rawbytes
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
data/lib/shepherd/db.rb
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
require "sqlite3"
|
|
2
|
+
|
|
3
|
+
module Shepherd
|
|
4
|
+
|
|
5
|
+
# A class through which you can connect to the database.
|
|
6
|
+
#
|
|
7
|
+
# == Usage
|
|
8
|
+
#
|
|
9
|
+
# module Shepherd
|
|
10
|
+
# Db.new.execute "sql query"
|
|
11
|
+
# end
|
|
12
|
+
#
|
|
13
|
+
# Inside a +Shepherd::Command::Klass+, it would look like:
|
|
14
|
+
#
|
|
15
|
+
# module Shepherd::Command
|
|
16
|
+
# class Klass
|
|
17
|
+
# def init
|
|
18
|
+
# Shepherd::Db.new.execute "sql query"
|
|
19
|
+
# end
|
|
20
|
+
# end
|
|
21
|
+
# end
|
|
22
|
+
#
|
|
23
|
+
# Here is {SQLite3 documantation}[http://sqlite-ruby.rubyforge.org/sqlite3/faq.html]. +Shepherd::Db.new+ is equal to +SQLite3::Database.new+ so there you've got a complete documentation.
|
|
24
|
+
#
|
|
25
|
+
class Db
|
|
26
|
+
|
|
27
|
+
# When the database file was not found
|
|
28
|
+
class DatabaseNotFound < RuntimeError; end
|
|
29
|
+
|
|
30
|
+
def initialize
|
|
31
|
+
raise DatabaseNotFound, "Error: database file not found: '#{Dir.home}/.shepherd/herd.db'\nTry running 'shep setup'." unless File.exists? "#{Dir.home}/.shepherd/herd.db"
|
|
32
|
+
# A new instance of +SQLite3::Database+
|
|
33
|
+
@db = SQLite3::Database.new "#{Dir.home}/.shepherd/herd.db"
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def method_missing m, *args, &block
|
|
37
|
+
@db.send m, *args, &block
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
data/lib/shepherd/version.rb
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
module Shepherd
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
module Version
|
|
3
|
+
MAJOR = 0
|
|
4
|
+
MINOR = 1
|
|
5
|
+
PATCH = 2
|
|
6
|
+
BUILD = nil
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
STRING = [MAJOR, MINOR, PATCH, BUILD].compact.join "."
|
|
9
|
+
end
|
|
10
10
|
end
|
data/lib/shepherd.rb
CHANGED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
module Shepherd
|
|
2
|
+
ROOT = File.expand_path(File.dirname(__FILE__))
|
|
3
|
+
|
|
4
|
+
autoload :Command, "#{ROOT}/shepherd/command"
|
|
5
|
+
autoload :Counter, "#{ROOT}/shepherd/counter"
|
|
6
|
+
autoload :Db, "#{ROOT}/shepherd/db"
|
|
7
|
+
autoload :Cli, "#{ROOT}/shepherd/cli"
|
|
8
|
+
autoload :Version, "#{ROOT}/shepherd/version"
|
|
9
|
+
end
|