alx 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +23 -0
- data/.simplecov +5 -0
- data/COPYING +20 -0
- data/Gemfile +4 -0
- data/LICENSE +674 -0
- data/README.md +5 -0
- data/Rakefile +16 -0
- data/alx.gemspec +24 -0
- data/bin/alx +14 -0
- data/features/add_books.feature +15 -0
- data/features/create_default_configuration.feature +8 -0
- data/features/give_meaningful_help.feature +8 -0
- data/features/remove_book.feature +17 -0
- data/features/step_definitions/alx_base_steps.rb +36 -0
- data/features/step_definitions/alx_configuration_steps.rb +19 -0
- data/features/step_definitions/alx_help_steps.rb +7 -0
- data/features/support/alx_extensions.rb +67 -0
- data/features/support/env.rb +27 -0
- data/lib/alx/add_handler.rb +25 -0
- data/lib/alx/book.rb +20 -0
- data/lib/alx/configuration.rb +51 -0
- data/lib/alx/controller.rb +43 -0
- data/lib/alx/editor.rb +33 -0
- data/lib/alx/executer.rb +13 -0
- data/lib/alx/handler.rb +62 -0
- data/lib/alx/help_handler.rb +39 -0
- data/lib/alx/library.rb +27 -0
- data/lib/alx/list_handler.rb +22 -0
- data/lib/alx/remove_handler.rb +36 -0
- data/lib/alx/renderer.rb +39 -0
- data/lib/alx/show_handler.rb +32 -0
- data/lib/alx/version.rb +3 -0
- data/lib/alx/viewer.rb +32 -0
- data/test/tc_book.rb +23 -0
- data/test/tc_controller.rb +37 -0
- data/test/tc_editor.rb +42 -0
- data/test/tc_library.rb +33 -0
- data/test/tc_list_handler.rb +48 -0
- data/test/tc_renderer.rb +41 -0
- data/test/tc_viewer.rb +58 -0
- data/test/test_helper.rb +69 -0
- metadata +168 -0
data/README.md
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'cucumber'
|
2
|
+
require 'cucumber/rake/task'
|
3
|
+
require 'rake/testtask'
|
4
|
+
require 'bundler'
|
5
|
+
Bundler::GemHelper.install_tasks
|
6
|
+
|
7
|
+
Cucumber::Rake::Task.new( :ft ) do | t |
|
8
|
+
t.cucumber_opts = "features --format pretty -x"
|
9
|
+
t.fork = false
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
Rake::TestTask.new( "ut" ) do | test |
|
14
|
+
test.test_files = FileList['test/tc_*.rb']
|
15
|
+
end
|
16
|
+
|
data/alx.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'alx/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "alx"
|
8
|
+
gem.version = Alx::VERSION
|
9
|
+
gem.authors = ["Peter Hajdu"]
|
10
|
+
gem.email = ["peter.ferenc.hajdu@gmail.com"]
|
11
|
+
gem.description = %q{Command line tool to manage your markdown documents. ( beta )}
|
12
|
+
gem.summary = %q{An easy to use command line text document manager. ( beta )}
|
13
|
+
gem.homepage = "http://github.com/PeterHajdu/alx"
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ["lib"]
|
19
|
+
|
20
|
+
gem.add_dependency( 'redcarpet' )
|
21
|
+
gem.add_development_dependency( 'cucumber' )
|
22
|
+
gem.add_development_dependency( 'rspec' )
|
23
|
+
gem.add_development_dependency( 'simplecov' )
|
24
|
+
end
|
data/bin/alx
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
require 'alx/configuration'
|
4
|
+
require 'alx/controller'
|
5
|
+
|
6
|
+
begin
|
7
|
+
configuration = Alx::Configuration.new
|
8
|
+
control = Alx::Controller.new( configuration.hash )
|
9
|
+
control.run()
|
10
|
+
rescue => exception
|
11
|
+
puts exception.message
|
12
|
+
exit 1
|
13
|
+
end
|
14
|
+
|
@@ -0,0 +1,15 @@
|
|
1
|
+
Feature: As a user
|
2
|
+
I would like to add books to the library
|
3
|
+
So that I can read them later
|
4
|
+
|
5
|
+
Scenario: Adding books to the library.
|
6
|
+
Given an empty library
|
7
|
+
When I add the following books
|
8
|
+
| first howto | text 1 |
|
9
|
+
| second howto | text 2 |
|
10
|
+
| and some more | text 3 |
|
11
|
+
Then I should be able to retrieve the following books
|
12
|
+
| first howto | text 1 |
|
13
|
+
| second howto | text 2 |
|
14
|
+
| and some more | text 3 |
|
15
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
Feature: As a user
|
2
|
+
I would like to remove books from the library
|
3
|
+
|
4
|
+
Scenario: Removing books from the library.
|
5
|
+
Given I add the following books
|
6
|
+
| first howto | text 1 |
|
7
|
+
| second howto | text 2 |
|
8
|
+
| and some more | text 3 |
|
9
|
+
When I remove the following books
|
10
|
+
| first howto |
|
11
|
+
| second howto |
|
12
|
+
Then I should not be able to retrieve the following books
|
13
|
+
| first howto |
|
14
|
+
| second howto |
|
15
|
+
But I should be able to retrieve the following books
|
16
|
+
| and some more | text 3 |
|
17
|
+
|
@@ -0,0 +1,36 @@
|
|
1
|
+
Given /^an empty library$/ do
|
2
|
+
cleanup_home
|
3
|
+
end
|
4
|
+
|
5
|
+
|
6
|
+
When /^I add the following books$/ do | books |
|
7
|
+
books.raw.each do | title, content |
|
8
|
+
ENV['EDITOR'] = "echo #{content} >"
|
9
|
+
add( title )
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
|
14
|
+
Then /^I should be able to retrieve the following books$/ do | books |
|
15
|
+
list
|
16
|
+
list_output = @output
|
17
|
+
books.raw.each do | title, content |
|
18
|
+
list_output.should =~ /#{title}/
|
19
|
+
show( title )
|
20
|
+
@output.should =~ /#{content}/
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
When /^I remove the following books$/ do | books |
|
25
|
+
books.raw.each do | title |
|
26
|
+
remove( title[ 0 ] )
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
Then /^I should not be able to retrieve the following books$/ do | books |
|
31
|
+
list
|
32
|
+
books.raw.each do | title |
|
33
|
+
@output.should_not =~ /#{title[ 0 ]}/
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
|
3
|
+
Given /^there is no configuration$/ do
|
4
|
+
cleanup_home
|
5
|
+
end
|
6
|
+
|
7
|
+
|
8
|
+
When /^I start alx$/ do
|
9
|
+
alx( "", false )
|
10
|
+
end
|
11
|
+
|
12
|
+
|
13
|
+
Then /^the default configuration should be created$/ do
|
14
|
+
check_directory_presence( lib_dir, true )
|
15
|
+
check_file_presence( conf_file, true )
|
16
|
+
conf = YAML.load_file( conf_file )
|
17
|
+
conf.should == Alx::DEFAULT_CONFIG
|
18
|
+
end
|
19
|
+
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'alx/controller'
|
2
|
+
require 'alx/configuration'
|
3
|
+
|
4
|
+
module AlxHelpers
|
5
|
+
|
6
|
+
def add( rest = "", success = true )
|
7
|
+
alx( "add " + rest, success )
|
8
|
+
end
|
9
|
+
|
10
|
+
def remove( rest = "", success = true )
|
11
|
+
alx( "remove " + rest, success )
|
12
|
+
end
|
13
|
+
|
14
|
+
def list( rest = "", success = true )
|
15
|
+
alx( "list " + rest, success )
|
16
|
+
end
|
17
|
+
|
18
|
+
def show( rest = "", success = true )
|
19
|
+
alx( "show -o " + rest, success )
|
20
|
+
end
|
21
|
+
|
22
|
+
def export( rest = [], success = true )
|
23
|
+
alx( "export " + rest.join( "," ), success )
|
24
|
+
end
|
25
|
+
|
26
|
+
def alx( rest, success_expected )
|
27
|
+
pipe = IO.popen( "bin/alx #{rest}" )
|
28
|
+
Process.wait
|
29
|
+
@output = pipe.readlines.join( "" )
|
30
|
+
was_success.should == success_expected
|
31
|
+
end
|
32
|
+
|
33
|
+
def was_success
|
34
|
+
$?.exitstatus == 0
|
35
|
+
end
|
36
|
+
|
37
|
+
def check_file_presence( path, expected )
|
38
|
+
File.exists?( path ).should == expected
|
39
|
+
end
|
40
|
+
|
41
|
+
def check_directory_presence( path, expected )
|
42
|
+
File.directory?( path ).should == expected
|
43
|
+
end
|
44
|
+
|
45
|
+
def alx_commands
|
46
|
+
Alx::Controller.new( {} ).handlers.keys
|
47
|
+
end
|
48
|
+
|
49
|
+
def conf_dir
|
50
|
+
"/tmp/fake_home/#{Alx::CONF_BASE_DIR}"
|
51
|
+
end
|
52
|
+
|
53
|
+
def conf_file
|
54
|
+
conf_dir + "/#{Alx::CONF_FILE}"
|
55
|
+
end
|
56
|
+
|
57
|
+
def lib_dir
|
58
|
+
conf_dir + "/#{Alx::LIB_BASE_DIR}/#{Alx::DEFAULT_SHELF}"
|
59
|
+
end
|
60
|
+
|
61
|
+
def cleanup_home
|
62
|
+
FileUtils.rm_rf( conf_dir, :secure => true )
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
World( AlxHelpers )
|
67
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
|
3
|
+
LIB_DIR = File.join( File.expand_path( File.dirname( __FILE__ ) ), '..', '..', 'lib' )
|
4
|
+
|
5
|
+
Before do
|
6
|
+
@real_home = ENV['HOME']
|
7
|
+
fake_home = File.join( '/tmp/', 'fake_home' )
|
8
|
+
FileUtils.rm_rf( fake_home, :secure => true )
|
9
|
+
FileUtils.mkdir( fake_home )
|
10
|
+
ENV['HOME'] = fake_home
|
11
|
+
|
12
|
+
@original_editor = ENV['EDITOR']
|
13
|
+
|
14
|
+
spec = Gem::Specification.find_by_name( 'redcarpet' )
|
15
|
+
gem_root = spec.gem_dir
|
16
|
+
gem_lib = gem_root + "/" + spec.require_paths[0]
|
17
|
+
|
18
|
+
@original_rubylib = ENV['RUBYLIB']
|
19
|
+
ENV['RUBYLIB'] = LIB_DIR + File::PATH_SEPARATOR + ENV['RUBYLIB'].to_s + File::PATH_SEPARATOR + gem_lib
|
20
|
+
end
|
21
|
+
|
22
|
+
After do
|
23
|
+
ENV['HOME'] = @real_home
|
24
|
+
ENV['RUBYLIB'] = @original_rubylib
|
25
|
+
ENV['EDITOR'] = @original_editor;
|
26
|
+
end
|
27
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'alx/handler'
|
2
|
+
require 'alx/editor'
|
3
|
+
|
4
|
+
module Alx
|
5
|
+
|
6
|
+
class AddHandler < Handler
|
7
|
+
def initialize( configuration )
|
8
|
+
super(
|
9
|
+
:configuration => configuration,
|
10
|
+
:command => 'add',
|
11
|
+
:rest_description => 'book title',
|
12
|
+
:description => "Adds new book to the library.",
|
13
|
+
:options => [ :editor, :stdin ] )
|
14
|
+
end
|
15
|
+
|
16
|
+
def handle
|
17
|
+
parse_options
|
18
|
+
options_error( "No file name given. Please provide one." ) if @conf[ :rest ].empty?
|
19
|
+
book_file_name = @conf[ :default_shelf_dir ] + "/" +@conf[ :rest ].gsub( / /, "_" )
|
20
|
+
Editor.new( @conf ).edit( book_file_name )
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
|
data/lib/alx/book.rb
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
module Alx
|
2
|
+
|
3
|
+
class Book
|
4
|
+
attr_reader :title, :file_name
|
5
|
+
def initialize( title, file_name )
|
6
|
+
@title = title
|
7
|
+
@file_name = file_name
|
8
|
+
end
|
9
|
+
|
10
|
+
def content
|
11
|
+
content = ""
|
12
|
+
File.open( @file_name ) do | file |
|
13
|
+
file.each { | line | content+=line }
|
14
|
+
end
|
15
|
+
return content
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'yaml'
|
3
|
+
|
4
|
+
module Alx
|
5
|
+
|
6
|
+
CONF_BASE_DIR=".alx"
|
7
|
+
CONF_FILE="conf"
|
8
|
+
LIB_BASE_DIR="library"
|
9
|
+
DEFAULT_SHELF="home"
|
10
|
+
|
11
|
+
DEFAULT_CONFIG = {
|
12
|
+
:editor => 'vim',
|
13
|
+
:html_viewer => 'elinks',
|
14
|
+
:terminal_viewer => 'less -R',
|
15
|
+
}
|
16
|
+
|
17
|
+
class Configuration
|
18
|
+
|
19
|
+
def initialize
|
20
|
+
@conf = {}
|
21
|
+
@conf[ :alx_home ] = ENV[ 'HOME' ] + "/#{CONF_BASE_DIR}"
|
22
|
+
@conf[ :conf_file ] = @conf[ :alx_home ] + "/#{CONF_FILE}"
|
23
|
+
@conf[ :default_shelf_dir ] = @conf[ :alx_home ] + "/#{LIB_BASE_DIR}/#{DEFAULT_SHELF}"
|
24
|
+
|
25
|
+
FileUtils::mkdir_p( @conf[ :default_shelf_dir ] )
|
26
|
+
create_default_config_if_needed( @conf[ :conf_file ] )
|
27
|
+
from_conf_file = load_config( @conf[ :conf_file ] )
|
28
|
+
@conf.merge!( from_conf_file )
|
29
|
+
|
30
|
+
@conf[ :editor ] = ENV[ 'EDITOR' ] if ENV[ 'EDITOR' ]
|
31
|
+
@conf[ :command ] = ARGV[ 0 ]
|
32
|
+
@conf[ :rest ] = ARGV[ 1..-1 ]
|
33
|
+
end
|
34
|
+
|
35
|
+
def hash
|
36
|
+
@conf
|
37
|
+
end
|
38
|
+
|
39
|
+
protected
|
40
|
+
def create_default_config_if_needed( file_name )
|
41
|
+
return if File.exist?( file_name )
|
42
|
+
File.open( file_name, "w" ) { | file | YAML.dump( DEFAULT_CONFIG, file ) }
|
43
|
+
end
|
44
|
+
|
45
|
+
def load_config( file_name )
|
46
|
+
YAML.load_file( file_name )
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end
|
51
|
+
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'alx/add_handler'
|
2
|
+
require 'alx/list_handler'
|
3
|
+
require 'alx/show_handler'
|
4
|
+
require 'alx/help_handler'
|
5
|
+
require 'alx/remove_handler'
|
6
|
+
|
7
|
+
module Alx
|
8
|
+
|
9
|
+
class Controller
|
10
|
+
attr_reader :handlers
|
11
|
+
|
12
|
+
def initialize( configuration )
|
13
|
+
@conf = configuration
|
14
|
+
@handlers = {}
|
15
|
+
register_handlers
|
16
|
+
end
|
17
|
+
|
18
|
+
def run
|
19
|
+
command = @conf[ :command ]
|
20
|
+
if @handlers[ command ]
|
21
|
+
@handlers[ command ].handle
|
22
|
+
else
|
23
|
+
@handlers[ 'help' ].handle
|
24
|
+
raise "I don't understand command: #{command}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
def register_handlers
|
30
|
+
add_handler( AddHandler.new( @conf ) )
|
31
|
+
add_handler( ListHandler.new( @conf ) )
|
32
|
+
add_handler( ShowHandler.new( @conf ) )
|
33
|
+
add_handler( RemoveHandler.new( @conf ) )
|
34
|
+
add_handler( HelpHandler.new( @conf, self ) )
|
35
|
+
end
|
36
|
+
|
37
|
+
def add_handler( handler )
|
38
|
+
@handlers[ handler.command_name ] = handler
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
data/lib/alx/editor.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'alx/executer'
|
2
|
+
|
3
|
+
module Alx
|
4
|
+
|
5
|
+
class Editor
|
6
|
+
include Executer
|
7
|
+
|
8
|
+
def initialize( conf )
|
9
|
+
@conf = conf
|
10
|
+
end
|
11
|
+
|
12
|
+
def edit( file_name )
|
13
|
+
@editor_command = @conf[ :editor ]
|
14
|
+
@editor_command ? use_editor( file_name ) : use_stdin( file_name )
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
def use_editor( file_name )
|
19
|
+
start( "#{@editor_command} #{file_name}")
|
20
|
+
end
|
21
|
+
|
22
|
+
def use_stdin( file_name )
|
23
|
+
puts( 'Reading input from standard input.' )
|
24
|
+
File.open( file_name, "a" ) do | file |
|
25
|
+
while line = $stdin.gets
|
26
|
+
file.puts( line )
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|