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.
@@ -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
+