aster 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.
- checksums.yaml +7 -0
- data/.gitignore +22 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +52 -0
- data/Rakefile +11 -0
- data/TODO +4 -0
- data/aster.gemspec +27 -0
- data/lib/aster.rb +15 -0
- data/lib/aster/command.rb +24 -0
- data/lib/aster/environment.rb +114 -0
- data/lib/aster/function.rb +10 -0
- data/lib/aster/parser.rb +72 -0
- data/lib/aster/sexp.treetop +58 -0
- data/lib/aster/variable.rb +11 -0
- data/lib/aster/version.rb +3 -0
- data/test/examples/web_server.aster +19 -0
- data/test/helper.rb +5 -0
- data/test/test_environment.rb +18 -0
- data/test/test_parser.rb +58 -0
- metadata +123 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 58243f4638f7370eaedd71419622f967f24bd60e
|
4
|
+
data.tar.gz: 8426cc93373842fb7cf66d2fcc3c389a47cdecf1
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 1adc2b41461422e04081c6fa8c4d9f2c460b8661691ee0aff87bacf5fc7d9b611fa031a7e1115b680221e767f071ec0c61ca953d44761e2062191fbb863a7ae4
|
7
|
+
data.tar.gz: 1cdcbe16dff0aaf31ec201df89181461416f94d3c1044d890de17ad664b60c8a06fcf7f8b6622266cc051f950fe647b2d3172770a2d3e3e7b3439b194bcd65ef
|
data/.gitignore
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
*.bundle
|
19
|
+
*.so
|
20
|
+
*.o
|
21
|
+
*.a
|
22
|
+
mkmf.log
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Sam Murphy
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
# Aster
|
2
|
+
|
3
|
+
Aster is a programming language that's designed to make configuration management more fun.
|
4
|
+
|
5
|
+
## Example
|
6
|
+
|
7
|
+
server web
|
8
|
+
default-instance-vars
|
9
|
+
var username root
|
10
|
+
var ssh-port 22
|
11
|
+
|
12
|
+
configure
|
13
|
+
run upgrade-ubuntu.sh
|
14
|
+
exec sudo reboot
|
15
|
+
exec sudo apt-get install nginx
|
16
|
+
run create-admin-user.aster
|
17
|
+
config-set username admin
|
18
|
+
config-set ssh-port 2222
|
19
|
+
upload sample.conf /etc/conf
|
20
|
+
|
21
|
+
add-remote-file-runner .rb
|
22
|
+
exec `which ruby`
|
23
|
+
|
24
|
+
file hostname.rb
|
25
|
+
require 'rubygems'
|
26
|
+
puts `hostname`.strip
|
27
|
+
|
28
|
+
file database.yml
|
29
|
+
---
|
30
|
+
production:
|
31
|
+
adapter: mysql2
|
32
|
+
username: root
|
33
|
+
password: 00000000
|
34
|
+
|
35
|
+
file sample.conf xml
|
36
|
+
<xml>
|
37
|
+
<var val="test" />
|
38
|
+
</xml>
|
39
|
+
|
40
|
+
function hostname
|
41
|
+
exec-script hostname.ruby
|
42
|
+
|
43
|
+
create-server-instance web
|
44
|
+
configure-instance {{instance.id}}
|
45
|
+
|
46
|
+
## Install
|
47
|
+
|
48
|
+
gem install aster
|
49
|
+
|
50
|
+
## Usage
|
51
|
+
|
52
|
+
Aster is not a configuration management application. Right now it is an experimental language that supports other languages embedded within `.aster` files.
|
data/Rakefile
ADDED
data/TODO
ADDED
data/aster.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'aster/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "aster"
|
8
|
+
spec.version = Aster::VERSION
|
9
|
+
spec.authors = ["Sam Murphy"]
|
10
|
+
spec.email = ["sam.murphy@gmail.com"]
|
11
|
+
spec.summary = %q{A programming language for configuring servers}
|
12
|
+
#spec.description = %q{TODO: Write a longer description. Optional.}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "treetop"
|
22
|
+
#spec.add_dependency "thor"
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.6"
|
25
|
+
spec.add_development_dependency "rake"
|
26
|
+
spec.add_development_dependency "pry"
|
27
|
+
end
|
data/lib/aster.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require "aster/version"
|
2
|
+
|
3
|
+
module Aster
|
4
|
+
# Your code goes here...
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'pry'
|
8
|
+
|
9
|
+
require_relative './aster/version'
|
10
|
+
require_relative './aster/variable'
|
11
|
+
require_relative './aster/command'
|
12
|
+
require_relative './aster/environment'
|
13
|
+
require_relative './aster/function'
|
14
|
+
require_relative './aster/parser'
|
15
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Aster
|
2
|
+
class Command
|
3
|
+
attr_accessor :text, :sublines
|
4
|
+
|
5
|
+
def initialize(commands, sublines = [])
|
6
|
+
@commands = commands
|
7
|
+
@sublines = sublines
|
8
|
+
end
|
9
|
+
|
10
|
+
def rest
|
11
|
+
@text.split(' ', 2)[1]
|
12
|
+
end
|
13
|
+
|
14
|
+
def arguments
|
15
|
+
_, *args = @commands
|
16
|
+
args
|
17
|
+
end
|
18
|
+
|
19
|
+
def function_name
|
20
|
+
@function_name ||= @commands.first.to_sym
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
module Aster
|
2
|
+
|
3
|
+
class Environment
|
4
|
+
|
5
|
+
attr_reader :stderr, :stdout
|
6
|
+
|
7
|
+
def initialize(parent = nil)
|
8
|
+
@parent = parent
|
9
|
+
@env = {}
|
10
|
+
@stdout = ""
|
11
|
+
@stderr = ""
|
12
|
+
|
13
|
+
if parent.nil?
|
14
|
+
define_function :echo, [:_list_] do |arguments|
|
15
|
+
@stdout << arguments.join(' ')
|
16
|
+
end
|
17
|
+
define_function :equal, [:a, :b] do |(a, b)|
|
18
|
+
a.to_s == b.to_s ? "yes" : "no"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def child
|
24
|
+
self.class.new(self)
|
25
|
+
end
|
26
|
+
|
27
|
+
def [](k)
|
28
|
+
@env[k.to_sym] || @parent && @parent[k.to_sym]
|
29
|
+
end
|
30
|
+
|
31
|
+
def []=(k, v)
|
32
|
+
@env[k.to_sym] = v
|
33
|
+
end
|
34
|
+
|
35
|
+
def eval(script)
|
36
|
+
tree = Parser.new.parse script
|
37
|
+
eval_tree tree
|
38
|
+
end
|
39
|
+
|
40
|
+
def define_function(name, args, commands = nil, &block)
|
41
|
+
@env[name.to_sym] = Function.new(args, commands, &block)
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def eval_line(command)
|
47
|
+
case command.function_name
|
48
|
+
when :function
|
49
|
+
fun, *args = command.arguments
|
50
|
+
self.define_function(
|
51
|
+
fun,
|
52
|
+
args,
|
53
|
+
command.sublines
|
54
|
+
)
|
55
|
+
when :if
|
56
|
+
cond_value = eval_line Command.new(command.rest)
|
57
|
+
if is_true?(cond_value)
|
58
|
+
eval_tree command.sublines
|
59
|
+
end
|
60
|
+
when :not
|
61
|
+
cond_value = eval_line Command.new(command.rest)
|
62
|
+
is_true?(cond_value) ? "no" : "yes"
|
63
|
+
else
|
64
|
+
function = self[command.function_name]
|
65
|
+
if function
|
66
|
+
eval_function(function, command.arguments, self.child)
|
67
|
+
else
|
68
|
+
#binding.pry
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def is_true?(val)
|
74
|
+
val && value.strip == "yes"
|
75
|
+
end
|
76
|
+
|
77
|
+
def eval_tree(tree)
|
78
|
+
tree.each do |command|
|
79
|
+
eval_line command
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
def eval_function(function, arguments, env)
|
84
|
+
# need to eval args
|
85
|
+
arguments = arguments.map do |arg|
|
86
|
+
if arg.is_a?(Variable)
|
87
|
+
env[arg.name]
|
88
|
+
else
|
89
|
+
arg
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# bind arguments
|
94
|
+
function.arguments.each_with_index do |a, i|
|
95
|
+
env[a] = arguments[i]
|
96
|
+
end
|
97
|
+
|
98
|
+
if function.commands
|
99
|
+
env.send :eval_tree, function.commands
|
100
|
+
elsif function.block
|
101
|
+
function.block.call arguments
|
102
|
+
else
|
103
|
+
raise
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
def eval_custom(m, args)
|
110
|
+
|
111
|
+
end
|
112
|
+
|
113
|
+
end
|
114
|
+
end
|
data/lib/aster/parser.rb
ADDED
@@ -0,0 +1,72 @@
|
|
1
|
+
|
2
|
+
require 'treetop'
|
3
|
+
|
4
|
+
module Aster
|
5
|
+
|
6
|
+
Treetop.load(File.dirname(__FILE__) + "/sexp.treetop")
|
7
|
+
|
8
|
+
class Parser
|
9
|
+
|
10
|
+
def parse(text)
|
11
|
+
lines = text.split("\n")
|
12
|
+
parse_lines lines
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def text_indent(text)
|
18
|
+
return -1 if text.nil?
|
19
|
+
white_space = text.match(/^( +)/)
|
20
|
+
return 0 if white_space.nil?
|
21
|
+
size = white_space[0].size
|
22
|
+
size % 2 == 0 ? size / 2 : -1
|
23
|
+
end
|
24
|
+
|
25
|
+
def raw_parse_line(line)
|
26
|
+
@sexp ||= SexpParser.new
|
27
|
+
result = @sexp.parse(line)
|
28
|
+
result.value
|
29
|
+
end
|
30
|
+
|
31
|
+
def parse_line(line)
|
32
|
+
Command.new raw_parse_line(line)
|
33
|
+
end
|
34
|
+
|
35
|
+
def parse_lines(lines)
|
36
|
+
current_indent = (lines.first ? text_indent(lines.first) : 0)
|
37
|
+
last_line = nil
|
38
|
+
data = []
|
39
|
+
lines.each_with_index do |line, i|
|
40
|
+
# Skip Empty lines
|
41
|
+
next if line.strip.empty?
|
42
|
+
|
43
|
+
# Skip Comments
|
44
|
+
next if line.strip[0] == "#"
|
45
|
+
|
46
|
+
next_line = lines[i + 1]
|
47
|
+
indent, next_indent = text_indent(line), text_indent(next_line)
|
48
|
+
command = parse_line(line)
|
49
|
+
|
50
|
+
# Grab sub lines if possible
|
51
|
+
if next_indent > indent
|
52
|
+
j = i + 1
|
53
|
+
sublines = []
|
54
|
+
while(look_ahead_line = lines[j])
|
55
|
+
look_ahead_indent = text_indent(look_ahead_line)
|
56
|
+
if look_ahead_indent > indent
|
57
|
+
sublines << lines.slice!(j)
|
58
|
+
else
|
59
|
+
break
|
60
|
+
end
|
61
|
+
end
|
62
|
+
command.sublines = parse_lines sublines
|
63
|
+
end
|
64
|
+
data << command
|
65
|
+
end
|
66
|
+
data
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
|
4
|
+
grammar Sexp
|
5
|
+
|
6
|
+
rule body
|
7
|
+
(expression / variable / identifier / string / space)* {
|
8
|
+
def value
|
9
|
+
elements.delete_if do |e|
|
10
|
+
!e.respond_to? :value
|
11
|
+
end
|
12
|
+
elements.map{|e| e.value}
|
13
|
+
end
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
rule expression
|
19
|
+
space? '{' body '}' space? {
|
20
|
+
def value
|
21
|
+
body.elements.delete_if do |e|
|
22
|
+
!e.respond_to? :value
|
23
|
+
end
|
24
|
+
body.elements.map{|e| e.value}
|
25
|
+
end
|
26
|
+
}
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
rule variable
|
31
|
+
'$' identifier {
|
32
|
+
def value
|
33
|
+
Aster::Variable.new identifier.text_value.to_sym
|
34
|
+
end
|
35
|
+
}
|
36
|
+
end
|
37
|
+
|
38
|
+
rule identifier
|
39
|
+
[a-zA-Z0-9] [a-zA-Z0-9]* {
|
40
|
+
def value
|
41
|
+
text_value
|
42
|
+
end
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
rule string
|
47
|
+
'"' ([^"\\] / "\\" . )* '"' {
|
48
|
+
def value
|
49
|
+
text_value
|
50
|
+
end
|
51
|
+
}
|
52
|
+
end
|
53
|
+
|
54
|
+
rule space
|
55
|
+
[\s]+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
server web
|
4
|
+
|
5
|
+
set max-instances 12
|
6
|
+
|
7
|
+
set instance-methods
|
8
|
+
|
9
|
+
function after-create-hook
|
10
|
+
configure
|
11
|
+
|
12
|
+
function configure
|
13
|
+
run install_base_ubuntu.aster
|
14
|
+
exec sudo apt-get install nginx
|
15
|
+
|
16
|
+
function reboot
|
17
|
+
exec sudo reboot
|
18
|
+
|
19
|
+
|
data/test/helper.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require_relative './helper'
|
2
|
+
|
3
|
+
class TestEnvironment < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def test_not
|
6
|
+
e = Aster::Environment.new
|
7
|
+
#assert_equal "no", e.eval("not yes")
|
8
|
+
#assert_equal "yes", e.eval("not no")
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_function
|
12
|
+
e = Aster::Environment.new
|
13
|
+
e.eval "function test arg1 arg2\n echo $arg1 and $arg2"
|
14
|
+
e.eval "test one two"
|
15
|
+
assert_equal("one and two", e.stdout)
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
data/test/test_parser.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
require_relative './helper'
|
2
|
+
|
3
|
+
class TestParser < Test::Unit::TestCase
|
4
|
+
|
5
|
+
def parse_line(text)
|
6
|
+
p = Aster::Parser.new
|
7
|
+
p.send :raw_parse_line, text
|
8
|
+
end
|
9
|
+
|
10
|
+
def parse text
|
11
|
+
p = Aster::Parser.new
|
12
|
+
p.parse text
|
13
|
+
end
|
14
|
+
|
15
|
+
def text_indent(text)
|
16
|
+
p = Aster::Parser.new
|
17
|
+
p.send :text_indent, text
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_leading_indent()
|
21
|
+
assert_equal 0, text_indent('')
|
22
|
+
assert_equal 1, text_indent(' ')
|
23
|
+
assert_equal 2, text_indent(' ')
|
24
|
+
assert_equal -1, text_indent(' ')
|
25
|
+
assert_equal -1, text_indent(' ')
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_line_parse
|
29
|
+
assert_equal ["a"], parse_line("a")
|
30
|
+
assert_equal ["a", "a"], parse_line("a a")
|
31
|
+
assert_equal [:a, :b], parse_line("{$a $b}").first.map{|v| v.name.to_sym}
|
32
|
+
assert_equal ["upload", "\"asdf.jpg\""], parse_line(%q(upload "asdf.jpg"))
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_command_parse
|
36
|
+
c = parse "asdf one two"
|
37
|
+
assert_equal c.first.function_name, :asdf
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_asdf
|
41
|
+
p = Aster::Parser.new
|
42
|
+
tree = p.parse "if {not {test}}"
|
43
|
+
command = tree.first
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_parse
|
47
|
+
parser = Aster::Parser.new
|
48
|
+
file = "
|
49
|
+
function test asdr
|
50
|
+
exec test
|
51
|
+
|
52
|
+
function test2 asdf
|
53
|
+
exec
|
54
|
+
"
|
55
|
+
tree = parser.parse file
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
metadata
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: aster
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sam Murphy
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-04-12 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: treetop
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.6'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.6'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description:
|
70
|
+
email:
|
71
|
+
- sam.murphy@gmail.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- .gitignore
|
77
|
+
- Gemfile
|
78
|
+
- LICENSE.txt
|
79
|
+
- README.md
|
80
|
+
- Rakefile
|
81
|
+
- TODO
|
82
|
+
- aster.gemspec
|
83
|
+
- lib/aster.rb
|
84
|
+
- lib/aster/command.rb
|
85
|
+
- lib/aster/environment.rb
|
86
|
+
- lib/aster/function.rb
|
87
|
+
- lib/aster/parser.rb
|
88
|
+
- lib/aster/sexp.treetop
|
89
|
+
- lib/aster/variable.rb
|
90
|
+
- lib/aster/version.rb
|
91
|
+
- test/examples/web_server.aster
|
92
|
+
- test/helper.rb
|
93
|
+
- test/test_environment.rb
|
94
|
+
- test/test_parser.rb
|
95
|
+
homepage: ''
|
96
|
+
licenses:
|
97
|
+
- MIT
|
98
|
+
metadata: {}
|
99
|
+
post_install_message:
|
100
|
+
rdoc_options: []
|
101
|
+
require_paths:
|
102
|
+
- lib
|
103
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - '>='
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
109
|
+
requirements:
|
110
|
+
- - '>='
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: '0'
|
113
|
+
requirements: []
|
114
|
+
rubyforge_project:
|
115
|
+
rubygems_version: 2.0.3
|
116
|
+
signing_key:
|
117
|
+
specification_version: 4
|
118
|
+
summary: A programming language for configuring servers
|
119
|
+
test_files:
|
120
|
+
- test/examples/web_server.aster
|
121
|
+
- test/helper.rb
|
122
|
+
- test/test_environment.rb
|
123
|
+
- test/test_parser.rb
|