Class: TerseRuby::Scan

Inherits:
Object
  • Object
show all
Defined in:
lib/terse_ruby/scan.rb

Overview

This Scan class does the meat of the work TODO generate to_s, ==, initialize

Class Method Summary collapse

Class Method Details

.gen_new_filename(f) ⇒ Object

Rules : Keep base-name, change ext. to .rb, write to current working dir



130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/terse_ruby/scan.rb', line 130

def self.gen_new_filename f
    path = Dir.getwd
    name = File.basename_no_ext f
    ext = ".rb"
    new_f = File.join(path, name) + ext

    if File.file?(new_f)
        puts "New file wll overwrite existing file " + new_f
        raise "Overwrite flag not specified; will not overwrite existing file " + new_f if !@overwrite
    end
    new_f
end

.is_file?(f) ⇒ Boolean

Returns:

  • (Boolean)


124
125
126
# File 'lib/terse_ruby/scan.rb', line 124

def self.is_file? f
    raise "Could not locate file at " + File.absolute_path(f) unless File.file?(f)
end

.plural_or_not(item) ⇒ Object

Returns an “s” string if the size of the item (item.size) is > 1; returns “” otherwise



120
121
122
# File 'lib/terse_ruby/scan.rb', line 120

def self.plural_or_not item
    item.size == 1 ? "" : "s"
end

.pv(s) ⇒ Object



143
144
145
# File 'lib/terse_ruby/scan.rb', line 143

def self.pv s
    puts s if @verbose
end

.scan_files(argv) ⇒ Object

The main method. ARGV from the invokation are passed in to here



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/terse_ruby/scan.rb', line 12

def self.scan_files(argv)
    puts "\nTerse Ruby called"

    keywords = TerseRuby::Keyword.generate_keywords
    flags = argv.options
    @verbose = flags.include_any?("v", "verbose")
    @overwrite = flags.include_any?("o", "overwrite", "w", "write")
    @no_formatting = flags.include_any?("n", "noformatting")

    files = argv.values

    if files.size < 1
        puts "No files supplied"
    else
        files.each do |f|
            is_file? f
        end
        pv "Will scan #{files.size} file#{plural_or_not files}"
        files.each do |f|
            is_file? f
            filename = File.basename f
            new_filename = gen_new_filename f
            newlines = []
            lines = File.readlines f
            pv "File #{filename} has #{lines.size} line#{plural_or_not lines}"
            # If we detect the start of a new class/method/etc. before the last one has been closed
            # then insert an "end" to close it off
            needs_top_level_end = false
            needs_inner_end = false
            insert_end = false
            lines.each do |l|
                line = l.chomp
                newline = line # keep the orginial line unless we detect a match 
                keywords.each do |k|
                    if line =~ k.regex
                        pv "\nMatch found against line --> #{line}"            
                        pv "Matched -------------------> " + $2
                        if k.is_end
                            if needs_inner_end
                                needs_inner_end = false
                            elsif needs_top_level_end
                                needs_top_level_end = false
                            end
                            insert_end = false
                        end
                        
                        if k.needs_inner_end
                            if needs_inner_end
                                newlines << "end"
                                # keep needs_inner_end true as we need to watch for an end for this new match
                            else
                                needs_inner_end = true # set in readiness for the next match
                            end
                        end
                        
                        if k.needs_top_level_end
                            if needs_inner_end
                                newlines << "end"
                                needs_inner_end = false
                            end
                            if needs_top_level_end
                                newlines << "end"
                                # keep needs_top_level_end true as we need to watch for an end for this new match
                            else
                                needs_top_level_end = true # set in readiness for the next match
                            end
                        end
                        
                        if k.try_follow_on_regex && line =~ k.follow_on_regex
                            # puts ""
                            # $& is the entire match, not just the bits in ( )
                            remainder = line[$&.size .. -1]
                            follow_on = (eval k.follow_on_substitute).inspect
                            newline = "#{$1}#{k.substitute} #{follow_on}#{remainder}"
                        else
                            remainder = line[($1.size + $2.size) .. -1]
                            newline = "#{$1}#{k.substitute}#{remainder}"
                        end
                        
                        pv "Line will become ----------> " + newline
                        break
                    end # end if regex        
                end # end keywords.each
                newlines << newline
            end # end lines.each
            # Add end lines to end of file if necessary
            newlines << "end" if needs_inner_end
            newlines << "end" if needs_top_level_end
            
            # Apply indentation
            newlines = TerseRuby::Format.indent(newlines) unless @no_formatting
            
            # Add newlines between the end of a method and the start of the next, if needed 
            newlines = TerseRuby::Format.space_lines(newlines) unless @no_formatting
            
            # Write out the new file
            File.open(new_filename, "w") do |new_f|
                newlines.each do |l|
                    new_f.puts l
                end
            end
            puts "\nWrote file #{new_filename}"
        end # end else
    end # end ARGV.size
    puts "\nTerse Ruby finished"
end