alx 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
|