loki 0.0.2

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.
@@ -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
+