fire 0.2.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.
- data/.index +53 -0
- data/.yardopts +10 -0
- data/HISTORY.md +33 -0
- data/LICENSE.txt +29 -0
- data/README.md +217 -0
- data/bin/autofire +5 -0
- data/bin/fire +5 -0
- data/demo/03_runner/01_applying_rules.md +51 -0
- data/demo/03_runner/02_resolve_prerequisites.md +95 -0
- data/demo/applique/ae.rb +1 -0
- data/demo/applique/fire.rb +1 -0
- data/demo/applique/rules.rb +5 -0
- data/demo/overview.md +14 -0
- data/lib/fire.rb +3 -0
- data/lib/fire.yml +53 -0
- data/lib/fire/cli.rb +64 -0
- data/lib/fire/core_ext.rb +4 -0
- data/lib/fire/core_ext/boolean.rb +10 -0
- data/lib/fire/core_ext/cli.rb +56 -0
- data/lib/fire/core_ext/true_class.rb +58 -0
- data/lib/fire/digest.rb +112 -0
- data/lib/fire/dsl.rb +34 -0
- data/lib/fire/match.rb +26 -0
- data/lib/fire/rule.rb +103 -0
- data/lib/fire/rulefile.rb +12 -0
- data/lib/fire/runner.rb +76 -0
- data/lib/fire/session.rb +268 -0
- data/lib/fire/shellutils.rb +77 -0
- data/lib/fire/state.rb +91 -0
- data/lib/fire/system.rb +244 -0
- data/lib/fire/task.rb +71 -0
- data/man/fire.1 +47 -0
- data/man/fire.1.html +130 -0
- data/man/fire.1.ronn +52 -0
- metadata +135 -0
data/demo/applique/ae.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'ae'
|
@@ -0,0 +1 @@
|
|
1
|
+
require 'fire'
|
data/demo/overview.md
ADDED
data/lib/fire.rb
ADDED
data/lib/fire.yml
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
---
|
2
|
+
revision: 2013
|
3
|
+
type: ruby
|
4
|
+
sources:
|
5
|
+
- var
|
6
|
+
authors:
|
7
|
+
- name: Trans
|
8
|
+
email: transfire@gmail.com
|
9
|
+
organizations:
|
10
|
+
- name: Rubyworks
|
11
|
+
requirements:
|
12
|
+
- name: notify
|
13
|
+
- groups:
|
14
|
+
- build
|
15
|
+
development: true
|
16
|
+
name: detroit
|
17
|
+
- groups:
|
18
|
+
- build
|
19
|
+
development: true
|
20
|
+
name: mast
|
21
|
+
conflicts: []
|
22
|
+
alternatives: []
|
23
|
+
resources:
|
24
|
+
- type: home
|
25
|
+
uri: http://rubyworks.github.com/fire
|
26
|
+
label: Homepage
|
27
|
+
- type: code
|
28
|
+
uri: http://github.com/rubyworks/fire
|
29
|
+
label: Source Code
|
30
|
+
- type: bugs
|
31
|
+
uri: http://github.com/rubyworks/fire/issues
|
32
|
+
label: Issue Tracker
|
33
|
+
repositories:
|
34
|
+
- name: upstream
|
35
|
+
scm: git
|
36
|
+
uri: git://github.com/rubyworks/fire.git
|
37
|
+
categories: []
|
38
|
+
copyrights:
|
39
|
+
- holder: Rubyworks
|
40
|
+
year: '2010'
|
41
|
+
license: BSD-2-Clause
|
42
|
+
customs: []
|
43
|
+
paths:
|
44
|
+
lib:
|
45
|
+
- lib
|
46
|
+
created: '2010-07-05'
|
47
|
+
summary: The best build tool, logically!
|
48
|
+
title: Fire
|
49
|
+
version: 0.2.0
|
50
|
+
name: fire
|
51
|
+
description: ! "Fire is a continuous integration build tool with a slick set logic
|
52
|
+
\nstate/rules system."
|
53
|
+
date: '2013-02-12'
|
data/lib/fire/cli.rb
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'fire/core_ext'
|
2
|
+
require 'fire/session'
|
3
|
+
|
4
|
+
module Fire
|
5
|
+
|
6
|
+
# Fire's command line interface.
|
7
|
+
#
|
8
|
+
class CLI
|
9
|
+
|
10
|
+
# Fire her up!
|
11
|
+
def self.run(argv=ARGV)
|
12
|
+
new(argv).run
|
13
|
+
end
|
14
|
+
|
15
|
+
# Fire her up in autorun mode!
|
16
|
+
def self.autorun(argv=ARGV)
|
17
|
+
new(argv).autorun
|
18
|
+
end
|
19
|
+
|
20
|
+
# Initialize new instance of Fire::CLI.
|
21
|
+
def initialize(argv=ARGV)
|
22
|
+
@argv = argv
|
23
|
+
end
|
24
|
+
|
25
|
+
# Returns session instance. [Session]
|
26
|
+
def session
|
27
|
+
@session ||= Session.new(:watch=>@watch)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Fire her up!
|
31
|
+
def run
|
32
|
+
args = cli_parse
|
33
|
+
session.run(args)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Fire her up in autorun mode!
|
37
|
+
def autorun
|
38
|
+
args = cli_parse
|
39
|
+
session.autorun(args)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Parse command line arguments with just the prettiest
|
43
|
+
# little CLI parser there ever was.
|
44
|
+
def cli_parse
|
45
|
+
cli @argv,
|
46
|
+
"-T" => method(:list_tasks),
|
47
|
+
"-w" => method(:watch)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Print out a list of availabe manual triggers.
|
51
|
+
def list_tasks
|
52
|
+
puts "(#{session.root})"
|
53
|
+
puts session.task_sheet
|
54
|
+
exit
|
55
|
+
end
|
56
|
+
|
57
|
+
# Set the watch wait period.
|
58
|
+
def watch(seconds)
|
59
|
+
@watch = seconds
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Kernel
|
2
|
+
private
|
3
|
+
#
|
4
|
+
# CLI is based on Clap library
|
5
|
+
# Copyright (c) 2010 Michel Martens
|
6
|
+
#
|
7
|
+
def cli(*args)
|
8
|
+
opts = (Hash === args.last ? args.pop : nil)
|
9
|
+
argv = args.first || ARGV.dup
|
10
|
+
args = []
|
11
|
+
|
12
|
+
#raise ArgumentError unless opts
|
13
|
+
|
14
|
+
# Split option aliases.
|
15
|
+
opts = opts.inject({}) do |h,(k,v)|
|
16
|
+
k.to_s.split(/\s+/).each{|o| h[o]=v}; h
|
17
|
+
end
|
18
|
+
|
19
|
+
# Convert single dash flags into multiple flags.
|
20
|
+
argv = argv.inject([]) do |a, v|
|
21
|
+
if v[0,1] == '-' && v[1,1] != '-'
|
22
|
+
a.concat(v[1..-1].chars.map{|c| "-#{c}"})
|
23
|
+
else
|
24
|
+
a << v
|
25
|
+
end
|
26
|
+
a
|
27
|
+
end
|
28
|
+
|
29
|
+
while argv.any?
|
30
|
+
item = argv.shift
|
31
|
+
flag = opts[item]
|
32
|
+
|
33
|
+
if flag
|
34
|
+
# Work around lambda semantics in 1.8.7.
|
35
|
+
arity = [flag.arity, 0].max
|
36
|
+
|
37
|
+
# Raise if there are not enough parameters
|
38
|
+
# available for the flag.
|
39
|
+
if argv.size < arity
|
40
|
+
raise ArgumentError
|
41
|
+
end
|
42
|
+
|
43
|
+
# Call the lambda with N items from argv,
|
44
|
+
# where N is the lambda's arity.
|
45
|
+
flag.call(*argv.shift(arity))
|
46
|
+
else
|
47
|
+
|
48
|
+
# Collect the items that don't correspond to
|
49
|
+
# flags.
|
50
|
+
args << item
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
args
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# We are going to try doing it this way. If i proves a problem
|
2
|
+
# we'll make a special class.
|
3
|
+
#
|
4
|
+
class TrueClass
|
5
|
+
def empty?
|
6
|
+
false
|
7
|
+
end
|
8
|
+
|
9
|
+
def &(other)
|
10
|
+
other
|
11
|
+
end
|
12
|
+
|
13
|
+
def |(other)
|
14
|
+
other
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
=begin
|
19
|
+
class TrueArray < Array
|
20
|
+
|
21
|
+
def each; end
|
22
|
+
|
23
|
+
def size
|
24
|
+
1 # ?
|
25
|
+
end
|
26
|
+
|
27
|
+
def empty?
|
28
|
+
false
|
29
|
+
end
|
30
|
+
|
31
|
+
def &(other)
|
32
|
+
other.dup
|
33
|
+
end
|
34
|
+
|
35
|
+
def |(other)
|
36
|
+
other.dup
|
37
|
+
end
|
38
|
+
|
39
|
+
## If this would have worked we would not have had
|
40
|
+
## to override Array.
|
41
|
+
#def coerce(other)
|
42
|
+
# return self, other
|
43
|
+
#end
|
44
|
+
end
|
45
|
+
=end
|
46
|
+
|
47
|
+
class Array
|
48
|
+
alias and_without_t :&
|
49
|
+
alias or_without_t :|
|
50
|
+
|
51
|
+
def |(other)
|
52
|
+
TrueClass === other ? dup : or_without_t(other)
|
53
|
+
end
|
54
|
+
|
55
|
+
def &(other)
|
56
|
+
TrueClass === other ? dup : and_without_t(other)
|
57
|
+
end
|
58
|
+
end
|
data/lib/fire/digest.rb
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'digest/sha1'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
module Fire
|
5
|
+
|
6
|
+
#
|
7
|
+
#
|
8
|
+
class Digest
|
9
|
+
|
10
|
+
#
|
11
|
+
DEFAULT_FILE = ".fire/digest"
|
12
|
+
|
13
|
+
#
|
14
|
+
attr :file
|
15
|
+
|
16
|
+
#
|
17
|
+
attr :current
|
18
|
+
|
19
|
+
#
|
20
|
+
attr :saved
|
21
|
+
|
22
|
+
#
|
23
|
+
attr :ignore
|
24
|
+
|
25
|
+
#
|
26
|
+
def initialize(options={})
|
27
|
+
@file = options[:file] || DEFAULT_FILE
|
28
|
+
@ignore = options[:ignore] || []
|
29
|
+
|
30
|
+
@current = {}
|
31
|
+
@saved = {}
|
32
|
+
|
33
|
+
read
|
34
|
+
refresh
|
35
|
+
end
|
36
|
+
|
37
|
+
# Load saved digest.
|
38
|
+
def read
|
39
|
+
return unless File.exist?(file)
|
40
|
+
File.read(file).lines.each do |line|
|
41
|
+
if md = /^(\w+)\s+(.*?)$/.match(line)
|
42
|
+
@saved[md[2]] = md[1]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
=begin
|
48
|
+
# Gather current digest for all files.
|
49
|
+
#
|
50
|
+
# Returns nothing.
|
51
|
+
def refresh
|
52
|
+
Dir['**/*'].each do |path|
|
53
|
+
if File.directory?(path)
|
54
|
+
# how to handle directories as a whole?
|
55
|
+
elsif File.exist?(path)
|
56
|
+
id = checksum(path)
|
57
|
+
@current[path] = id
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
=end
|
62
|
+
|
63
|
+
# Gather current digest for all files.
|
64
|
+
#
|
65
|
+
# Returns nothing.
|
66
|
+
def refresh
|
67
|
+
list = Dir['**/*']
|
68
|
+
list = list.reject{ |path| ignore.any?{ |ig| /^#{ig}/ =~ path } }
|
69
|
+
list.each do |path|
|
70
|
+
if File.directory?(path)
|
71
|
+
# how to handle directories as a whole?
|
72
|
+
elsif File.exist?(path)
|
73
|
+
id = checksum(path)
|
74
|
+
@current[path] = id
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# Save current digest.
|
80
|
+
def save
|
81
|
+
dir = File.dirname(file)
|
82
|
+
FileUtils.mkdir(dir) unless File.directory?(dir)
|
83
|
+
File.open(file, 'w'){ |f| f << to_s }
|
84
|
+
end
|
85
|
+
|
86
|
+
# Returns [String] digest file format.
|
87
|
+
def to_s
|
88
|
+
s = ""
|
89
|
+
current.each do |path, id|
|
90
|
+
s << "#{id} #{path}\n"
|
91
|
+
end
|
92
|
+
s
|
93
|
+
end
|
94
|
+
|
95
|
+
# Compute the sha1 identifer for a file.
|
96
|
+
#
|
97
|
+
# file - path to a file
|
98
|
+
#
|
99
|
+
# Returns [String] SHA1 digest string.
|
100
|
+
def checksum(file)
|
101
|
+
sha = ::Digest::SHA1.new
|
102
|
+
File.open(file, 'r') do |fh|
|
103
|
+
fh.each_line do |l|
|
104
|
+
sha << l
|
105
|
+
end
|
106
|
+
end
|
107
|
+
sha.hexdigest
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
data/lib/fire/dsl.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
module Fire
|
2
|
+
|
3
|
+
p "HERE!!!!!!!"
|
4
|
+
|
5
|
+
#
|
6
|
+
module DSL
|
7
|
+
|
8
|
+
def state(name, &condition)
|
9
|
+
Fire.system.state(name, &condition)
|
10
|
+
end
|
11
|
+
|
12
|
+
def rule(logic, &procedure)
|
13
|
+
Fire.system.rule(logic, &procedure)
|
14
|
+
end
|
15
|
+
|
16
|
+
#def file(pattern, &procedure)
|
17
|
+
# Fire.system.file(pattern, &procedure)
|
18
|
+
#end
|
19
|
+
|
20
|
+
def trip(state)
|
21
|
+
Fire.system.trip(state)
|
22
|
+
end
|
23
|
+
|
24
|
+
def desc(description)
|
25
|
+
Fire.system.desc(description)
|
26
|
+
end
|
27
|
+
|
28
|
+
def task(name_and_logic, &procedure)
|
29
|
+
Fire.system.task(name_and_logic, &procedure)
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
data/lib/fire/match.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
module Fire
|
2
|
+
|
3
|
+
# Match is a subclass of a string that also stores the
|
4
|
+
# MatchData then matched against it in a Regexp comparison.
|
5
|
+
#
|
6
|
+
class Match < String
|
7
|
+
# Initialize a new instance of Match.
|
8
|
+
#
|
9
|
+
# string - The string. [String]
|
10
|
+
# matchdata - The match data. [MatchData]
|
11
|
+
#
|
12
|
+
def intialize(string, matchdata)
|
13
|
+
replace(string)
|
14
|
+
@matchdata = matchdata
|
15
|
+
end
|
16
|
+
|
17
|
+
# The match data that resulted from
|
18
|
+
# a successful Regexp against the string.
|
19
|
+
#
|
20
|
+
# Returns [MatchData]
|
21
|
+
def matchdata
|
22
|
+
@matchdata
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|