ki-repo 0.1.1 → 0.1.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.
@@ -1,6 +1,6 @@
1
1
  # encoding: UTF-8
2
2
 
3
- # Copyright 2012 Mikko Apo
3
+ # Copyright 2012-2013 Mikko Apo
4
4
  #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
6
6
  # you may not use this file except in compliance with the License.
@@ -1,6 +1,6 @@
1
1
  # encoding: UTF-8
2
2
 
3
- # Copyright 2012 Mikko Apo
3
+ # Copyright 2012-2013 Mikko Apo
4
4
  #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
6
6
  # you may not use this file except in compliance with the License.
@@ -1,6 +1,6 @@
1
1
  # encoding: UTF-8
2
2
 
3
- # Copyright 2012 Mikko Apo
3
+ # Copyright 2012-2013 Mikko Apo
4
4
  #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
6
6
  # you may not use this file except in compliance with the License.
@@ -104,14 +104,14 @@ module Ki
104
104
  end
105
105
 
106
106
  def import_from_metadata(metadata, source=nil)
107
- if defined?(@specific_version_id) && defined?(@create_new_version)
107
+ if specific_version_id && create_new_version
108
108
  raise "Can't define both specific_version_id '#{specific_version_id}' and create_new_version '#{create_new_version}'!"
109
109
  end
110
110
 
111
- if defined?(@specific_version_id)
112
- version_id = @specific_version_id
113
- elsif defined? @create_new_version
114
- component_id = @create_new_version
111
+ if specific_version_id
112
+ version_id = specific_version_id
113
+ elsif create_new_version
114
+ component_id = create_new_version
115
115
  version = finder.version(component_id)
116
116
  if version
117
117
  id = version.version_id.split("/").last
@@ -140,7 +140,7 @@ module Ki
140
140
  metadata_dir.metadata.cached_data = metadata.cached_data
141
141
  metadata_dir.metadata.version_id = version_id
142
142
  metadata_dir.metadata.save
143
- if defined? @move_files
143
+ if move_files
144
144
  FileUtils.rm(metadata.path)
145
145
  end
146
146
  source_dirs = []
@@ -158,7 +158,7 @@ module Ki
158
158
 
159
159
 
160
160
  def delete_empty_source_dirs(source, source_dirs)
161
- if defined? @move_files
161
+ if move_files
162
162
  expanded_source_dirs = {}
163
163
  source_dirs.each do |d|
164
164
  dir_entries(d).each do |expanded|
@@ -179,7 +179,7 @@ module Ki
179
179
  arr = str.split("/")
180
180
  ret = []
181
181
  c = arr.size
182
- while (c > 0)
182
+ while c > 0
183
183
  ret << File.join(arr[0..c])
184
184
  c-=1
185
185
  end
@@ -187,7 +187,7 @@ module Ki
187
187
  end
188
188
 
189
189
  def to_repo(src, dest)
190
- if defined? @move_files
190
+ if move_files
191
191
  FileUtils.mv(src, dest)
192
192
  else
193
193
  FileUtils.cp(src, dest)
@@ -223,7 +223,7 @@ module Ki
223
223
  if dir != "."
224
224
  FileUtils.mkdir_p File.join(out, dir)
225
225
  end
226
- if defined? @copy
226
+ if copy
227
227
  FileUtils.cp(full_path, File.join(out, file_path))
228
228
  else
229
229
  FileUtils.ln_sf(full_path, File.join(out, file_path))
@@ -1,6 +1,6 @@
1
1
  # encoding: UTF-8
2
2
 
3
- # Copyright 2012 Mikko Apo
3
+ # Copyright 2012-2013 Mikko Apo
4
4
  #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
6
6
  # you may not use this file except in compliance with the License.
@@ -25,7 +25,7 @@ module Ki
25
25
  attr_chain :finder, -> { version.component.finder }
26
26
  attr_chain :block
27
27
  attr_chain :internals
