yay 0.0.5 → 0.0.6
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/lib/yay/application.rb +24 -6
- data/lib/yay/colour_wheel.rb +71 -57
- data/lib/yay/colourizer.rb +22 -4
- data/lib/yay/errors.rb +76 -16
- data/lib/yay/installer.rb +126 -3
- data/lib/yay/lexer.rb +9 -4
- data/lib/yay/lexer_regex.rb +3 -0
- data/lib/yay/lister.rb +59 -0
- data/lib/yay/loader.rb +2 -0
- data/lib/yay/parser.rb +146 -121
- data/lib/yay/parser_gen.rb +20 -18
- data/lib/yay/paths.rb +9 -5
- data/lib/yay/rule_set.rb +3 -1
- data/lib/yay/version.rb +15 -12
- metadata +15 -14
data/lib/yay/application.rb
CHANGED
|
@@ -3,6 +3,8 @@ require 'yay/colourizer'
|
|
|
3
3
|
require 'yay/version'
|
|
4
4
|
|
|
5
5
|
class Yay
|
|
6
|
+
# this class acts as controller for yay. it interprets user input and
|
|
7
|
+
# coordinates with the parser
|
|
6
8
|
class Application
|
|
7
9
|
|
|
8
10
|
# arg that can be used if you don't want the application to do anything
|
|
@@ -14,11 +16,12 @@ class Yay
|
|
|
14
16
|
# arg that can be used to dump the version and exit
|
|
15
17
|
SHOW_VERSION_ARG = '--version'
|
|
16
18
|
|
|
19
|
+
# create an application with all the necessary user context
|
|
17
20
|
def initialize(input, output, error, args)
|
|
18
|
-
raise ArgumentError, "input"
|
|
21
|
+
raise ArgumentError, "input" unless input.kind_of? IO
|
|
19
22
|
raise ArgumentError, "output" unless output.kind_of? IO
|
|
20
|
-
raise ArgumentError, "error"
|
|
21
|
-
raise ArgumentError, "args"
|
|
23
|
+
raise ArgumentError, "error" unless error.kind_of? IO
|
|
24
|
+
raise ArgumentError, "args" unless args.kind_of? Array
|
|
22
25
|
|
|
23
26
|
@input = input
|
|
24
27
|
@output = output
|
|
@@ -27,6 +30,7 @@ class Yay
|
|
|
27
30
|
@running = false
|
|
28
31
|
end
|
|
29
32
|
|
|
33
|
+
# run the application. when this ends, termination is expected
|
|
30
34
|
def run
|
|
31
35
|
raise "already running" if @running
|
|
32
36
|
@running = true
|
|
@@ -44,26 +48,40 @@ class Yay
|
|
|
44
48
|
return if preArg == DO_NOTHING_ARG
|
|
45
49
|
|
|
46
50
|
begin
|
|
47
|
-
|
|
51
|
+
|
|
48
52
|
@parser = Yay::Parser.new
|
|
49
53
|
@parser.allow_all = true
|
|
50
54
|
@parser.parse_array(@args)
|
|
51
55
|
@rules = @parser.get_rules
|
|
52
56
|
|
|
57
|
+
# the parser may instruct us to shut down
|
|
58
|
+
if @parser.shutdown
|
|
59
|
+
return
|
|
60
|
+
end
|
|
61
|
+
|
|
53
62
|
@colourizer = Yay::Colourizer.new @rules, @input, @output
|
|
54
|
-
|
|
63
|
+
|
|
55
64
|
if preArg == DUMP_RULES_ARG
|
|
56
65
|
dump_colours @colourizer.line_rules, @colourizer.part_rules
|
|
57
66
|
return
|
|
58
67
|
end
|
|
59
68
|
|
|
60
69
|
@colourizer.colourize_pipe
|
|
70
|
+
|
|
71
|
+
# provide readable text for internal errors
|
|
61
72
|
rescue Yay::Error => error
|
|
62
|
-
@error.puts error.printable_message
|
|
73
|
+
@error.puts "#{ColourWheel::fail}#{error.printable_message}#{ColourWheel::end_colour}"
|
|
74
|
+
|
|
75
|
+
# catch ctrl+c and similar events
|
|
63
76
|
rescue Interrupt
|
|
64
77
|
end
|
|
78
|
+
|
|
79
|
+
# emit the end colour just in case we were interrupted
|
|
80
|
+
print ColourWheel.end_colour
|
|
65
81
|
end
|
|
66
82
|
|
|
83
|
+
# with the --dump command we can see the resulting rules created by the
|
|
84
|
+
# rule definitions (from all files included too)
|
|
67
85
|
def dump_colours line_rules, word_rules
|
|
68
86
|
|
|
69
87
|
puts "line rules:" if line_rules
|
data/lib/yay/colour_wheel.rb
CHANGED
|
@@ -1,58 +1,72 @@
|
|
|
1
|
-
# To change this template, choose Tools | Templates
|
|
2
|
-
# and open the template in the editor.
|
|
3
|
-
|
|
4
1
|
class Yay
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
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
|
-
|
|
2
|
+
# the colour wheel contains all the constants needed to create coloured text
|
|
3
|
+
# there are also a few static helper methods to make rendering text easier
|
|
4
|
+
class ColourWheel
|
|
5
|
+
|
|
6
|
+
# commands. support varies
|
|
7
|
+
MISC = {
|
|
8
|
+
:reset => 0,
|
|
9
|
+
:bright => 1,
|
|
10
|
+
:dim => 2,
|
|
11
|
+
:underscore => 4,
|
|
12
|
+
:blink => 5,
|
|
13
|
+
:reverse => 7,
|
|
14
|
+
:hidden => 8,
|
|
15
|
+
|
|
16
|
+
:normal => 0, #alias
|
|
17
|
+
:invert => 7, #alias
|
|
18
|
+
:inverted => 7, #alias
|
|
19
|
+
:underscored => 4, #alias
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
# foreground colours
|
|
23
|
+
FG = {
|
|
24
|
+
:black => 30,
|
|
25
|
+
:red => 31,
|
|
26
|
+
:green => 32,
|
|
27
|
+
:yellow => 33,
|
|
28
|
+
:blue => 34,
|
|
29
|
+
:magenta => 35,
|
|
30
|
+
:cyan => 36,
|
|
31
|
+
:white => 37,
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
# background colours
|
|
35
|
+
BG = {
|
|
36
|
+
:black => 40,
|
|
37
|
+
:red => 41,
|
|
38
|
+
:green => 42,
|
|
39
|
+
:yellow => 43,
|
|
40
|
+
:blue => 44,
|
|
41
|
+
:magenta => 45,
|
|
42
|
+
:cyan => 46,
|
|
43
|
+
:white => 47
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
# return all the possible colour names
|
|
47
|
+
# the keys are used as string representations by the parser
|
|
48
|
+
def self.all_names
|
|
49
|
+
# assume BG and FG have the same keys
|
|
50
|
+
MISC.keys | FG.keys
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# ge the string that begins the current colour code
|
|
54
|
+
def self.begin_colours(colour_numbers)
|
|
55
|
+
"\033[#{colour_numbers.join(';')}m"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# the command necessary to stop printing with colour
|
|
59
|
+
def self.end_colour
|
|
60
|
+
"\033[0m"
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# ge the string that begins the current colour code
|
|
64
|
+
def self.success
|
|
65
|
+
self.begin_colours([FG[:green]])
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def self.fail()
|
|
69
|
+
self.begin_colours([FG[:red]])
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
data/lib/yay/colourizer.rb
CHANGED
|
@@ -1,21 +1,32 @@
|
|
|
1
1
|
require 'yay/colour_wheel'
|
|
2
2
|
|
|
3
3
|
class Yay
|
|
4
|
+
# this class adds colour to a stream based on rules that have been generated
|
|
5
|
+
# by a parser
|
|
4
6
|
class Colourizer
|
|
7
|
+
# create a colourizer using specified parser rules and input and output
|
|
8
|
+
# streams (usually stdin/stdout)
|
|
5
9
|
def initialize rules, input, output
|
|
6
10
|
colourize_rules rules
|
|
7
11
|
@input = input
|
|
8
12
|
@output = output
|
|
9
13
|
end
|
|
10
14
|
|
|
15
|
+
# get the rules that are applied to a whole line if it contains matching text
|
|
16
|
+
# of the form [[regex, colour_string],..]
|
|
11
17
|
def line_rules
|
|
12
18
|
@line_rules
|
|
13
19
|
end
|
|
14
20
|
|
|
21
|
+
# get the rules that are applied to matching text
|
|
22
|
+
# of the form [[regex, colour_string],..]
|
|
15
23
|
def part_rules
|
|
16
24
|
@part_rules
|
|
17
25
|
end
|
|
18
26
|
|
|
27
|
+
# process the rules created by a parser and determine the actual strings we
|
|
28
|
+
# need to emit when we use this colour. this breaks parser rules up in to
|
|
29
|
+
# two categories - line rules and part rules
|
|
19
30
|
def colourize_rules rules
|
|
20
31
|
@line_rules = []
|
|
21
32
|
@part_rules = []
|
|
@@ -36,25 +47,32 @@ class Yay
|
|
|
36
47
|
}
|
|
37
48
|
end
|
|
38
49
|
|
|
50
|
+
# create a pipe between the input and output streams, applying colour rules
|
|
51
|
+
# to every line that appears. only an interrupt, end of file or exception
|
|
52
|
+
# will end this process
|
|
39
53
|
def colourize_pipe
|
|
54
|
+
# this is the colour we'll use when we haven't already applied a colour
|
|
55
|
+
# we remember the previous colour as we can colourize words within a line
|
|
56
|
+
# that's already been coloured
|
|
40
57
|
default_end_colour = ColourWheel::end_colour
|
|
41
58
|
|
|
42
59
|
@input.each_line { |line|
|
|
43
60
|
|
|
44
|
-
# track the line_rules end colour so we can return to this after each
|
|
61
|
+
# track the line_rules end colour so we can return to this after each
|
|
62
|
+
# match
|
|
45
63
|
end_colour = default_end_colour
|
|
46
64
|
|
|
47
|
-
#
|
|
65
|
+
# apply all line rules
|
|
48
66
|
@line_rules.each { |rule|
|
|
49
67
|
if line.match(rule[0])
|
|
50
68
|
line = "#{rule[1]}#{line.rstrip}#{default_end_colour}"
|
|
51
69
|
end_colour = rule[1]
|
|
52
|
-
# only allow one line
|
|
70
|
+
# leave loop; only allow one line match per line
|
|
53
71
|
break
|
|
54
72
|
end
|
|
55
73
|
}
|
|
56
74
|
|
|
57
|
-
#
|
|
75
|
+
# apply all partial rules
|
|
58
76
|
@part_rules.each { |rule|
|
|
59
77
|
line.gsub!(rule[0], "#{rule[1]}\\0#{end_colour}")
|
|
60
78
|
}
|
data/lib/yay/errors.rb
CHANGED
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
|
|
2
2
|
class Yay
|
|
3
|
+
# the base class for errors in yay. this provides error reporting in a
|
|
4
|
+
# friendly way (who likes stack traces?)
|
|
3
5
|
class Error < StandardError
|
|
4
|
-
|
|
6
|
+
attr_reader :position
|
|
5
7
|
|
|
8
|
+
# override this to provide user feedback
|
|
6
9
|
def printable_message
|
|
7
10
|
raise "Unimplemented printable error"
|
|
8
11
|
end
|
|
9
12
|
|
|
13
|
+
# a generic representation of the error's location on the line, file, etc
|
|
10
14
|
def printable_position
|
|
11
15
|
array = @position
|
|
12
16
|
return "" unless @position
|
|
13
|
-
length = array.length
|
|
14
17
|
return " in file #{array[2]}, line #{array[1]}, word #{array[0]}" if array[2]
|
|
15
18
|
return " on line #{array[1]}, word #{array[0]}" if array[1]
|
|
16
19
|
return " at word #{array[0]}" if array[0]
|
|
@@ -18,8 +21,47 @@ class Yay
|
|
|
18
21
|
end
|
|
19
22
|
end
|
|
20
23
|
|
|
24
|
+
# thrown when an invalid filename was entered
|
|
25
|
+
class BadFilenameError < Error
|
|
26
|
+
attr_reader :value
|
|
27
|
+
attr_reader :message
|
|
28
|
+
|
|
29
|
+
def initialize value
|
|
30
|
+
@value = value
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def printable_message
|
|
34
|
+
return "Invalid filename #{value} entered"
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# this error wraps an underlying error
|
|
39
|
+
class InstallFailedError < Error
|
|
40
|
+
MAX_LENGTH = 1028
|
|
41
|
+
|
|
42
|
+
attr_reader :error
|
|
43
|
+
attr_reader :url
|
|
44
|
+
attr_reader :content
|
|
45
|
+
|
|
46
|
+
def initialize url, error, content=nil
|
|
47
|
+
@url = url
|
|
48
|
+
@error = error
|
|
49
|
+
@content = content
|
|
50
|
+
@content = 'empty' if (content==nil||content.strip=="")
|
|
51
|
+
if @content.length >= InstallFailedError::MAX_LENGTH
|
|
52
|
+
@content = "#{@content.slice(0,InstallFailedError::MAX_LENGTH)}\n.."
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def printable_message
|
|
57
|
+
return "Failed to download and install file from #{url}\nReason: #{error}\nResponse was:\n#{content}\nCheck your url!"
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# this error is raised when a variable has already been assigned a value
|
|
62
|
+
# for example @x is red and @x is blue
|
|
21
63
|
class AlreadyAssignedError < Error
|
|
22
|
-
|
|
64
|
+
attr_reader :variable
|
|
23
65
|
|
|
24
66
|
def initialize variable
|
|
25
67
|
@variable = variable
|
|
@@ -30,9 +72,12 @@ class Yay
|
|
|
30
72
|
end
|
|
31
73
|
end
|
|
32
74
|
|
|
75
|
+
# this is a generic access control error that's raised when someoen tries to
|
|
76
|
+
# do something disallowed in their current context. for example, you can
|
|
77
|
+
# use the install command from the command line but not a yayfile
|
|
33
78
|
class NotAllowedError < Error
|
|
34
|
-
|
|
35
|
-
|
|
79
|
+
attr_reader :action
|
|
80
|
+
attr_reader :path
|
|
36
81
|
|
|
37
82
|
def initialize action, path
|
|
38
83
|
@action = action
|
|
@@ -44,22 +89,26 @@ class Yay
|
|
|
44
89
|
end
|
|
45
90
|
end
|
|
46
91
|
|
|
92
|
+
# raised when there's a circular reference between rules. this happens when
|
|
93
|
+
# variables point back to themselves in some way. e.g. @x is @y and @y is @x
|
|
47
94
|
class CircularReferenceError < Error
|
|
48
|
-
|
|
49
|
-
|
|
95
|
+
attr_reader :current
|
|
96
|
+
attr_reader :path
|
|
50
97
|
|
|
51
98
|
def initialize current, path
|
|
52
99
|
@current = current
|
|
53
100
|
@path = path
|
|
54
101
|
end
|
|
55
|
-
|
|
102
|
+
|
|
56
103
|
def printable_message
|
|
57
104
|
return "There is a circular reference between variables: #{path.join(' => ')} => #{current}#{printable_position}"
|
|
58
105
|
end
|
|
59
106
|
end
|
|
60
107
|
|
|
108
|
+
# raised when a variable has been referenced but not given a value. for example
|
|
109
|
+
# cheese is @x without ever defining what @x is
|
|
61
110
|
class UnresolvedSubstitutionError < Error
|
|
62
|
-
|
|
111
|
+
attr_reader :variable
|
|
63
112
|
|
|
64
113
|
def initialize variable
|
|
65
114
|
@variable = variable
|
|
@@ -70,9 +119,10 @@ class Yay
|
|
|
70
119
|
end
|
|
71
120
|
end
|
|
72
121
|
|
|
122
|
+
# raised when include file resolution has failed
|
|
73
123
|
class CouldntFindFileError < Error
|
|
74
|
-
|
|
75
|
-
|
|
124
|
+
attr_reader :filename
|
|
125
|
+
attr_reader :tried
|
|
76
126
|
|
|
77
127
|
def initialize filename, tried
|
|
78
128
|
@filename = filename
|
|
@@ -84,10 +134,13 @@ class Yay
|
|
|
84
134
|
end
|
|
85
135
|
end
|
|
86
136
|
|
|
137
|
+
# raised when a colour sequence was malformed. in practice you can use
|
|
138
|
+
# infinite colour commands but zero to two actual colours, the first one will
|
|
139
|
+
# be the foreground and the second one will be the background
|
|
87
140
|
class TooManyColoursError < Error
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
141
|
+
attr_reader :fg
|
|
142
|
+
attr_reader :bg
|
|
143
|
+
attr_reader :colour
|
|
91
144
|
|
|
92
145
|
def initialize fg, bg, colour, position
|
|
93
146
|
@fg = fg
|
|
@@ -101,9 +154,12 @@ class Yay
|
|
|
101
154
|
end
|
|
102
155
|
end
|
|
103
156
|
|
|
157
|
+
# raised when an unexpected token was found by the parser. in otherwords,
|
|
158
|
+
# the rules of the syntax have been broken somehow and the user hasn't written
|
|
159
|
+
# a valid command
|
|
104
160
|
class UnexpectedTokenError < Error
|
|
105
|
-
|
|
106
|
-
|
|
161
|
+
attr_reader :type
|
|
162
|
+
attr_reader :value
|
|
107
163
|
|
|
108
164
|
def initialize type, value, position
|
|
109
165
|
@type = type
|
|
@@ -111,12 +167,16 @@ class Yay
|
|
|
111
167
|
@position = position
|
|
112
168
|
end
|
|
113
169
|
|
|
170
|
+
# add extra feedback for some tokens. help the user out!
|
|
114
171
|
def extra_message
|
|
115
172
|
return "Since #{value} has a special meaning, try enclosing it in quotes or a regex when searching for it" if type == "colour"
|
|
173
|
+
return "Have you finished the line off properly?" if type == "$end"
|
|
116
174
|
return ""
|
|
117
175
|
end
|
|
118
176
|
|
|
119
177
|
def printable_message
|
|
178
|
+
return "Unexpected text \"#{value}\"#{printable_position}\n#{extra_message}" if type == "error"
|
|
179
|
+
return "Unexpected end of line#{printable_position}\n#{extra_message}" if type == "$end"
|
|
120
180
|
return "Unexpected #{type} \"#{value}\"#{printable_position}\n#{extra_message}"
|
|
121
181
|
end
|
|
122
182
|
end
|
data/lib/yay/installer.rb
CHANGED
|
@@ -1,12 +1,135 @@
|
|
|
1
|
+
require 'net/http'
|
|
2
|
+
require 'net/https'
|
|
3
|
+
require 'uri'
|
|
4
|
+
require 'yay/paths'
|
|
5
|
+
require 'fileutils'
|
|
1
6
|
|
|
2
7
|
class Yay
|
|
8
|
+
# installs .yay files from a remote url in to either ~/.yay or /etc/yay
|
|
9
|
+
# depending on the users permissions
|
|
3
10
|
class Installer
|
|
4
|
-
|
|
5
|
-
|
|
11
|
+
|
|
12
|
+
# initialize an installer for the specified url. the .install method will
|
|
13
|
+
# attempt the actual installation process
|
|
14
|
+
def initialize file_name, url
|
|
15
|
+
# directories to iterate. begin with /etc/yay, which should only be
|
|
16
|
+
# accessible to sudo. then try a local install.
|
|
17
|
+
paths = Yay::Paths.new
|
|
18
|
+
validate_filename file_name
|
|
19
|
+
@file_name = append_filetype file_name
|
|
20
|
+
@dirs = [
|
|
21
|
+
paths.global_yay_path,
|
|
22
|
+
paths.local_yay_path
|
|
23
|
+
]
|
|
24
|
+
@url = url
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# some filenames just aren't a good idea
|
|
28
|
+
def validate_filename string
|
|
29
|
+
raise BadFilenameError.new string if /[\?\*\\\/]/.match(string)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# add the .yay part to the filename if it's missing
|
|
33
|
+
def append_filetype string
|
|
34
|
+
return "#{string}.yay" unless /\.yay$/.match(string)
|
|
35
|
+
return string
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# see if we can write to a directory. will try to create the folder (and
|
|
39
|
+
# its parents) unless asked otherwise
|
|
40
|
+
def can_write_to_dir dir, create
|
|
41
|
+
|
|
42
|
+
begin
|
|
43
|
+
stat = File.stat(dir)
|
|
44
|
+
return true if stat && stat.writable?
|
|
45
|
+
rescue Errno::ENOENT
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# create and try again if it doesn't exist
|
|
49
|
+
if create
|
|
50
|
+
begin
|
|
51
|
+
FileUtils.mkdir_p dir
|
|
52
|
+
#FileUtils.chmod 0644, dir
|
|
53
|
+
result = can_write_to_dir dir, false
|
|
54
|
+
puts "Created #{dir}" if result
|
|
55
|
+
return result
|
|
56
|
+
rescue Errno::EACCES
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
return false
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# try to find the install directory
|
|
64
|
+
def get_install_directory
|
|
65
|
+
# search globally and then locally to see if we can write
|
|
66
|
+
@dirs.each { |dir|
|
|
67
|
+
return dir if can_write_to_dir dir, true
|
|
68
|
+
}
|
|
69
|
+
return nil
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# make a curl-ish request and get the contents
|
|
73
|
+
def get_remote_string url, limit=5
|
|
74
|
+
raise InstallFailedError.new url, 'HTTP redirect too deep' if limit == 0
|
|
75
|
+
|
|
76
|
+
begin
|
|
77
|
+
puts "Requesting #{url}"
|
|
78
|
+
url = URI.parse(url)
|
|
79
|
+
|
|
80
|
+
request = Net::HTTP::Get.new(url.path || '/')
|
|
81
|
+
|
|
82
|
+
http = Net::HTTP.new url.host, url.port
|
|
83
|
+
#http.set_debug_output($stderr)
|
|
84
|
+
http.use_ssl = url.scheme == 'https'
|
|
85
|
+
|
|
86
|
+
response = http.start { |http2|
|
|
87
|
+
http2.request(request)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
rescue StandardError => error
|
|
91
|
+
raise InstallFailedError.new url, error.to_s
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
case response
|
|
95
|
+
when Net::HTTPSuccess then
|
|
96
|
+
return response.body
|
|
97
|
+
when Net::HTTPRedirection then
|
|
98
|
+
puts "Redirecting to #{response['location']}";
|
|
99
|
+
return get_remote_string(response['location'], limit - 1)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
raise InstallFailedError.new url, "#{response.code} \"#{response.message}\"", response.body
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# ensure the rules we've downloaded parse correctly
|
|
106
|
+
def verify_rules url, string
|
|
107
|
+
begin
|
|
108
|
+
parser = Yay::Parser.new
|
|
109
|
+
parser.parse(string)
|
|
110
|
+
rescue Yay::Error => error
|
|
111
|
+
raise InstallFailedError.new url, error.printable_message, string
|
|
112
|
+
end
|
|
113
|
+
raise InstallFailedError.new url, "No rules in downloaded file", string if parser.get_rules == []
|
|
114
|
+
return parser
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
# store a string
|
|
118
|
+
def install_string string, dest_folder
|
|
119
|
+
dest = "#{dest_folder}/#{@file_name}"
|
|
120
|
+
File.open(dest, 'w') {|file|
|
|
121
|
+
file.write(string)
|
|
122
|
+
}
|
|
123
|
+
puts "#{ColourWheel::success}Installed to #{dest}#{ColourWheel::end_colour}"
|
|
6
124
|
end
|
|
7
125
|
|
|
126
|
+
# attempt the installation process
|
|
8
127
|
def install
|
|
9
|
-
|
|
128
|
+
dest_folder = get_install_directory
|
|
129
|
+
raise "Couldn't write to or create directories #{@dirs.join(' or ')} something is up with your system!" unless dest_folder
|
|
130
|
+
string = get_remote_string @url
|
|
131
|
+
verify_rules @url, string
|
|
132
|
+
install_string string, dest_folder
|
|
10
133
|
end
|
|
11
134
|
end
|
|
12
135
|
end
|
data/lib/yay/lexer.rb
CHANGED
|
@@ -2,11 +2,12 @@ require 'strscan'
|
|
|
2
2
|
require 'yay/lexer_regex'
|
|
3
3
|
|
|
4
4
|
class Yay
|
|
5
|
+
# tokenises yay rules
|
|
5
6
|
class Lexer
|
|
6
7
|
attr :context_name
|
|
7
8
|
|
|
8
9
|
def initialize(string="", context_name=nil)
|
|
9
|
-
@position =
|
|
10
|
+
@position = 1
|
|
10
11
|
@line = 1
|
|
11
12
|
@context_name = context_name
|
|
12
13
|
|
|
@@ -15,19 +16,23 @@ class Yay
|
|
|
15
16
|
use_string(string)
|
|
16
17
|
end
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
# the context name describes the source yay rules. this is free-form
|
|
20
|
+
# text but is best set to the filename
|
|
21
|
+
def context_name= value
|
|
22
|
+
@context_name = value
|
|
23
|
+
end
|
|
21
24
|
|
|
22
25
|
# take a string and begin scanning it
|
|
23
26
|
def use_string(string)
|
|
24
27
|
@scanner = StringScanner.new string
|
|
25
28
|
end
|
|
26
29
|
|
|
30
|
+
# return the current word
|
|
27
31
|
def position
|
|
28
32
|
@position
|
|
29
33
|
end
|
|
30
34
|
|
|
35
|
+
# return the current line
|
|
31
36
|
def line
|
|
32
37
|
@line
|
|
33
38
|
end
|
data/lib/yay/lexer_regex.rb
CHANGED
|
@@ -27,6 +27,9 @@ class Yay
|
|
|
27
27
|
[:literal , /\b\S+\b/],
|
|
28
28
|
]
|
|
29
29
|
|
|
30
|
+
# get the regular expressions we need. always use this instead of
|
|
31
|
+
# referencing the base patterns directly as we augment that array with
|
|
32
|
+
# the colour names that are available
|
|
30
33
|
def get_patterns
|
|
31
34
|
patterns = BASE_PATTERNS
|
|
32
35
|
# add the colour keywords. generate these from the colour wheel's constants
|
data/lib/yay/lister.rb
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
require 'yay/paths'
|
|
2
|
+
|
|
3
|
+
class Yay
|
|
4
|
+
# Lists installed .yay files
|
|
5
|
+
# See also: Rimmer, Cat
|
|
6
|
+
class Lister
|
|
7
|
+
|
|
8
|
+
# returns [[name, path],..]
|
|
9
|
+
def get_files_in_dir dir
|
|
10
|
+
results = []
|
|
11
|
+
Dir.glob("#{dir}/*.yay").each { |path|
|
|
12
|
+
matches = /\/(\w*)?\.yay$/.match(path)
|
|
13
|
+
if matches[1]
|
|
14
|
+
results.unshift [matches[1], path]
|
|
15
|
+
else
|
|
16
|
+
puts "Eh.. #{path} isn't quite right"
|
|
17
|
+
end
|
|
18
|
+
}
|
|
19
|
+
return results
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# returns {dir=>[file,..]
|
|
23
|
+
def get_all_files
|
|
24
|
+
paths = Yay::Paths.new
|
|
25
|
+
result = {}
|
|
26
|
+
paths.yay_paths.each { |path|
|
|
27
|
+
result[path] = get_files_in_dir path
|
|
28
|
+
}
|
|
29
|
+
return result
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# print the search paths we'll use when looking for yay files
|
|
33
|
+
def print_paths
|
|
34
|
+
puts "Search paths: (in order of precedence)"
|
|
35
|
+
paths = Yay::Paths.new
|
|
36
|
+
paths.yay_paths.each { |dir|
|
|
37
|
+
puts dir
|
|
38
|
+
}
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# print the files we can use and the command that can be typed to use it
|
|
42
|
+
def print_files
|
|
43
|
+
puts "Installed styles:"
|
|
44
|
+
get_all_files.each_pair { |dir, files|
|
|
45
|
+
#puts "#{dir}:"
|
|
46
|
+
files.each { |file|
|
|
47
|
+
puts "#{file[0]}#{' '*(20-file[0].length)}#{file[1]}"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# print all paths and files we find in them
|
|
53
|
+
def print
|
|
54
|
+
print_paths
|
|
55
|
+
puts
|
|
56
|
+
print_files
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
data/lib/yay/loader.rb
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
require 'yay/paths'
|
|
2
2
|
|
|
3
3
|
class Yay
|
|
4
|
+
# resolves the location of an include file
|
|
4
5
|
class Loader
|
|
5
6
|
def initialize filename
|
|
6
7
|
@filename = filename
|
|
7
8
|
end
|
|
8
9
|
|
|
10
|
+
# get the default loader. this, um, loads the default.yay file!
|
|
9
11
|
def self.default_file_loader
|
|
10
12
|
return Yay::Loader.new Yay::Paths::DEFAULT_YAYFILE
|
|
11
13
|
end
|
data/lib/yay/parser.rb
CHANGED
|
@@ -6,150 +6,175 @@ require 'yay/loader'
|
|
|
6
6
|
require 'yay/installer'
|
|
7
7
|
require 'yay/errors'
|
|
8
8
|
require 'yay/paths'
|
|
9
|
+
require 'yay/lister'
|
|
9
10
|
|
|
10
11
|
class Yay
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
12
|
+
# extends the parser that was automatically generated by racc and adds the
|
|
13
|
+
# behaviour necessary. this separation is done only because it's difficult to
|
|
14
|
+
# use .y files for anything other than grammar rules, even if they do allow
|
|
15
|
+
# ruby code
|
|
16
|
+
class Parser < Yay::ParserGen
|
|
17
|
+
|
|
18
|
+
# allow this parser to load the default rule file if the rule body is empty
|
|
19
|
+
attr_accessor :allow_default
|
|
20
|
+
|
|
21
|
+
# allow this parser to install new rule files from remote sources. beware
|
|
22
|
+
# the consequences. this should be allowed from the command line only!
|
|
23
|
+
attr_accessor :allow_install
|
|
24
|
+
|
|
25
|
+
# allow this parser to include rule files that are installed. including
|
|
26
|
+
# ones in the gem folders, globally and locally
|
|
27
|
+
attr_accessor :allow_include
|
|
28
|
+
|
|
29
|
+
# allow this parser to search for and print out all the rules that are
|
|
30
|
+
# installed
|
|
31
|
+
attr_accessor :allow_list
|
|
32
|
+
|
|
33
|
+
# set to true to signal to the application or parent parser that it's time
|
|
34
|
+
# to shut down
|
|
35
|
+
attr_reader :shutdown
|
|
16
36
|
|
|
17
37
|
def initialize context_name=nil
|
|
18
|
-
|
|
38
|
+
@lexer = Yay::Lexer.new
|
|
19
39
|
@lexer.context_name = context_name
|
|
20
40
|
end
|
|
21
41
|
|
|
22
|
-
def allow_include= value
|
|
23
|
-
@allow_include = value
|
|
24
|
-
end
|
|
25
|
-
|
|
26
42
|
# load a file from a url
|
|
27
|
-
|
|
43
|
+
def include_file filename
|
|
28
44
|
raise NotAllowedError.new "include #{filename}", current_position unless @allow_include
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
45
|
+
loader = Yay::Loader.new filename
|
|
46
|
+
loader.load
|
|
47
|
+
@ruleset.merge loader.get_rules
|
|
48
|
+
end
|
|
33
49
|
|
|
34
50
|
# install a file from a url
|
|
35
|
-
|
|
51
|
+
def install_file file_name, url
|
|
36
52
|
raise NotAllowedError.new "install #{url}", current_position unless @allow_install
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
53
|
+
installer = Yay::Installer.new file_name, url
|
|
54
|
+
installer.install
|
|
55
|
+
@shutdown = true
|
|
56
|
+
end
|
|
57
|
+
|
|
41
58
|
# print the full list of yay files
|
|
42
|
-
|
|
43
|
-
raise NotAllowedError.new "list installed yay files", current_position unless @
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
59
|
+
def list_installed
|
|
60
|
+
raise NotAllowedError.new "list installed yay files", current_position unless @allow_list
|
|
61
|
+
lister = Yay::Lister.new
|
|
62
|
+
lister.print
|
|
63
|
+
@shutdown = true
|
|
64
|
+
end
|
|
65
|
+
|
|
47
66
|
# allow all parser actions
|
|
48
67
|
def allow_all= value
|
|
49
|
-
@allow_default = @allow_install = @allow_include = @
|
|
68
|
+
@allow_default = @allow_install = @allow_include = @allow_list = value
|
|
50
69
|
end
|
|
51
70
|
|
|
52
71
|
# load the default file. used when the commandline is empty
|
|
53
72
|
def use_default_file
|
|
54
73
|
# don't throw an error in this case. it's legitimate for a file to be empty
|
|
55
74
|
return unless @allow_default
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
# a regular expression and convert it in to a bytewise options variable
|
|
72
|
-
def extract_regexp_options args
|
|
73
|
-
return 0 if args.nil?
|
|
74
|
-
raise ArgumentError unless args.kind_of? String
|
|
75
|
-
options_map = {
|
|
76
|
-
'i' => Regexp::IGNORECASE,
|
|
77
|
-
'm' => Regexp::MULTILINE,
|
|
78
|
-
'x' => Regexp::EXTENDED,
|
|
79
|
-
}
|
|
80
|
-
options = 0
|
|
81
|
-
args.each { |char|
|
|
82
|
-
options |= options_map[char] || 0
|
|
83
|
-
}
|
|
84
|
-
return options
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
# for lack of a better function, this will take a string like "/abc/" and
|
|
88
|
-
# transform it in to a regex object
|
|
89
|
-
def string_to_regex string, escape=true
|
|
90
|
-
matches = /\/([^\/\\\r\n]*(?:\\.[^\/\\\r\n]*)*)\/([a-z]\b)*/.match string
|
|
91
|
-
return nil if matches[1].nil?
|
|
92
|
-
content = matches[1]
|
|
93
|
-
content = Regexp::escape(content) if escape
|
|
94
|
-
options = extract_regexp_options matches[2]
|
|
95
|
-
return Regexp.new(content, options)
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
# given an array of colour strings, create an array with the VT100 colour
|
|
99
|
-
# sequences inside
|
|
100
|
-
def handle_colours colours
|
|
101
|
-
fg = bg = nil
|
|
102
|
-
result = []
|
|
103
|
-
# iterate the colour list and try to find up to two colours (foreground,
|
|
104
|
-
# background) and unlimited miscellaneous colours (reset, invert, etc)
|
|
105
|
-
colours.each { |colour|
|
|
106
|
-
misc_val = ColourWheel::MISC[colour]
|
|
107
|
-
if !misc_val.nil?
|
|
108
|
-
result.push misc_val
|
|
109
|
-
elsif !fg
|
|
110
|
-
fg = ColourWheel::FG[colour]
|
|
111
|
-
result.push fg
|
|
112
|
-
elsif !bg
|
|
113
|
-
bg = ColourWheel::BG[colour]
|
|
114
|
-
result.push bg
|
|
115
|
-
else
|
|
116
|
-
raise Yay::TooManyColoursError.new fg, bg, colour, current_position
|
|
117
|
-
end
|
|
118
|
-
}
|
|
119
|
-
result
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
def get_rules
|
|
123
|
-
@ruleset.get_rules
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
# process commandline arguments as if they were from a yay file
|
|
127
|
-
def parse_array args
|
|
128
|
-
raise ArgumentError, "args" unless args.kind_of? Array
|
|
129
|
-
parse args.join(' ')
|
|
130
|
-
end
|
|
131
|
-
|
|
132
|
-
# parse a string
|
|
133
|
-
def parse(str)
|
|
134
|
-
@lexer.use_string(str)
|
|
135
|
-
@ruleset = Yay::RuleSet.new
|
|
136
|
-
|
|
137
|
-
do_parse
|
|
138
|
-
get_rules
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
# get the next token
|
|
142
|
-
def next_token
|
|
143
|
-
@lexer.next_token
|
|
144
|
-
end
|
|
75
|
+
loader = Yay::Loader.default_file_loader
|
|
76
|
+
loader.load
|
|
77
|
+
@ruleset.merge loader.get_rules
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# process a string token in to something we can use
|
|
81
|
+
def handle_string string
|
|
82
|
+
string = Regexp::escape(string)
|
|
83
|
+
return Regexp.new(string, Regexp::IGNORECASE)
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
# process a regex token in to something we can use
|
|
87
|
+
def handle_regex string
|
|
88
|
+
return string_to_regex string, false
|
|
89
|
+
end
|
|
145
90
|
|
|
91
|
+
# for lack of a better function, this will take the ending sequence from
|
|
92
|
+
# a regular expression and convert it in to a bytewise options variable
|
|
93
|
+
def extract_regexp_options args
|
|
94
|
+
return 0 if args.nil?
|
|
95
|
+
raise ArgumentError unless args.kind_of? String
|
|
96
|
+
options_map = {
|
|
97
|
+
'i' => Regexp::IGNORECASE,
|
|
98
|
+
'm' => Regexp::MULTILINE,
|
|
99
|
+
'x' => Regexp::EXTENDED,
|
|
100
|
+
}
|
|
101
|
+
options = 0
|
|
102
|
+
args.each { |char|
|
|
103
|
+
options |= options_map[char] || 0
|
|
104
|
+
}
|
|
105
|
+
return options
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# for lack of a better function, this will take a string like "/abc/" and
|
|
109
|
+
# transform it in to a regex object
|
|
110
|
+
def string_to_regex string, escape=true
|
|
111
|
+
matches = /\/([^\/\\\r\n]*(?:\\.[^\/\\\r\n]*)*)\/([a-z]\b)*/.match string
|
|
112
|
+
return nil if matches[1].nil?
|
|
113
|
+
content = matches[1]
|
|
114
|
+
content = Regexp::escape(content) if escape
|
|
115
|
+
options = extract_regexp_options matches[2]
|
|
116
|
+
return Regexp.new(content, options)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# given an array of colour strings, create an array with the VT100 colour
|
|
120
|
+
# sequences inside
|
|
121
|
+
def handle_colours colours
|
|
122
|
+
fg = bg = nil
|
|
123
|
+
result = []
|
|
124
|
+
# iterate the colour list and try to find up to two colours (foreground,
|
|
125
|
+
# background) and unlimited miscellaneous colours (reset, invert, etc)
|
|
126
|
+
colours.each { |colour|
|
|
127
|
+
misc_val = ColourWheel::MISC[colour]
|
|
128
|
+
if !misc_val.nil?
|
|
129
|
+
result.push misc_val
|
|
130
|
+
elsif !fg
|
|
131
|
+
fg = ColourWheel::FG[colour]
|
|
132
|
+
result.push fg
|
|
133
|
+
elsif !bg
|
|
134
|
+
bg = ColourWheel::BG[colour]
|
|
135
|
+
result.push bg
|
|
136
|
+
else
|
|
137
|
+
raise Yay::TooManyColoursError.new fg, bg, colour, current_position
|
|
138
|
+
end
|
|
139
|
+
}
|
|
140
|
+
result
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# get the end result of the parse
|
|
144
|
+
def get_rules
|
|
145
|
+
@ruleset.get_rules
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
# process commandline arguments as if they were from a yay file
|
|
149
|
+
def parse_array args
|
|
150
|
+
raise ArgumentError, "args" unless args.kind_of? Array
|
|
151
|
+
parse args.join(' ')
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# parse a string. returns the results
|
|
155
|
+
def parse(str)
|
|
156
|
+
@lexer.use_string(str)
|
|
157
|
+
@ruleset = Yay::RuleSet.new
|
|
158
|
+
|
|
159
|
+
do_parse
|
|
160
|
+
return get_rules
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# get the next token
|
|
164
|
+
def next_token
|
|
165
|
+
@lexer.next_token
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
# get location information from the lexer in a nice little array we can
|
|
169
|
+
# pass to an exception constructor
|
|
146
170
|
def current_position
|
|
147
171
|
return [@lexer.position, @lexer.line, @lexer.context_name]
|
|
148
172
|
end
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
173
|
+
|
|
174
|
+
# the racc on_error function
|
|
175
|
+
def on_error error_token_id, error_value, cant_touch_this
|
|
176
|
+
type = token_to_str error_token_id
|
|
177
|
+
raise Yay::UnexpectedTokenError.new type, error_value, current_position
|
|
178
|
+
end
|
|
179
|
+
end
|
|
155
180
|
end
|
data/lib/yay/parser_gen.rb
CHANGED
|
@@ -15,37 +15,39 @@ module_eval(<<'...end grammar.y/module_eval...', 'grammar.y', 54)
|
|
|
15
15
|
##### State transition tables begin ###
|
|
16
16
|
|
|
17
17
|
racc_action_table = [
|
|
18
|
-
-7, -25,
|
|
19
|
-
|
|
20
|
-
10, 12, 28,
|
|
21
|
-
29,
|
|
18
|
+
-7, -25, 33, 17, 25, 17, -25, 12, 22, 22,
|
|
19
|
+
33, 20, 30, 9, 10, 12, 2, 4, 8, 9,
|
|
20
|
+
10, 12, 28, 36, 31, 29, 29, 19, -2, 17,
|
|
21
|
+
38, 29, 38 ]
|
|
22
22
|
|
|
23
23
|
racc_action_check = [
|
|
24
24
|
7, 6, 21, 17, 10, 9, 6, 21, 6, 7,
|
|
25
25
|
23, 4, 19, 23, 23, 23, 0, 0, 0, 0,
|
|
26
|
-
0, 0, 18, 24,
|
|
27
|
-
29,
|
|
26
|
+
0, 0, 18, 24, 20, 18, 24, 3, 2, 1,
|
|
27
|
+
27, 29, 35 ]
|
|
28
28
|
|
|
29
29
|
racc_action_pointer = [
|
|
30
|
-
14,
|
|
30
|
+
14, 18, 28, 27, 9, nil, -1, 0, nil, -6,
|
|
31
31
|
2, nil, nil, nil, nil, nil, nil, -8, 17, 12,
|
|
32
|
-
|
|
33
|
-
nil, nil, nil, nil,
|
|
32
|
+
22, 0, nil, 8, 18, nil, nil, 20, nil, 23,
|
|
33
|
+
nil, nil, nil, nil, nil, 22, nil, nil, nil, nil,
|
|
34
|
+
nil ]
|
|
34
35
|
|
|
35
36
|
racc_action_default = [
|
|
36
37
|
-5, -29, -20, -30, -30, -1, -19, -25, -4, -29,
|
|
37
38
|
-30, -8, -21, -9, -10, -11, -12, -29, -30, -30,
|
|
38
|
-
|
|
39
|
-
|
|
39
|
+
-30, -30, -24, -30, -30, -17, -28, -27, -14, -23,
|
|
40
|
+
41, -3, -18, -20, -6, -27, -16, -13, -26, -22,
|
|
41
|
+
-15 ]
|
|
40
42
|
|
|
41
43
|
racc_goto_table = [
|
|
42
|
-
5, 18, 27,
|
|
43
|
-
|
|
44
|
-
nil, nil, nil,
|
|
44
|
+
5, 18, 27, 37, 21, 23, 32, 3, 35, 24,
|
|
45
|
+
nil, 40, nil, 39, nil, nil, nil, 26, nil, nil,
|
|
46
|
+
nil, nil, nil, 34 ]
|
|
45
47
|
|
|
46
48
|
racc_goto_check = [
|
|
47
49
|
2, 11, 12, 13, 4, 4, 10, 1, 12, 11,
|
|
48
|
-
13, nil,
|
|
50
|
+
nil, 13, nil, 12, nil, nil, nil, 11, nil, nil,
|
|
49
51
|
nil, nil, nil, 2 ]
|
|
50
52
|
|
|
51
53
|
racc_goto_pointer = [
|
|
@@ -60,7 +62,7 @@ racc_reduce_table = [
|
|
|
60
62
|
0, 0, :racc_error,
|
|
61
63
|
1, 13, :_reduce_1,
|
|
62
64
|
1, 13, :_reduce_2,
|
|
63
|
-
|
|
65
|
+
3, 13, :_reduce_3,
|
|
64
66
|
1, 13, :_reduce_4,
|
|
65
67
|
0, 13, :_reduce_5,
|
|
66
68
|
3, 14, :_reduce_6,
|
|
@@ -90,7 +92,7 @@ racc_reduce_table = [
|
|
|
90
92
|
|
|
91
93
|
racc_reduce_n = 30
|
|
92
94
|
|
|
93
|
-
racc_shift_n =
|
|
95
|
+
racc_shift_n = 41
|
|
94
96
|
|
|
95
97
|
racc_token_table = {
|
|
96
98
|
false => 0,
|
|
@@ -177,7 +179,7 @@ module_eval(<<'.,.,', 'grammar.y', 6)
|
|
|
177
179
|
|
|
178
180
|
module_eval(<<'.,.,', 'grammar.y', 7)
|
|
179
181
|
def _reduce_3(val, _values, result)
|
|
180
|
-
install_file val[1]
|
|
182
|
+
install_file val[1], val[2]
|
|
181
183
|
result
|
|
182
184
|
end
|
|
183
185
|
.,.,
|
data/lib/yay/paths.rb
CHANGED
|
@@ -2,10 +2,10 @@ require 'rubygems'
|
|
|
2
2
|
require 'yay/version'
|
|
3
3
|
|
|
4
4
|
class Yay
|
|
5
|
-
|
|
5
|
+
|
|
6
6
|
# some utility functions for finding the current install and .yay paths
|
|
7
7
|
class Paths
|
|
8
|
-
|
|
8
|
+
|
|
9
9
|
DEFAULT_YAYFILE = 'default'
|
|
10
10
|
|
|
11
11
|
# get the paths to installed gems
|
|
@@ -20,13 +20,17 @@ class Yay
|
|
|
20
20
|
|
|
21
21
|
# get all the paths where we might be able to find .yay files
|
|
22
22
|
def yay_paths
|
|
23
|
-
result = [local_yay_path]
|
|
23
|
+
result = [local_yay_path,global_yay_path]
|
|
24
24
|
gempaths.each { |v|
|
|
25
25
|
result.push gempath_to_yaypath(v)
|
|
26
26
|
}
|
|
27
27
|
return result
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
+
def global_yay_path
|
|
31
|
+
return '/etc/yay'
|
|
32
|
+
end
|
|
33
|
+
|
|
30
34
|
# get the path we store local .yay files
|
|
31
35
|
def local_yay_path
|
|
32
36
|
raise "ENV[HOME] not found!" unless ENV['HOME']
|
|
@@ -34,5 +38,5 @@ class Yay
|
|
|
34
38
|
end
|
|
35
39
|
|
|
36
40
|
end
|
|
37
|
-
|
|
38
|
-
end
|
|
41
|
+
|
|
42
|
+
end
|
data/lib/yay/rule_set.rb
CHANGED
|
@@ -21,7 +21,8 @@ class Yay
|
|
|
21
21
|
def merge rules
|
|
22
22
|
@rules = @rules | rules
|
|
23
23
|
end
|
|
24
|
-
|
|
24
|
+
|
|
25
|
+
# get the rules, complete with variable substitutions made
|
|
25
26
|
def get_rules
|
|
26
27
|
# ensure we substitute all variables
|
|
27
28
|
substitute_variables if @string_to_var
|
|
@@ -79,6 +80,7 @@ class Yay
|
|
|
79
80
|
return result
|
|
80
81
|
end
|
|
81
82
|
|
|
83
|
+
# replace all references to variables with their actual colours
|
|
82
84
|
def substitute_variables
|
|
83
85
|
@string_to_var.each { |ref|
|
|
84
86
|
string = ref[0]
|
data/lib/yay/version.rb
CHANGED
|
@@ -2,18 +2,21 @@ require 'open3'
|
|
|
2
2
|
|
|
3
3
|
class Yay
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
# the gem version. increment to make a new release!
|
|
6
|
+
VERSION = "0.0.6"
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
8
|
+
# yoinked from chef. this gives us the git revision number of the current
|
|
9
|
+
# build if possible. used for --version
|
|
10
|
+
def self.version
|
|
11
|
+
@rev ||= begin
|
|
12
|
+
begin
|
|
13
|
+
rev = Open3.popen3("git rev-parse HEAD") {|stdin, stdout, stderr| stdout.read }.strip
|
|
14
|
+
rescue Errno::ENOENT
|
|
15
|
+
rev = ""
|
|
16
|
+
end
|
|
17
|
+
rev.empty? ? nil : " (#{rev})"
|
|
18
|
+
end
|
|
19
|
+
"#{VERSION}#@rev"
|
|
20
|
+
end
|
|
18
21
|
|
|
19
22
|
end
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: yay
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
hash:
|
|
4
|
+
hash: 19
|
|
5
5
|
prerelease: false
|
|
6
6
|
segments:
|
|
7
7
|
- 0
|
|
8
8
|
- 0
|
|
9
|
-
-
|
|
10
|
-
version: 0.0.
|
|
9
|
+
- 6
|
|
10
|
+
version: 0.0.6
|
|
11
11
|
platform: ruby
|
|
12
12
|
authors:
|
|
13
13
|
- jon davey
|
|
@@ -15,7 +15,7 @@ autorequire:
|
|
|
15
15
|
bindir: bin
|
|
16
16
|
cert_chain: []
|
|
17
17
|
|
|
18
|
-
date: 2011-11-
|
|
18
|
+
date: 2011-11-20 00:00:00 +00:00
|
|
19
19
|
default_executable:
|
|
20
20
|
dependencies: []
|
|
21
21
|
|
|
@@ -30,21 +30,22 @@ extra_rdoc_files: []
|
|
|
30
30
|
files:
|
|
31
31
|
- LICENSE
|
|
32
32
|
- data/yay/default.yay
|
|
33
|
-
- data/yay/syslog.yay
|
|
34
33
|
- data/yay/log4x.yay
|
|
35
|
-
-
|
|
36
|
-
- lib/yay/
|
|
34
|
+
- data/yay/syslog.yay
|
|
35
|
+
- lib/yay/colourizer.rb
|
|
36
|
+
- lib/yay/application.rb
|
|
37
|
+
- lib/yay/version.rb
|
|
37
38
|
- lib/yay/parser_gen.rb
|
|
38
|
-
- lib/yay/
|
|
39
|
-
- lib/yay/colour_wheel.rb
|
|
39
|
+
- lib/yay/lister.rb
|
|
40
40
|
- lib/yay/lexer_regex.rb
|
|
41
|
-
- lib/yay/
|
|
42
|
-
- lib/yay/
|
|
43
|
-
- lib/yay/application.rb
|
|
41
|
+
- lib/yay/errors.rb
|
|
42
|
+
- lib/yay/parser.rb
|
|
44
43
|
- lib/yay/loader.rb
|
|
45
|
-
- lib/yay/
|
|
46
|
-
- lib/yay/
|
|
44
|
+
- lib/yay/paths.rb
|
|
45
|
+
- lib/yay/colour_wheel.rb
|
|
47
46
|
- lib/yay/installer.rb
|
|
47
|
+
- lib/yay/rule_set.rb
|
|
48
|
+
- lib/yay/lexer.rb
|
|
48
49
|
- bin/yay
|
|
49
50
|
has_rdoc: true
|
|
50
51
|
homepage: http://github.com/jond3k/yay
|