ki-repo 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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