28
- attr_chain :exclude_dependencies, -> { [] }, :convert => lambda { |list| Array.wrap(list).map { |s| /#{s}/ } }
28
+ attr_chain :exclude_dependencies, -> { [] }, :convert => lambda { |list| Array(list).map { |s| /#{s}/ } }
29
29
 
30
30
  def iterate_versions(&block)
31
31
  start_iteration do |version_iterator|
@@ -80,10 +80,10 @@ module Ki
80
80
  end
81
81
 
82
82
  class FileFinder < VersionIterator
83
- attr_chain :files, -> { [] }, :convert => lambda { |list| Array.wrap(list).map { |s| FileRegexp.matcher(s) } }
84
- attr_chain :exclude_files, -> { [] }, :convert => lambda { |list| Array.wrap(list).map { |s| FileRegexp.matcher(s) } }
85
- attr_chain :tags, -> { [] }, :convert => lambda { |list| Array.wrap(list)}
86
- attr_chain :exclude_tags, -> { [] }, :convert => lambda { |list| Array.wrap(list)}
83
+ attr_chain :files, -> { [] }, :convert => lambda { |list| Array(list).map { |s| FileRegexp.matcher(s) } }
84
+ attr_chain :exclude_files, -> { [] }, :convert => lambda { |list| Array(list).map { |s| FileRegexp.matcher(s) } }
85
+ attr_chain :tags, -> { [] }, :convert => lambda { |list| Array(list)}
86
+ attr_chain :exclude_tags, -> { [] }, :convert => lambda { |list| Array(list)}
87
87
 
88
88
  def file_map
89
89
  start_iteration do |ver_iterator|
@@ -1,6 +1,6 @@
1
1
  # encoding: UTF-8
2
2
 
3
- # Copyright 2012 Mikko Apo
3
+ # Copyright 2012-2013 Mikko Apo
4
4
  #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
6
6
  # you may not use this file except in compliance with the License.
@@ -1,6 +1,6 @@
1
1
  # encoding: UTF-8
2
2
 
3
- # Copyright 2012 Mikko Apo
3
+ # Copyright 2012-2013 Mikko Apo
4
4
  #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
6
6
  # you may not use this file except in compliance with the License.
@@ -15,9 +15,25 @@
15
15
  # limitations under the License.
16
16
 
17
17
  module Ki
18
- module DirectoryBaseModule
18
+
19
+ class DirectoryBase
19
20
  attr_chain :parent, :require
20
21
 
22
+ def initialize(path)
23
+ init_from_path(path)
24
+ end
25
+
26
+ def self.find!(path, *locations)
27
+ locations.each do |loc|
28
+ dest = loc.go(path)
29
+ if dest.exists?
30
+ return dest
31
+ end
32
+ end
33
+ raise "Could not find '#{path}' from '#{locations.map { |l| l.path }.join("', '")}'"
34
+ end
35
+
36
+
21
37
  def init_from_path(path)
22
38
  @path = path
23
39
  end
@@ -84,23 +100,9 @@ module Ki
84
100
  def child(name)
85
101
  DirectoryBase.new(name)
86
102
  end
87
- end
88
-
89
- class DirectoryBase
90
- include DirectoryBaseModule
91
-
92
- def initialize(path)
93
- init_from_path(path)
94
- end
95
103
 
96
- def self.find!(path, *locations)
97
- locations.each do |loc|
98
- dest = loc.go(path)
99
- if dest.exists?
100
- return dest
101
- end
102
- end
103
- raise "Could not find '#{path}' from '#{locations.map { |l| l.path }.join("', '")}'"
104
+ def empty?(*sub_path)
105
+ Dir.entries(go(*sub_path).path).size == 2
104
106
  end
105
107
  end
106
108
  end
@@ -1,6 +1,6 @@
1
1
  # encoding: UTF-8
2
2
 
3
- # Copyright 2012 Mikko Apo
3
+ # Copyright 2012-2013 Mikko Apo
4
4
  #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
6
6
  # you may not use this file except in compliance with the License.
@@ -1,6 +1,6 @@
1
1
  # encoding: UTF-8
2
2
 
3
- # Copyright 2012 Mikko Apo
3
+ # Copyright 2012-2013 Mikko Apo
4
4
  #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
6
6
  # you may not use this file except in compliance with the License.
@@ -71,7 +71,9 @@ module Ki
71
71
 
72
72
  def add_item(obj)
73
73
  edit_data do
74
- @cached_data << obj
74
+ if !@cached_data.include?(obj)
75
+ @cached_data << obj
76
+ end
75
77
  end
76
78
  create_list_item(obj)
77
79
  end
@@ -1,6 +1,6 @@
1
1
  # encoding: UTF-8
2
2
 
3
- # Copyright 2012 Mikko Apo
3
+ # Copyright 2012-2013 Mikko Apo
4
4
  #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
6
6
  # you may not use this file except in compliance with the License.
@@ -1,6 +1,6 @@
1
1
  # encoding: UTF-8
2
2
 
3
- # Copyright 2012 Mikko Apo
3
+ # Copyright 2012-2013 Mikko Apo
4
4
  #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
6
6
  # you may not use this file except in compliance with the License.
@@ -29,16 +29,6 @@ module Ki
29
29
  attr_chain :operations, -> { Array.new }, :accessor => CachedData
30
30
  attr_chain :dependencies, -> { Array.new }, :accessor => CachedData
31
31
 
32
- def add_file_info(name, size, *args)
33
- extra = (args.select { |arg| arg.kind_of?(Hash) }.size!(0..1).first or {})
34
- tags = (args - [extra]).flatten.uniq
35
- file_hash = {"path" => name, "size" => size}.merge(extra)
36
- if tags.size > 0
37
- file_hash["tags"]=tags
38
- end
39
- files << file_hash
40
- end
41
-
42
32
  # Comma separated list of dependency arguments
43
33
  # * dependency parameters can be given in the hash
44
34
  # TODO: version_id should be resolved through Version
@@ -58,41 +48,27 @@ module Ki
58
48
  operations << args
59
49
  end
60
50
 
61
- def VersionMetadataFile.calculate_hashes(full_path, digester_ids)
62
- digesters = {}
63
- digester_ids.each do |h|
64
- digesters[h] = KiCommand::KiExtensions.find!(File.join("/hashing", h)).digest
65
- end
66
- algos = digesters.values
67
- File.open(full_path, "r") do |io|
68
- while (!io.eof)
69
- buf = io.readpartial(1024)
70
- algos.each do |digester|
71
- digester.update(buf)
72
- end
73
- end
74
- end
75
- digesters.each_pair do |h, digester|
76
- digesters[h]=digester.hexdigest
77
- end
78
- digesters
79
- end
80
-
81
51
  # Processes all files from source that match patterns and for each file calculates hashes and stores tags based on default_parameters
82
52
  def add_files(source, patterns, default_parameters={})
83
- files_or_dirs = Array.wrap(patterns).map do |pattern|
53
+ files_or_dirs = Array(patterns).map do |pattern|
84
54
  Dir.glob(File.join(source, pattern))
85
55
  end.flatten
86
56
 
87
- files = files_or_dirs.map do |file_or_dir|
88
- if File.directory?(file_or_dir)
89
- Dir.glob(File.join(file_or_dir, "**/*"))
57
+ files = []
58
+
59
+ files_or_dirs.each do |file_or_dir|
60
+ if File.file?(file_or_dir)
61
+ files << file_or_dir
90
62
  else
91
- file_or_dir
63
+ Dir.glob(File.join(file_or_dir, "**/*")).each do |file|
64
+ if File.file?(file)
65
+ files << file
66
+ end
67
+ end
92
68
  end
93
- end.flatten.sort
69
+ end
94
70
 
95
- files.each do |file|
71
+ files.sort.each do |file|
96
72
  add_file(source, file, default_parameters)
97
73
  end
98
74
  self
@@ -106,7 +82,7 @@ module Ki
106
82
  extra["executable"]=true
107
83
  end
108
84
  if parameters["tags"]
109
- tags = Array.wrap(parameters["tags"])
85
+ tags = Array(parameters["tags"])
110
86
  if tags && tags.size > 0
111
87
  extra["tags"]= tags
112
88
  end
@@ -119,6 +95,45 @@ module Ki
119
95
  end
120
96
  add_file_info(full_path[root.size+1..-1], size, extra)
121
97
  end
98
+
99
+ def add_file_info(name, size, *args)
100
+ extra = (args.select { |arg| arg.kind_of?(Hash) }.size!(0..1).first or {})
101
+ tags = (args - [extra]).flatten.uniq
102
+ file_hash = {"path" => name, "size" => size}.merge(extra)
103
+ if tags.size > 0
104
+ file_hash["tags"]=tags
105
+ end
106
+ files.each do |f|
107
+ if f["path"] == name
108
+ if f == file_hash
109
+ return
110
+ else
111
+ raise "'#{name}' has already been added to version, but with different attributes:\n- old: #{f.inspect}\n- new: #{file_hash.inspect}"
112
+ end
113
+ end
114
+ end
115
+ files << file_hash
116
+ end
117
+
118
+ def VersionMetadataFile.calculate_hashes(full_path, digester_ids)
119
+ digesters = {}
120
+ digester_ids.each do |h|
121
+ digesters[h] = KiCommand::KiExtensions.find!(File.join("/hashing", h)).digest
122
+ end
123
+ algos = digesters.values
124
+ File.open(full_path, "r") do |io|
125
+ while (!io.eof)
126
+ buf = io.readpartial(1024)
127
+ algos.each do |digester|
128
+ digester.update(buf)
129
+ end
130
+ end
131
+ end
132
+ digesters.each_pair do |h, digester|
133
+ digesters[h]=digester.hexdigest
134
+ end
135
+ digesters
136
+ end
122
137
  end
123
138
 
124
139
  module DependencyMethods
data/lib/ki_repo_all.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # encoding: UTF-8
2
2
 
3
- # Copyright 2012 Mikko Apo
3
+ # Copyright 2012-2013 Mikko Apo
4
4
  #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
6
6
  # you may not use this file except in compliance with the License.
@@ -23,7 +23,9 @@ require_relative 'util/test'
23
23
  require_relative 'util/service_registry'
24
24
  require_relative 'util/hash'
25
25
  require_relative 'util/hash_cache'
26
+ require_relative 'util/hash_log'
26
27
  require_relative 'util/simple_optparse'
28
+ require_relative 'util/shell'
27
29
 
28
30
  require_relative 'data_storage/dir_base'
29
31
  require_relative 'data_storage/ki_json'
@@ -40,3 +42,7 @@ require_relative 'data_access/version_iterators'
40
42
  require_relative 'cmd/cmd'
41
43
  require_relative 'cmd/version_cmd'
42
44
  require_relative 'cmd/user_pref_cmd'
45
+
46
+ require_relative 'web/default_rack_handler'
47
+ require_relative 'web/rack_cmd'
48
+ require_relative 'web/test_browser'
@@ -1,6 +1,6 @@
1
1
  # encoding: UTF-8
2
2
 
3
- # Copyright 2012 Mikko Apo
3
+ # Copyright 2012-2013 Mikko Apo
4
4
  #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
6
6
  # you may not use this file except in compliance with the License.
@@ -45,7 +45,7 @@
45
45
  # * :default makes it easy to isolate functionality to a default value while still making it easy to override the default behaviour
46
46
  # * :default adds easy lazy evalution and memoization to the attribute, default value is evaluated only if needed
47
47
  # * Testing becomes easier when objects have more exposed fields
48
- # * :require converts tricky nil exceptions in to useful errors. Instead of the "undefined method `bar' for nil:NilClass" you get a good error message that states which field was not defined
48
+ # * :require converts tricky nil exceptions in to useful errors. Instead of the "undefined method 'bar' for nil:NilClass" you get a good error message that states which field was not defined
49
49
  # foo.name.bar # if name has not been defined, raises "'name' has not been set" exception
50
50
  # * :immutable, :valid and :convert make complex validations and converts easy
51
51
  #
@@ -1,6 +1,6 @@
1
1
  # encoding: UTF-8
2
2
 
3
- # Copyright 2012 Mikko Apo
3
+ # Copyright 2012-2013 Mikko Apo
4
4
  #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
6
6
  # you may not use this file except in compliance with the License.
data/lib/util/hash.rb CHANGED
@@ -1,6 +1,6 @@
1
1
  # encoding: UTF-8
2
2
 
3
- # Copyright 2012 Mikko Apo
3
+ # Copyright 2012-2013 Mikko Apo
4
4
  #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
6
6
  # you may not use this file except in compliance with the License.
@@ -1,6 +1,6 @@
1
1
  # encoding: UTF-8
2
2
 
3
- # Copyright 2012 Mikko Apo
3
+ # Copyright 2012-2013 Mikko Apo
4
4
  #
5
5
  # Licensed under the Apache License, Version 2.0 (the "License");
6
6
  # you may not use this file except in compliance with the License.
@@ -0,0 +1,93 @@
1
+ # encoding: UTF-8
2
+
3
+ # Copyright 2012-2013 Mikko Apo
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+
17
+ module Ki
18
+ # Generate hash object based log entries.
19
+ # @see log
20
+ module HashLog
21
+ HashLogThreadCurrentKey = :hash_log
22
+ HashLogMutex = Mutex.new
23
+
24
+ # Create a hash log entry or return current hash log entry
25
+ # * Supports hierarchic logs, where log entry can contain any number of sub entries
26
+ # * Supports parallel execution, threads can log in to one log structure
27
+ # * Logs start and stop time of execution
28
+ #
29
+ # Hierarchic logging works by keeping a stack of log entries in Thread local store
30
+ #
31
+ # @see set_hash_log_root_for_thread
32
+ # @see hash_log_current
33
+ def log(*args, &block)
34
+ current_log_entry = hash_log_current
35
+ # return
36
+ if args.empty? && block.nil?
37
+ current_log_entry
38
+ else
39
+ new_entry = {"start" => Time.now}
40
+ if args.first.kind_of?(String)
41
+ new_entry["name"] = args.delete_at(0)
42
+ end
43
+ if args.first.kind_of?(Hash)
44
+ new_entry.merge!(args.first)
45
+ end
46
+ log_list = nil
47
+ if current_log_entry
48
+ # there is current log entry, create a new sub log entry
49
+ HashLogMutex.synchronize do
50
+ log_list = current_log_entry["logs"] ||= []
51
+ end
52
+ else
53
+ # append new_entry to end of log list
54
+ log_list = Thread.current[HashLogThreadCurrentKey]
55
+ end
56
+ HashLogMutex.synchronize do
57
+ log_list << new_entry
58
+ end
59
+ if block
60
+ HashLogMutex.synchronize do
61
+ Thread.current[HashLogThreadCurrentKey] << new_entry
62
+ end
63
+ begin
64
+ block.call new_entry
65
+ rescue Exception => e
66
+ new_entry["exception"] = e.message
67
+ new_entry["backtrace"] = e.backtrace.join("\n")
68
+ raise
69
+ ensure
70
+ HashLogMutex.synchronize do
71
+ Thread.current[HashLogThreadCurrentKey].delete(new_entry)
72
+ end
73
+ new_entry["end"] = Time.now
74
+ end
75
+ else
76
+ new_entry
77
+ end
78
+ end
79
+ end
80
+
81
+ def set_hash_log_root_for_thread(root)
82
+ HashLogMutex.synchronize do
83
+ (Thread.current[HashLogThreadCurrentKey] ||= []) << root
84
+ end
85
+ end
86
+
87
+ def hash_log_current
88
+ HashLogMutex.synchronize do
89
+ (Thread.current[HashLogThreadCurrentKey] ||= []).last
90
+ end
91
+ end
92
+ end
93
+ end