loki 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ .DS_Store
2
+ *.gem
3
+ .bundle
4
+ Gemfile.lock
5
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+ gemspec
3
+
4
+ gem "rake"
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # require "rubygems"
4
+
5
+ require File.expand_path(File.join(File.dirname(__FILE__), "..", "lib", "loki"))
@@ -0,0 +1,33 @@
1
+ require "singleton"
2
+ require "fileutils"
3
+
4
+ require "loki/time"
5
+ require "loki/logger"
6
+ require "loki/identity"
7
+ require "loki/file_pattern"
8
+ require "loki/file_path"
9
+ require "loki/task/base"
10
+ require "loki/task/proc"
11
+ require "loki/task/task"
12
+ require "loki/task/file"
13
+ require "loki/task/make"
14
+
15
+
16
+ module Loki
17
+
18
+ def self.task(name = :task, &block)
19
+ task = Task::Task.new(name)
20
+ task.instance_eval(&block)
21
+ # task.list
22
+ task.work
23
+ end
24
+
25
+
26
+ private
27
+
28
+ def self.block_unique_id(&block)
29
+ source = block.source_location
30
+ ::File.expand_path(source[0]) + ":#{source[1]}"
31
+ end
32
+
33
+ end # module
@@ -0,0 +1,41 @@
1
+ module Loki
2
+ class FilePath
3
+ attr_reader :path
4
+
5
+
6
+ def initialize(path)
7
+ self.path = path
8
+ end
9
+
10
+
11
+ def path=(path)
12
+ @path = ::File.expand_path(path.to_s)
13
+ end
14
+
15
+
16
+ def relative(from = Dir.pwd)
17
+ @path.gsub(/^#{from}\//, '')
18
+ end
19
+
20
+
21
+ def absolute
22
+ ::File.expand_path(@path)
23
+ end
24
+
25
+
26
+ def mtime
27
+ ::File.mtime(@path)
28
+ end
29
+
30
+
31
+ def exists?
32
+ ::File.exists?(@path)
33
+ end
34
+
35
+
36
+ def to_s
37
+ @path.to_s
38
+ end
39
+
40
+ end # class
41
+ end # module
@@ -0,0 +1,79 @@
1
+ module Loki
2
+ class FilePattern
3
+ include Enumerable
4
+ attr_reader :path
5
+
6
+
7
+ def initialize(path)
8
+ self.path = path
9
+ end
10
+
11
+
12
+ def path=(new_path)
13
+ @path = new_path.to_s
14
+ end
15
+
16
+
17
+ def each(&block)
18
+ Dir.glob(@path).each do |file|
19
+ yield FilePath.new(file) if block_given?
20
+ end
21
+ end
22
+
23
+
24
+ def interpolate_each(result_pattern, &block)
25
+ each do |source_path|
26
+ yield source_path, interpolate(source_path, result_pattern) if block_given?
27
+ end
28
+ end
29
+
30
+
31
+ def individual?
32
+ !(@path =~ /[\?\[\]\{\}\*]/)
33
+ end
34
+
35
+
36
+ def collection?
37
+ !individual?
38
+ end
39
+
40
+
41
+ def relative(from = Dir.pwd)
42
+ @path.gsub(/^#{from}\//, '')
43
+ end
44
+
45
+
46
+ def absolute
47
+ ::File.expand_path(@path)
48
+ end
49
+
50
+
51
+ def to_s
52
+ @path.to_s
53
+ end
54
+
55
+
56
+ private
57
+
58
+ def interpolate(source_path, result_pattern)
59
+ parts_regex = ""
60
+ parts = absolute.split("/") # File::SEPARATOR
61
+ parts.each_with_index do |part, index|
62
+ if part == "**"
63
+ parts_regex += "((?:[^\/]+\/)*)"
64
+ else
65
+ has_captures = !!(part =~ /[\?\[\]\{\}\*]/)
66
+ part.gsub!(/\?/, ".")
67
+ part.gsub!(/([\.\\])/, "\\\\\\1")
68
+ part.gsub!(/\{([^\}]+)\}/) { "(?:" + $1.split(",").join("|") + ")" }
69
+ part.gsub!(/\*/, "[^\/]+")
70
+ parts_regex += has_captures ? "(" + part + ")" : part
71
+ parts_regex += "/" unless index == parts.size - 1
72
+ end
73
+ end
74
+ parts = source_path.to_s.match(/^#{parts_regex}$/)
75
+ result_pattern.to_s.gsub(/\*+\/?/).each_with_index { |m, i| parts[i+1] }
76
+ end
77
+
78
+ end # class
79
+ end # module
@@ -0,0 +1,21 @@
1
+ module Loki
2
+
3
+ IDENTITY_MAP = {}
4
+
5
+ module Identity
6
+ def self.included(other)
7
+ other.class_eval %{
8
+ class << self
9
+ alias_method :__#{other.to_s.gsub(':','')}_new, :new
10
+ def new(name, *args, &block)
11
+ name = self.identify(name) if self.respond_to?(:identify)
12
+ IDENTITY_MAP.fetch(name) do
13
+ IDENTITY_MAP[name] = __#{other.to_s.gsub(':','')}_new(name, *args, &block)
14
+ end
15
+ end
16
+ end
17
+ }
18
+ end
19
+ end
20
+
21
+ end # module
@@ -0,0 +1,70 @@
1
+ module Loki
2
+ class Logger
3
+ include Singleton
4
+
5
+
6
+ COLORS = {
7
+ :red => 31,
8
+ :green => 32,
9
+ :yellow => 33,
10
+ :blue => 34,
11
+ :magenta => 35,
12
+ :cyan => 36,
13
+ :white => 37,
14
+ :r => 31,
15
+ :g => 32,
16
+ :y => 33,
17
+ :b => 34,
18
+ :m => 35,
19
+ :c => 36,
20
+ :w => 37
21
+ }
22
+
23
+
24
+ def initialize
25
+ @indent = 0
26
+ end
27
+
28
+
29
+ def push
30
+ @indent += 1
31
+ end
32
+
33
+
34
+ def pull
35
+ @indent -= 1
36
+ end
37
+
38
+
39
+ def puts(text, mark = ">")
40
+ $stdout.puts((" " * @indent * 2) + "#{mark} #{parse(text)}")
41
+ end
42
+
43
+
44
+ def line
45
+ $stdout.puts("-" * 80) if @indent == 0
46
+ end
47
+
48
+
49
+ public
50
+
51
+ def paint(text, color = :white)
52
+ "\e[#{COLORS[color]}m#{text}\e[0m"
53
+ end
54
+
55
+
56
+ def parse(text)
57
+ colors = COLORS.keys.collect(&:to_s).join('|')
58
+ text.gsub(/\<(#{colors})\>(.*)\<\/\1\>/) do
59
+ paint($2, $1.to_sym)
60
+ end
61
+ end
62
+
63
+ end # class
64
+
65
+
66
+ def self.logger
67
+ @logger ||= Logger.instance
68
+ end
69
+
70
+ end # module
@@ -0,0 +1,74 @@
1
+ module Loki
2
+ module Task
3
+ class Base
4
+ attr_reader :name
5
+
6
+
7
+ def initialize(name)
8
+ @name = name
9
+ @parent = nil
10
+ end
11
+
12
+
13
+ def work(&block)
14
+ Loki.logger.puts "#{@name}"
15
+ Loki.logger.push
16
+ yield if block_given?
17
+ Loki.logger.pull
18
+ end
19
+
20
+
21
+ def time
22
+ Time.now
23
+ end
24
+
25
+
26
+ def done?
27
+ false
28
+ end
29
+
30
+
31
+ def sham?
32
+ false
33
+ end
34
+
35
+
36
+ def list(&block)
37
+ Loki.logger.line
38
+ Loki.logger.puts "#{self.class}: #{@name}, done: #{done?}, time: #{time}", "-"
39
+ Loki.logger.push
40
+ yield if block_given?
41
+ Loki.logger.pull
42
+ Loki.logger.line
43
+ end
44
+
45
+
46
+ protected
47
+
48
+ def parent
49
+ @parent
50
+ end
51
+
52
+
53
+ def parent=(parent)
54
+ @parent = parent
55
+ end
56
+
57
+
58
+ def siblings
59
+ @parent.children.reject { |task| task == self }
60
+ end
61
+
62
+
63
+ def evaluate(&block)
64
+ block_id = Loki.block_unique_id(&block)
65
+ @evaluated ||= {}
66
+ unless @evaluated.has_key?(block_id)
67
+ instance_eval(&block)
68
+ @evaluated[block_id] = true
69
+ end
70
+ end
71
+
72
+ end # class
73
+ end # module
74
+ end # module
@@ -0,0 +1,48 @@
1
+ module Loki
2
+ module Task
3
+ class File < Task
4
+ include Identity
5
+
6
+
7
+ def initialize(path)
8
+ @path = FilePath.new(path)
9
+ super(@path.relative)
10
+ end
11
+
12
+
13
+ def self.identify(name)
14
+ ::File.expand_path(name.to_s)
15
+ end
16
+
17
+
18
+ def path
19
+ @path.path
20
+ end
21
+
22
+
23
+ def done?
24
+ exists? and up_to_date? and super
25
+ end
26
+
27
+
28
+ def exists?
29
+ @path.exists?
30
+ end
31
+
32
+
33
+ def up_to_date?
34
+ @children.none? { |task| task.time > time }
35
+ end
36
+
37
+
38
+ def time
39
+ if exists?
40
+ @path.mtime
41
+ else
42
+ Loki::PRIMEVAL
43
+ end
44
+ end
45
+
46
+ end # class
47
+ end # module
48
+ end # module
@@ -0,0 +1,41 @@
1
+ module Loki
2
+ module Task
3
+ class Make < File
4
+ include Identity
5
+
6
+
7
+ def initialize(path, sources = nil)
8
+ @sources = Array(sources).map { |s| File.new(s) }
9
+ super(path)
10
+ end
11
+
12
+
13
+ def sources
14
+ @sources.collect(&:path)
15
+ end
16
+
17
+
18
+ def source_path
19
+ @sources.first.path
20
+ end
21
+
22
+
23
+ def result_path
24
+ @path.path
25
+ end
26
+
27
+
28
+ def up_to_date?
29
+ (@children + @sources).none? { |task| task.time > time }
30
+ end
31
+
32
+ def test?
33
+ @children.find_all { |task| task.time > time }.each do |o|
34
+ ap "#{o.name} #{o.time}"
35
+ end
36
+ (@children + @sources).reject(&:sham?).none? { |task| task.time > time }
37
+ end
38
+
39
+ end # class
40
+ end # module
41
+ end # module
@@ -0,0 +1,34 @@
1
+ module Loki
2
+ module Task
3
+ class Proc < Base
4
+
5
+ def initialize(name, &proc)
6
+ @proc = proc
7
+ super(name.gsub(/^#{Dir.pwd}\//, ''))
8
+ end
9
+
10
+
11
+ def work
12
+ super do
13
+ @proc.call unless @proc.nil?
14
+ end
15
+ end
16
+
17
+
18
+ def time
19
+ Loki::PRIMEVAL
20
+ end
21
+
22
+
23
+ def done?
24
+ siblings.reject(&:sham?).all?(&:done?) and @parent.done?
25
+ end
26
+
27
+
28
+ def sham?
29
+ true
30
+ end
31
+
32
+ end # class
33
+ end # module
34
+ end # module
@@ -0,0 +1,91 @@
1
+ module Loki
2
+ module Task
3
+ class Task < Base
4
+ include Identity
5
+ attr_reader :children
6
+
7
+
8
+ def initialize(name)
9
+ @children = []
10
+ super(name)
11
+ end
12
+
13
+
14
+ def task(name, &block)
15
+ add_dependency Task.new(name), &block
16
+ end
17
+
18
+
19
+ def proc(&block)
20
+ source = Loki.block_unique_id(&block)
21
+ add_dependency Proc.new(source, &block)
22
+ end
23
+
24
+
25
+ def make(result_pattern, source_pattern = nil, &block)
26
+ if source_pattern.nil?
27
+ add_dependency Make.new(result_pattern), &block
28
+ else
29
+ source_pattern = FilePattern.new(source_pattern)
30
+ result_pattern = FilePattern.new(result_pattern)
31
+ if result_pattern.individual?
32
+ add_dependency Make.new(result_pattern, source_pattern.to_a), &block
33
+ else
34
+ source_pattern.interpolate_each(result_pattern) do |source_path, result_path|
35
+ add_dependency Make.new(result_path, source_path), &block
36
+ end
37
+ end
38
+ end
39
+ end
40
+
41
+
42
+ def scan(dependencies, &block)
43
+ dependencies = Dir.glob(dependencies) if dependencies.is_a?(String)
44
+ dependencies.each do |dependency|
45
+ add_dependency(File.new(dependency), &block)
46
+ end
47
+ end
48
+
49
+
50
+ def work
51
+ super do
52
+ @children.each do |task|
53
+ task.work unless task.done?
54
+ end
55
+ end
56
+ end
57
+
58
+
59
+ def done?
60
+ @children.reject(&:sham?).all?(&:done?)
61
+ end
62
+
63
+
64
+ def time
65
+ @children.collect(&:time).max || super
66
+ end
67
+
68
+
69
+ def list
70
+ super do
71
+ @children.each do |task|
72
+ task.list
73
+ end
74
+ end
75
+ end
76
+
77
+
78
+ protected
79
+
80
+ def add_dependency(task, &block)
81
+ unless children.include?(task)
82
+ task.parent = self
83
+ children << task
84
+ task.evaluate(&block) if block_given?
85
+ end
86
+ task
87
+ end
88
+
89
+ end # class
90
+ end # module
91
+ end # module
@@ -0,0 +1,46 @@
1
+ require 'singleton'
2
+
3
+
4
+ module Loki
5
+ class Primeval
6
+ include Comparable
7
+ include Singleton
8
+
9
+
10
+ def <=>(other)
11
+ -1
12
+ end
13
+
14
+
15
+ def to_s
16
+ "<Primeval>"
17
+ end
18
+
19
+
20
+ def strftime(*args)
21
+ "<Primeval>"
22
+ end
23
+ end
24
+
25
+
26
+ PRIMEVAL = Primeval.instance
27
+ end
28
+
29
+
30
+ class Time
31
+
32
+ alias loki_original_compare :<=>
33
+ def <=>(other)
34
+ if Loki::Primeval === other
35
+ - other.<=>(self)
36
+ else
37
+ loki_original_compare(other)
38
+ end
39
+ end
40
+
41
+
42
+ def to_s
43
+ strftime("%m-%d-%Y %H:%M:%S")
44
+ end
45
+
46
+ end
@@ -0,0 +1,3 @@
1
+ module Loki
2
+ VERSION = "0.0.2"
3
+ end
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "loki/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "loki"
7
+ s.version = Loki::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Patrick Hogan"]
10
+ s.email = ["pbhogan@gmail.com"]
11
+ s.homepage = "https://github.com/pbhogan/loki"
12
+ s.summary = "A highly experimental and simplistic Rake-like DSL."
13
+ s.description = s.summary
14
+
15
+ # s.rubyforge_project = "loki"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+ end
metadata ADDED
@@ -0,0 +1,77 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: loki
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.2
6
+ platform: ruby
7
+ authors:
8
+ - Patrick Hogan
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-06-24 00:00:00 Z
14
+ dependencies: []
15
+
16
+ description: A highly experimental and simplistic Rake-like DSL.
17
+ email:
18
+ - pbhogan@gmail.com
19
+ executables:
20
+ - loki
21
+ extensions: []
22
+
23
+ extra_rdoc_files: []
24
+
25
+ files:
26
+ - .gitignore
27
+ - Gemfile
28
+ - Rakefile
29
+ - bin/loki
30
+ - lib/loki.rb
31
+ - lib/loki/file_path.rb
32
+ - lib/loki/file_pattern.rb
33
+ - lib/loki/identity.rb
34
+ - lib/loki/logger.rb
35
+ - lib/loki/task/base.rb
36
+ - lib/loki/task/file.rb
37
+ - lib/loki/task/make.rb
38
+ - lib/loki/task/proc.rb
39
+ - lib/loki/task/task.rb
40
+ - lib/loki/time.rb
41
+ - lib/loki/version.rb
42
+ - loki.gemspec
43
+ homepage: https://github.com/pbhogan/loki
44
+ licenses: []
45
+
46
+ post_install_message:
47
+ rdoc_options: []
48
+
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ hash: -3930385297513677759
57
+ segments:
58
+ - 0
59
+ version: "0"
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ hash: -3930385297513677759
66
+ segments:
67
+ - 0
68
+ version: "0"
69
+ requirements: []
70
+
71
+ rubyforge_project:
72
+ rubygems_version: 1.8.5
73
+ signing_key:
74
+ specification_version: 3
75
+ summary: A highly experimental and simplistic Rake-like DSL.
76
+ test_files: []
77
+