ruby-edit 0.1.0

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,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ruby_edit/command'
4
+
5
+ module RubyEdit
6
+ class ApplyPrompt < RubyEdit::Command
7
+ def continue?
8
+ prompt.yes?('Do you want to apply these changes?')
9
+ end
10
+ end
11
+ end
12
+
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'thor'
4
+
5
+ module RubyEdit
6
+ # Handle the application command line parsing
7
+ # and the dispatch to various command objects
8
+ #
9
+ # @api public
10
+ class CLI < Thor
11
+ # Error raised by this runner
12
+ Error = Class.new(StandardError)
13
+
14
+ desc 'version', 'ruby-edit version'
15
+ def version
16
+ require_relative 'version'
17
+ puts "v#{RubyEdit::VERSION}"
18
+ end
19
+ map %w[--version -v] => :version
20
+
21
+ desc 'grep', 'search for an expression in your directory'
22
+ method_option :help, aliases: '-h', type: :boolean, desc: 'Display usage information'
23
+ method_option :expression, aliases: %w[-e --expression], type: :string,
24
+ desc: 'the grep expression'
25
+ method_option :path, aliases: %w[-p --path], type: :string, desc: 'the path you want to search'
26
+ def grep(*)
27
+ if options[:help]
28
+ invoke :help, ['grep']
29
+ else
30
+ require_relative 'commands/grep'
31
+ RubyEdit::Commands::Grep.new(options).execute
32
+ end
33
+ end
34
+
35
+ map %w[--grep -g] => :grep
36
+
37
+ desc 'configure', 'set and read your settings'
38
+ method_option :help, aliases: '-h', type: :boolean, desc: 'Display useage information'
39
+ method_option :editor, aliases: %w[-e --editor], type: :string,
40
+ desc: 'Set or view your default text editor'
41
+ def configure(*)
42
+ if options[:help]
43
+ invoke :help, ['configure']
44
+ else
45
+ require_relative 'commands/configure'
46
+ RubyEdit::Commands::Configure.new(options).execute
47
+ end
48
+ end
49
+
50
+ map %w[--configure -c] => :configure
51
+
52
+ desc 'edit', '[Default] Perform a grep and edit the changes in one file'
53
+ method_option :help, aliases: '-h', type: :boolean, desc: 'Display usage information'
54
+ method_option :expression, aliases: %w[-e --expression], type: :string,
55
+ desc: 'the grep expression'
56
+ method_option :path, aliases: %w[-p --path], type: :string, desc: 'the path you want to search'
57
+
58
+ def edit(*)
59
+ if options[:help]
60
+ invoke :help, ['edit']
61
+ elsif options.empty?
62
+ invoke :help
63
+ else
64
+ require_relative 'commands/edit'
65
+ RubyEdit::Commands::Edit.new(options).execute
66
+ end
67
+ end
68
+
69
+ default_task :edit
70
+ end
71
+ end
72
+
@@ -0,0 +1,122 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'forwardable'
4
+
5
+ module RubyEdit
6
+ class Command
7
+ extend Forwardable
8
+
9
+ def_delegators :command, :run
10
+
11
+ # Execute this command
12
+ #
13
+ # @api public
14
+ def execute(*)
15
+ raise(
16
+ NotImplementedError,
17
+ "#{self.class}##{__method__} must be implemented"
18
+ )
19
+ end
20
+
21
+ # The external commands runner
22
+ #
23
+ # @see http://www.rubydoc.info/gems/tty-command
24
+ #
25
+ # @api public
26
+ def command(**options)
27
+ require 'tty-command'
28
+ TTY::Command.new(options)
29
+ end
30
+
31
+ # The cursor movement
32
+ #
33
+ # @see http://www.rubydoc.info/gems/tty-cursor
34
+ #
35
+ # @api public
36
+ def cursor
37
+ require 'tty-cursor'
38
+ TTY::Cursor
39
+ end
40
+
41
+ # Open a file or text in the user's preferred editor
42
+ #
43
+ # @see http://www.rubydoc.info/gems/tty-editor
44
+ #
45
+ # @api public
46
+ def editor
47
+ require 'tty-editor'
48
+ TTY::Editor
49
+ end
50
+
51
+ # File manipulation utility methods
52
+ #
53
+ # @see http://www.rubydoc.info/gems/tty-file
54
+ #
55
+ # @api public
56
+ def generator
57
+ require 'tty-file'
58
+ TTY::File
59
+ end
60
+
61
+ # Terminal output paging
62
+ #
63
+ # @see http://www.rubydoc.info/gems/tty-pager
64
+ #
65
+ # @api public
66
+ def pager(**options)
67
+ require 'tty-pager'
68
+ TTY::Pager.new(options)
69
+ end
70
+
71
+ # Terminal platform and OS properties
72
+ #
73
+ # @see http://www.rubydoc.info/gems/tty-pager
74
+ #
75
+ # @api public
76
+ def platform
77
+ require 'tty-platform'
78
+ TTY::Platform.new
79
+ end
80
+
81
+ # The interactive prompt
82
+ #
83
+ # @see http://www.rubydoc.info/gems/tty-prompt
84
+ #
85
+ # @api public
86
+ def prompt(**options)
87
+ require 'tty-prompt'
88
+ TTY::Prompt.new(options)
89
+ end
90
+
91
+ # Get terminal screen properties
92
+ #
93
+ # @see http://www.rubydoc.info/gems/tty-screen
94
+ #
95
+ # @api public
96
+ def screen
97
+ require 'tty-screen'
98
+ TTY::Screen
99
+ end
100
+
101
+ # The unix which utility
102
+ #
103
+ # @see http://www.rubydoc.info/gems/tty-which
104
+ #
105
+ # @api public
106
+ def which(*args)
107
+ require 'tty-which'
108
+ TTY::Which.which(*args)
109
+ end
110
+
111
+ # Check if executable exists
112
+ #
113
+ # @see http://www.rubydoc.info/gems/tty-which
114
+ #
115
+ # @api public
116
+ def exec_exist?(*args)
117
+ require 'tty-which'
118
+ TTY::Which.exist?(*args)
119
+ end
120
+ end
121
+ end
122
+
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ruby_edit'
4
+
5
+ module RubyEdit
6
+ module Commands
7
+ class Configure
8
+ def initialize(options)
9
+ @options = options
10
+ end
11
+
12
+ def execute(output: $stdout)
13
+ # This may need to be made dynamic if more configuration options are added
14
+ if editor == 'editor'
15
+ output.puts RubyEdit.config.editor
16
+ else
17
+ RubyEdit.config.editor = editor
18
+ output.puts "Editor changed to #{editor}"
19
+ end
20
+ end
21
+
22
+ private
23
+
24
+ def editor
25
+ @options[:editor]
26
+ end
27
+ end
28
+ end
29
+ end
30
+
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ruby_edit'
4
+ require 'ruby_edit/apply_prompt'
5
+ require 'ruby_edit/editor'
6
+ require 'ruby_edit/grep'
7
+ require 'ruby_edit/source_file'
8
+ require 'ruby_edit/writer'
9
+
10
+ module RubyEdit
11
+ module Commands
12
+ # TODO: Write an integration spec for this
13
+ class Edit
14
+ def initialize(options)
15
+ @grep = RubyEdit::Grep.new(options)
16
+ @sourcefile = RubyEdit::SourceFile.new
17
+ @editor = RubyEdit::Editor.new
18
+ @output = $stdout
19
+ @errors = $stderr
20
+ end
21
+
22
+ def execute
23
+ grep_search
24
+ populate_sourcefile
25
+ edit_file
26
+ apply_changes if apply_changes?
27
+ delete_sourcefile
28
+ end
29
+
30
+ private
31
+
32
+ def grep_search
33
+ @grep.search(output: @output, errors: @errors)
34
+ end
35
+
36
+ def populate_sourcefile
37
+ @sourcefile.populate(@grep.result.out)
38
+ end
39
+
40
+ def edit_file
41
+ @editor.edit_sourcefile
42
+ end
43
+
44
+ def apply_changes?
45
+ RubyEdit::ApplyPrompt.new.continue?
46
+ end
47
+
48
+ def apply_changes
49
+ RubyEdit::Writer.new.write
50
+ end
51
+
52
+ def delete_sourcefile
53
+ @sourcefile.delete
54
+ end
55
+ end
56
+ end
57
+ end
58
+
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ruby_edit/grep'
4
+
5
+ module RubyEdit
6
+ module Commands
7
+ class Grep
8
+ def initialize(options)
9
+ @options = options
10
+ @grep = RubyEdit::Grep.new(@options)
11
+ end
12
+
13
+ def execute(output: $stdout)
14
+ @result = @grep.search
15
+ output.puts 'OK'
16
+ end
17
+ end
18
+ end
19
+ end
20
+
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'tty/config'
4
+
5
+ module RubyEdit
6
+ class Configuration
7
+ LOCATION = File.expand_path('../../configuration', __dir__)
8
+
9
+ def initialize
10
+ @config = TTY::Config.new
11
+ @config.filename = LOCATION
12
+ @config.read("#{LOCATION}.yml")
13
+ end
14
+
15
+ def editor
16
+ @config.fetch(:editor).to_sym
17
+ end
18
+
19
+ def editor=(editor)
20
+ @config.set(:editor, value: editor.to_s)
21
+ write
22
+ end
23
+
24
+ def reset_defaults
25
+ @config.set(:editor, value: 'vim')
26
+ write
27
+ end
28
+
29
+ private
30
+
31
+ def write
32
+ @config.write
33
+ end
34
+ end
35
+ end
36
+
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ruby_edit/command'
4
+
5
+ module RubyEdit
6
+ class Editor < RubyEdit::Command
7
+ def initialize
8
+ @config = RubyEdit.config
9
+ end
10
+
11
+ def edit_sourcefile
12
+ editor.open RubyEdit::SOURCE_FILE_LOCATION, command: @config.editor
13
+ end
14
+ end
15
+ end
16
+
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ruby_edit/command'
4
+
5
+ module RubyEdit
6
+ class Grep < RubyEdit::Command
7
+ attr_reader :result
8
+
9
+ def initialize(options)
10
+ @path = options[:path] || '.'
11
+ @expression = options[:expression]
12
+ end
13
+
14
+ def search(output: $stdout, errors: $stderr)
15
+ if empty_expression?
16
+ output.puts 'No expression given'
17
+ return false
18
+ end
19
+ @result = run "grep -irn #{@path} -e '#{@expression}'" do |out, err|
20
+ output << out if out
21
+ errors << err if err
22
+ end
23
+ rescue TTY::Command::ExitError => error
24
+ output.puts error
25
+ end
26
+
27
+ private
28
+
29
+ def empty_expression?
30
+ @expression.nil? || @expression.empty?
31
+ end
32
+ end
33
+ end
34
+
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'ruby_edit/command'
4
+
5
+ module RubyEdit
6
+ class SourceFile < RubyEdit::Command
7
+ def populate(content)
8
+ generator.create_file(RubyEdit::SOURCE_FILE_LOCATION, content, force: true)
9
+ end
10
+
11
+ def delete
12
+ generator.remove_file(RubyEdit::SOURCE_FILE_LOCATION)
13
+ end
14
+ end
15
+ end
16
+
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyEdit
4
+ VERSION = '0.1.0'
5
+ end
6
+
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'fileutils'
4
+ require 'tempfile'
5
+ require 'ruby_edit/command'
6
+
7
+ module RubyEdit
8
+ class Writer < RubyEdit::Command
9
+ LINE_REGEX = /^.*\d+./
10
+
11
+ def write
12
+ File.open(RubyEdit::SOURCE_FILE_LOCATION, 'rb') do |file|
13
+ file.each_line { |line| find_and_replace_line line }
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def find_and_replace_line(new_line)
20
+ @temp_file = Tempfile.new('temp_file')
21
+ split_file_and_line(new_line)
22
+ @new_line = new_line.sub LINE_REGEX, ''
23
+ begin
24
+ replace_line
25
+ replace_file
26
+ ensure
27
+ @temp_file.close
28
+ @temp_file.unlink
29
+ end
30
+ end
31
+
32
+ def split_file_and_line(line)
33
+ @file_name, @line_number = line.match(LINE_REGEX)[0].split(':')
34
+ rescue NoMethodError
35
+ false
36
+ end
37
+
38
+ # Replaces the line in the original file, with the line from the sourcefile
39
+ def replace_line
40
+ File.open(@file_name, 'r+') do |file|
41
+ file.each_with_index do |line, index|
42
+ output = index + 1 == @line_number.to_i ? @new_line : line
43
+ @temp_file.puts output
44
+ end
45
+ end
46
+ end
47
+
48
+ # Replaces the old file, with the new edited file
49
+ def replace_file
50
+ @temp_file.close
51
+ FileUtils.mv(@temp_file.path, @file_name)
52
+ end
53
+ end
54
+ end
55
+