alx 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ # alx
2
+
3
+ alx is *going to be* an easy to use command line application to handle text based documents
4
+
5
+
@@ -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
+
@@ -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,8 @@
1
+ Feature: A default configuration folder hierarchy has to be created
2
+ if it does not exist already.
3
+
4
+ Scenario: Creating default configuration
5
+ Given there is no configuration
6
+ When I start alx
7
+ Then the default configuration should be created
8
+
@@ -0,0 +1,8 @@
1
+ Feature: As a user
2
+ I would like to see meaningful help text
3
+ So that I can use the software easier
4
+
5
+ Scenario: Starting alx for help
6
+ When I start alx
7
+ Then I should be able to see a list of available commands
8
+
@@ -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,7 @@
1
+
2
+ Then /^I should be able to see a list of available commands$/ do
3
+ alx_commands.each do | command |
4
+ @output.should =~ /#{command}/
5
+ end
6
+ end
7
+
@@ -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
+
@@ -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
+
@@ -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
+