kit 0.0.6 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2011 Evan Boyd Sosenko
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,54 @@
1
+ = Kit
2
+
3
+ == What is Kit?
4
+
5
+ Kit is a framework for making simple management tools called kits. Each kit keeps track of a set of objects (the bits) and info about them. Actions of different types can be queued as tasks and run separately. Bits are put into groups so that code for each action type can be different for each group. The tasks are stored in a seperate database, so the permissions for adding tasks and managing bit meta information can be set separately.
6
+
7
+ == Using Kit
8
+
9
+ To use Kit, you fist need a kit. You can download a {pre-build kit}[https://github.com/razor-x/kit/wiki/Pre-built-kits] or {build your own kit}[https://github.com/razor-x/kit/wiki/Building-your-own-kit]. Once you have a kit, create a new kit object with
10
+
11
+ k = Kit.new "/path_to/config.yml"
12
+
13
+ where the config file is either the default config file included with the kit, or your own that may override some of the defaults. Now you can start adding bits and queuing and running tasks:
14
+
15
+ bit = { :name => "foo", :group_name => "bar" }
16
+ k.add_bit bit
17
+
18
+ { :baz => { :bit => 1 } }.each do |action, options|
19
+ k.add_task action, options
20
+ end
21
+
22
+ k.run_tasks
23
+
24
+ For more information on what methods are available see the {YARD documentation}[https://rubygems.org/gems/kit] which is hosted at RubyGems.org. For more detailed information on how to use Kit, check out the wiki[https://github.com/razor-x/kit/wiki].
25
+
26
+ == Installation
27
+
28
+ === Gem Installation
29
+
30
+ Download and install Kit with
31
+
32
+ gem install kit
33
+
34
+ == Development
35
+
36
+ === Source Repository
37
+
38
+ Kit is currently hosted at github. The github web page is
39
+ https://github.com/razor-x/kit. To clone the project run
40
+
41
+ git clone git://github.com/razor-x/kit.git
42
+
43
+ After cloning, you should run yard to generate documentation for the source.
44
+
45
+ == License
46
+
47
+ Kit is licensed under the MIT license.
48
+
49
+ == Warranty
50
+
51
+ This software is provided "as is" and without any express or
52
+ implied warranties, including, without limitation, the implied
53
+ warranties of merchantibility and fitness for a particular
54
+ purpose.
data/lib/kit.rb CHANGED
@@ -1,58 +1,71 @@
1
1
  require 'yaml'
2
2
 
3
+ # Primary class for Kit.
3
4
  class Kit
5
+
6
+ require 'kit/bit'
7
+
8
+ # Exceptions.
9
+
10
+ # Raised when an action is specified that is not in the defined actions for the kit.
11
+ class NoAction < RuntimeError
12
+ end
13
+
4
14
  # Loads the settings for the kit.
5
15
  # @param [String, Hash] config path to kit config file or hash of kit settings
6
16
  def initialize config
7
-
17
+ # Load the config and merge with the default config.
8
18
  config = load_config_file config if File.exists? config
9
19
 
10
20
  fail "No path to kit set" unless config[:kits_path]
11
21
 
12
22
  @@kit_path = config[:kits_path]
13
-
14
23
  defaults = YAML.load File.read @@kit_path + "/config.yml"
15
24
  config = defaults.merge config
16
25
 
26
+ # Load backend for selected database type.
17
27
  load 'kit/db_sqlite3.rb' if config[:db_backend] == :sqlite3
18
28
 
19
- load @@kit_path + "/bit.rb"
29
+ # Load class files for the kit
30
+ begin
31
+ load @@kit_path + "/bit.rb"
32
+ load @@kit_path + "/kit.rb"
33
+ rescue LoadError
34
+ end
20
35
 
21
- @@db = Backend.new config[:db_config]
36
+ # Set the class variables.
22
37
  @@info = config[:info]
38
+ @@unique = config[:unique]
23
39
  @@actions = config[:actions]
40
+ @@status_types = [ :pending, :completed, :queued ]
41
+ @@db = Backend.new config[:db_config]
42
+
43
+ # Run initialization specific to the kit.
44
+ begin
45
+ self.kit_initialize
46
+ rescue NoMethodError
47
+ end
24
48
  end
25
49
 
50
+ # Kit related methods.
51
+
52
+ # @return [Hash] names of actions defined for this kit
26
53
  def action_types
27
54
  @@actions.keys
28
55
  end
29
56
 
30
- # Converts a kit config file into a hash of kit settings.
31
- # @param [String] file path to a kit config file in yaml format
32
- # @return [Hash] kit settings
33
- def load_config_file file
34
-
35
- config = YAML.load File.read file
36
- @@config_path = File.absolute_path File.dirname file
37
-
38
- dir = config[:kits_path]
39
- dir = if config[:kits_path].nil?
40
- @@config_path
41
- else
42
- File.absolute_path @@config_path + config[:kits_path] unless [ "/", "~" ].include? config[:kits_path][0]
43
- end
44
-
45
- config[:kits_path] = dir
46
- return config
57
+ # @return [Array] names of task status types defined for this kit
58
+ def status_types
59
+ @@status_types
47
60
  end
48
61
 
49
- # Deletes the kit's databases
62
+ # Deletes the kit's databases.
50
63
  def delete_dbs
51
- @@db.db_paths.each do |key, f|
52
- File.delete f
53
- end
64
+ @@db.delete
54
65
  end
55
66
 
67
+ # Bit related methods.
68
+
56
69
  # Creates bit object if it is unique enough.
57
70
  # @param [Hash] info requested initial properties of the bit
58
71
  # @return [Bit, nil] the new bit or nil if too similar to a bit that already exists
@@ -64,35 +77,52 @@ class Kit
64
77
  end
65
78
  end
66
79
 
80
+ # Gets a bit that matches id or info.
81
+ # @param [Integer, Hash] bit id or hash of info unique enough to identify a bit
82
+ # @return [Bit, nil] the Bit or nil if no unique bit could be found
67
83
  def get_bit info
68
84
  begin
69
85
  if info.is_a? Integer
70
86
  Bit.new info
71
- elsif info_is_a? Hash
87
+ elsif info.is_a? Hash
72
88
  Bit.new Bit::lookup_id info
73
89
  end
74
- rescue NoElement
90
+ rescue Bit::NoElement
75
91
  nil
76
92
  end
77
93
  end
78
94
 
95
+ # Task related methods.
96
+
97
+ # Gets all tasks with requested status for one action type.
98
+ # @param [Symbol] name of action type to get tasks for
99
+ # @param [Symbol] task status
100
+ # @return [Array] tasks for given action type with requested status
101
+ def get_tasks_by_status action, status
102
+ @@db.select_all_actions_by_status action, @@actions[action], status
103
+ end
104
+
79
105
  # Adds a new task to the corresponding action table.
80
106
  # @param [Symbol] action name of the action type
81
107
  # @param [Hash] options options for the corresponding action type
82
108
  def add_task action, options
83
- fail NoAction unless @@actions.include? action
84
- @@db.insert_action action, options
109
+ begin
110
+ fail NoAction, "#{action}" unless @@actions.include? action
111
+ @@db.insert_action action, options
112
+ rescue NoAction => ex
113
+ puts "Could not add task: no such action: '#{ex.message}'."
114
+ end
85
115
  end
86
116
 
87
117
  # Runs all pending tasks.
88
118
  def run_tasks
89
119
  collect_tasks_by_bit.each do |bit, tasks|
90
- b = Bit.new bit
120
+ b = get_bit bit
121
+ next if b.nil?
91
122
 
92
123
  actions = tasks.group_by { |t| t[:action] } . keys
93
-
94
124
  actions.each do |a|
95
- load @@kit_path + "/#{a}/#{b.project_name}.rb"
125
+ load @@kit_path + "/actions/#{b.group_name}/#{a}.rb"
96
126
  b.extend Actions
97
127
  end
98
128
 
@@ -101,31 +131,42 @@ class Kit
101
131
  end
102
132
 
103
133
  b.run_all
104
- # TODO try and use yields here to set status to running and then complete / failed as each task runs and finishes
134
+ # TODO try and use blocks here to set status to running and then complete / failed as each task runs and finishes
105
135
  end
106
136
  end
107
137
 
108
- def get_tasks_by_status action, status
109
- @@db.select_all_actions_by_status action, @@actions[action], status
110
- end
111
-
112
138
  private
113
- # Gets all tasks and groups them by bit.
139
+ # Gets all pending tasks with requested status and groups them by bit.
114
140
  # @return [Hash{Integer => Hash}] tasks grouped by bit id
115
141
  def collect_tasks_by_bit
116
-
117
142
  tasks = []
118
143
  @@actions.each_key do |action|
119
144
  tasks.push get_tasks_by_status action, :pending
120
145
  end
121
146
  tasks.flatten!
122
-
123
147
  tasks.group_by { |t| t[:bit] }
124
148
  end
125
149
 
126
- class NoAction < StandardError
127
- end
150
+ # Converts a kit config file into a hash of kit settings.
151
+ # @param [String] file path to a kit config file in YAML format
152
+ # @return [Hash] kit settings
153
+ def load_config_file file
154
+
155
+ # Load the file using YAML.
156
+ config = YAML.load File.read file
157
+ @@config_path = File.absolute_path File.dirname file
158
+
159
+ # Determine the path to the kit.
160
+ config[:kits_path] = \
161
+ if config[:kits_path].nil?
162
+ @@config_path
163
+ elsif ! [ "/", "~" ].include? config[:kits_path][0]
164
+ File.absolute_path @@config_path + config[:kits_path]
165
+ else
166
+ config[:kits_path]
167
+ end
128
168
 
129
- end
169
+ return config
170
+ end
130
171
 
131
- require 'kit/bit'
172
+ end
@@ -1,45 +1,133 @@
1
+ # Class to manage individual bits.
1
2
  class Bit < Kit
2
3
 
4
+ # Exceptions.
5
+
6
+ # Raised when element exists but was not expected.
7
+ class DuplicateElement < RuntimeError
8
+ end
9
+
10
+ # Raised when no element exists.
11
+ class NoElement < RuntimeError
12
+ end
13
+
14
+ # Raised when not enough info is given to perform the operation.
15
+ class MissingValues < RuntimeError
16
+ end
17
+
3
18
  attr_reader :id
4
19
 
5
- # Loads all bit info from database, or attempts to add new bit to database
20
+ # Loads all bit info from database, or attempts to add new bit to database.
21
+ # Raises a TypeError if not given an integer or hash.
6
22
  # @param [Integer, Hash] info id of bit or info for new bit
7
23
  def initialize info
24
+ @id = \
25
+ if info.is_a? Integer
26
+ info
27
+ elsif info.is_a? Hash
28
+ info.each do |key, value|
29
+ instance_variable_set "@#{key}", value
30
+ end
31
+ g = @group_name if @group_name
32
+ g = @group_id if @group_id
33
+ self.group = g, info
34
+ insert_new
35
+ else
36
+ fail TypeError
37
+ end
38
+ load_info
39
+ end
8
40
 
9
- @id = if info.is_a? Integer
10
- info
11
- else
12
- make_ivars info
13
- insert_new
14
- end
41
+ private
42
+
43
+ # Add support fot the dynamic instance variables.
44
+ class ::Array
45
+ # Makes a hash that maps symbols in the array to instance variable values.
46
+ # @param [Object] obj the object with the instance variables to use
47
+ # @param [Array] exclude instance variables named in this array as symbols are excluded from the hash
48
+ # @return [Hash] mapping of symbols in the array to instance variable values
49
+ def hash_ivars obj, exclude = []
50
+ h = {}
51
+ self.each do |x|
52
+ h[x] = obj.instance_variable_get "@#{x}" unless exclude.include? x
53
+ end
54
+ return h
55
+ end
56
+ end
15
57
 
16
- load_info
58
+ # Set group by name or id.
59
+ # @param [Integer, String] group id or info for group
60
+ def group= group
61
+ @group_id = group if group.is_a? Integer
62
+ @group_name = group if group.is_a? String
17
63
 
64
+ if @group_id.nil?
65
+ g = @@db.select_info_by_name :groups, [ :rowid ], @group_name
66
+ @group_id = if g.nil? then insert_new_group else g[:rowid] end
67
+ end
18
68
  end
19
69
 
20
- # Sets instance variables for each key => value pair
21
- def make_ivars hash
22
- hash.each do |ivar, val|
23
- self.class.send :attr_accessor, ivar unless respond_to? ivar
24
- send "#{ivar}=", val
70
+ # Inserts a new bit into the database using the availible instance variables.
71
+ # Raises a MissingValues if required values are not given.
72
+ # Raises a DuplicateElement if a bit with unique values already exists.
73
+ def insert_new
74
+ uniq = @@unique[:bits].hash_ivars self
75
+ uniq.each { |x| fail MissingValues if x.nil? }
76
+
77
+ fail DuplicateElement if lookup_id uniq
78
+
79
+ data = @@info[:bits].hash_ivars self, [ :rowid ]
80
+ @@db.insert_info :bits, data
81
+ end
82
+
83
+ # (see #insert_new)
84
+ def insert_new_group
85
+ fail MissingValues if @group_name.nil?
86
+ fail DuplicateElement if @@db.select_info_by_name :groups, @@unique[:groups], @group_name
87
+
88
+ data = @@info[:groups].hash_ivars self, [ :rowid, :name ]
89
+ data[:name] = @group_name
90
+
91
+ @@db.insert_info :groups, data
92
+ end
93
+
94
+ # Loads all bit info from the database into instance variables.
95
+ def load_info
96
+ fail MissingValues if @id.nil?
97
+ info = @@db.select_info_by_id :bits, @@info[:bits], @id
98
+ fail NoElement unless info
99
+
100
+ group_info = @@db.select_info_by_id :groups, @@info[:groups], info[:group_id]
101
+ info[:group_name] = group_info[:name]
102
+ group_info.delete :rowid
103
+ group_info.delete :name
104
+
105
+ info.merge! group_info
106
+ info.delete :rowid
107
+
108
+ info.each do |key, value|
109
+ instance_variable_set "@#{key}", value
110
+ self.class.send :attr_reader, key
111
+ self.class.send :public, key
25
112
  end
26
113
  end
27
114
 
28
- # Add a task to the array of pending tasks in @tasks.
115
+ public
116
+ # Add a task to the array of pending tasks.
29
117
  # @param [Hash] task info for task
30
118
  def queue_task task
31
119
  @tasks = [] unless @tasks
32
120
  @tasks << task
33
121
  end
34
122
 
35
- def clear_task task
123
+ # def clear_task task
36
124
  # action = task[:action]
37
125
  # id = task[:rowid]
38
126
  #
39
127
  # @@db.delete_action_by_id action, id
40
- end
128
+ # end
41
129
 
42
- # Runs all tasks in the list of pending tasks in @tasks and returns the status of each run task.
130
+ # Runs all tasks in the list of pending tasks and returns the status of each run task.
43
131
  # @return [Hash] key is task id
44
132
  def run_all
45
133
  tasks = @tasks
@@ -55,14 +143,13 @@ class Bit < Kit
55
143
  end
56
144
  status
57
145
  end
58
-
59
-
60
146
  end
61
147
 
62
- class DuplicateElement < RuntimeError
63
- end
64
-
65
- class NoElement < RuntimeError
148
+ # Finds bit ids that match given criteria.
149
+ # @param [Hash] criteria field / value pairs that will be matched against
150
+ # @return [Array] bit ids that match criteria
151
+ def lookup_id criteria
152
+ @@db.select_info_by_criteria :bits, [:rowid], criteria
66
153
  end
67
154
 
68
155
  end
@@ -1,7 +1,9 @@
1
1
  require 'sqlite3'
2
2
 
3
- # Methods to make sqlite3 interation more consice
3
+ # Methods to make sqlite3 interation more concise.
4
4
  module SQLite3Tools
5
+
6
+ # Array methods.
5
7
  class ::Array
6
8
  # Converts an array of symbols to a string of backquoted strings for use in SELECT statement
7
9
  # @return [String]
@@ -24,6 +26,7 @@ module SQLite3Tools
24
26
  end
25
27
  end
26
28
 
29
+ # Integer methods.
27
30
  class ::Integer
28
31
  # Generates placeholder string for INSERT statements.
29
32
  # @return String placeholder
@@ -37,6 +40,7 @@ module SQLite3Tools
37
40
  end
38
41
  end
39
42
 
43
+ # SQLite3 database methods.
40
44
  class SQLite3::Database
41
45
  # Selects given columns using given query and converts results to to hashes.
42
46
  # @param [Array<Symbol>] columns names of columns to select
@@ -52,6 +56,7 @@ module SQLite3Tools
52
56
  end
53
57
  end
54
58
 
59
+ # Backend abstracts database interactions.
55
60
  class Backend < Kit
56
61
 
57
62
  include SQLite3Tools
@@ -114,36 +119,40 @@ class Backend < Kit
114
119
  end
115
120
 
116
121
  public
117
- def select_all_actions_by_status action, fields, status
118
- query = "FROM `#{action}` WHERE `status` = '#{status}'"
119
- rows = @action_db.select fields, query
120
-
121
- h = { :action => action }
122
- rows.map { |t| t.merge h }
123
- end
124
122
 
125
- def insert_action table, data
126
- data.merge! ( { :status => "pending" } )
127
- @action_db.execute "INSERT INTO #{table} ( `#{data.keys.join "`, `"}` ) VALUES ( #{data.length.make_placeholders} )", data.values
128
- @action_db.last_insert_row_id
129
- end
130
-
131
- def delete_action_by_id action, id
132
- # puts "DELETE FROM `#{action}` WHERE `rowid` = #{id}"
123
+ # Deletes database files.
124
+ def delete
125
+ @db_paths.each do |key, f|
126
+ File.delete f
127
+ end
133
128
  end
134
129
 
130
+ # Gets the row from an info table with the given id.
131
+ # @param [Symbol] table what database table to query
132
+ # @param [Array] fields list of column names to return
133
+ # @param [Integer] id rowid of record to return
134
+ # @return [Array] hash for each returned row with a key for each requested field
135
135
  def select_info_by_id table, fields, id
136
136
  info = @info_db.select fields, "FROM `#{table}` WHERE `rowid` = '#{id}'"
137
137
  info.first
138
138
  end
139
139
 
140
+ # Gets the rows from an info table with the given name.
141
+ # @param table (see #select_info_by_id)
142
+ # @param fields (see #select_info_by_id)
143
+ # @param [String] name of records to return
144
+ # @return (see #select_info_by_id)
140
145
  def select_info_by_name table, fields, name
141
146
  info = @info_db.select fields, "FROM `#{table}` WHERE `name` = '#{name}'"
142
147
  info.first
143
148
  end
144
149
 
150
+ # Gets the rows from an info table with the given criteria.
151
+ # @param table (see #select_info_by_id)
152
+ # @param fields (see #select_info_by_id)
153
+ # @param [Hash] criteria key / value pairs required to match
154
+ # @return (see #select_info_by_id)
145
155
  def select_info_by_criteria table, fields, criteria
146
-
147
156
  q = []
148
157
  criteria.each do |key, value|
149
158
  q << "`#{key}` = '#{value}'"
@@ -153,8 +162,38 @@ class Backend < Kit
153
162
  info.first
154
163
  end
155
164
 
165
+ # Inserts a new row into an info table.
166
+ # @param table (see #select_info_by_id)
167
+ # @param [Hash] data key / value pairs for new row
168
+ # @return [Integer] rowid of new row
156
169
  def insert_info table, data
157
170
  @info_db.execute "INSERT INTO #{table} ( `#{data.keys.join "`, `"}` ) VALUES ( #{data.length.make_placeholders} )", data.values
158
171
  @info_db.last_insert_row_id
159
172
  end
173
+
174
+ # Gets the rows from the action table with given status.
175
+ # @param table (see #select_info_by_id)
176
+ # @param fields (see #select_info_by_id)
177
+ # @param [Symbol] status name of status to match
178
+ # @return (see #select_info_by_id)
179
+ def select_all_actions_by_status table, fields, status
180
+ query = "FROM `#{table}` WHERE `status` = '#{status}'"
181
+ rows = @action_db.select fields, query
182
+
183
+ rows.map { |t| t.merge ( { :action => table, :status => t[:status].to_sym } ) }
184
+ end
185
+
186
+ # Inserts a new row into an action table.
187
+ # @param (see #insert_info)
188
+ # @return (see #insert_info)
189
+ def insert_action table, data
190
+ data.merge! ( { :status => :pending.to_s, :time => Time.now.to_i } )
191
+ @action_db.execute "INSERT INTO #{table} ( `#{data.keys.join "`, `"}` ) VALUES ( #{data.length.make_placeholders} )", data.values
192
+ @action_db.last_insert_row_id
193
+ end
194
+
195
+ # def delete_action_by_id action, id
196
+ # puts "DELETE FROM `#{action}` WHERE `rowid` = #{id}"
197
+ # end
198
+
160
199
  end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
+ - 1
7
8
  - 0
8
- - 6
9
- version: 0.0.6
9
+ version: 0.1.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Evan Boyd Sosenko
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2011-05-01 00:00:00 -07:00
17
+ date: 2011-05-13 00:00:00 -07:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -32,7 +32,7 @@ dependencies:
32
32
  version: 1.3.3
33
33
  type: :runtime
34
34
  version_requirements: *id001
35
- description: "\t\tKit is a framework for making simple management tools called kits. Includes a skeleton kit for managing web projects: clone, deploy upgrades, and push git updates to your web apps.\n"
35
+ description: "\t\tKit is a framework for making simple management tools called kits.\n"
36
36
  email:
37
37
  executables: []
38
38
 
@@ -44,16 +44,8 @@ files:
44
44
  - lib/kit.rb
45
45
  - lib/kit/bit.rb
46
46
  - lib/kit/db_sqlite3.rb
47
- - README
48
- - kits/my_kit/sqlite3_info.sql
49
- - kits/my_kit/upgrades/my_project.rb
50
- - kits/my_kit/sqlite3_actions.sql
51
- - kits/my_kit/bit.rb
52
- - kits/my_kit/config.yml
53
- - kits/my_kit/commits/my_project.rb
54
- - kits/my_kit/clones/my_project.rb
55
- - spec/my_kit/my_kit.yml
56
- - spec/my_kit_spec.rb
47
+ - LICENCE.txt
48
+ - README.rdoc
57
49
  has_rdoc: true
58
50
  homepage:
59
51
  licenses:
data/README DELETED
@@ -1,60 +0,0 @@
1
- = Kit
2
-
3
- Kit is a framework for making simple management tools called kits. Read about why I wrote kit below for an idea of what Kit can do for you.
4
-
5
- == What is Kit?
6
-
7
- Kit's in it's infant stage and still changing too much to document everything it does or will do. The best way to understand what Kit is about is to read the motivation behind it (see below). Of course, you can always read the yard docs or source code if you want to see how it's coming.
8
-
9
- === Why I wrote kit
10
-
11
- Here are two independent problems Kit will solve (each will be a separate kit).
12
-
13
- ==== Apache server running multiple virtual hosts (vhosts)
14
-
15
- * Each time a vhost is added things have to happen, e.g. config files need to be made, directories created, etc.
16
- * Depending on the type of vhost, these tasks may be different e.g. what directories are made, how the conifg files look, etc.
17
- * If vhosts are removed or moved from one type to another, things need to be archived, cleaned up, etc.
18
- * If the config file template changes, etc., the vhosts should all get updated.
19
-
20
- ==== Web development server-side site management
21
-
22
- Unless you're strictly using a development framework, testing and deploying new code is non-trivial. Exporting your code from your git repo may be more complicated then running cp -R, e.g. compressing JavaScript and CSS. Sometimes, the only place to test a project on is in production environment . I needed a tool that made testing and updating a site running a mix of differnt web software, i.e.
23
-
24
- * Clone my production site to one of many testing sites.
25
- * Push update packages to any of the production or testing sites.
26
- * Push a git branch to any of the production or testing sites.
27
- * Allow other developers access to all of these functions without giving them shell access or elevated user privileges.
28
-
29
- == Building your own kit
30
-
31
- For instructions on how to build your own kit go to
32
- * https://github.com/razor-x/kit/wiki/Building-your-own-kit
33
-
34
- == Installation
35
-
36
- === Gem Installation
37
-
38
- Download and install Kit with the following.
39
-
40
- gem install kit
41
-
42
- == Development
43
-
44
- === Source Repository
45
-
46
- Kit is currently hosted at github. The github web page is
47
- https://github.com/razor-x/kit. To clone the project run
48
-
49
- git clone git://github.com/razor-x/kit.git
50
-
51
- == License
52
-
53
- Kit is licensed under the GPLv3.
54
-
55
- == Warranty
56
-
57
- This software is provided "as is" and without any express or
58
- implied warranties, including, without limitation, the implied
59
- warranties of merchantibility and fitness for a particular
60
- purpose.
@@ -1,54 +0,0 @@
1
- class Bit
2
-
3
- def lookup_id uniq
4
- @@db.select_info_by_criteria :bits, [:rowid], uniq
5
- end
6
-
7
- def insert_new
8
-
9
- if @project_id.nil?
10
-
11
- p = @@db.select_info_by_name :projects, [ :rowid ], @project_name
12
-
13
- @project_id = if p.nil? then insert_new_project else p[:rowid] end
14
-
15
- end
16
-
17
- uniq = { :name => @name, :project => @project_id }
18
- data = { :root => @root, :commit => nil, :commit_time => nil }
19
-
20
- fail DuplicateElement if lookup_id uniq
21
-
22
- data.merge! uniq
23
-
24
- @@db.insert_info :bits, data
25
- end
26
-
27
- def insert_new_project
28
-
29
- fail DuplicateElement if @@db.select_info_by_name :projects, [ :name ], @project_name
30
-
31
- data = { :name => @project_name, :git => @git }
32
- @@db.insert_info :projects, data
33
- end
34
-
35
- def load_info
36
-
37
- info = @@db.select_info_by_id :bits, @@info[:bits], @id
38
-
39
- fail NoElement unless info
40
-
41
- @name = info[:name]
42
- @project_id = info[:project]
43
-
44
- project_info = @@db.select_info_by_id :projects, @@info[:projects], @project_id
45
- info.merge! project_info
46
-
47
- @project_name = info[:name]
48
- @root = info[:root]
49
- @git = info[:git]
50
- @commit = { :name => info[:commit], :time => info[:commit_time] }
51
-
52
- end
53
-
54
- end
@@ -1,8 +0,0 @@
1
- module Actions
2
-
3
- def clones options
4
- src = Bit.new options[:src]
5
- puts "cloning #{src.project_name}.#{src.name} to #{@project_name}.#{@name}"
6
- end
7
-
8
- end
@@ -1,7 +0,0 @@
1
- module Actions
2
-
3
- def commits options
4
- puts "commiting"
5
- end
6
-
7
- end
@@ -1,36 +0,0 @@
1
- # Path to this kit's root directory.
2
- # Absolute or relative to this config file.
3
- # If not specified, defaults to the folder that holds this config file.
4
- #
5
- :kits_path:
6
- #
7
- # Database backend to use. Available options:
8
- # :sqlite3
9
- #
10
- :db_backend: :sqlite3
11
- #
12
- # Path to the files to save each sqlite3 database (since only sqlite3 is supported).
13
- # Absolute or relative to this config file.
14
- #
15
- :db_config:
16
- :info: "info.db"
17
- :actions: "actions.db"
18
- #
19
- # Tables and columns for each database.
20
- #
21
- # Each table in the :info: database must be of the form
22
- # :table_name: [ :rowid, :name, :column_name_1, :column_name_2 ]
23
- # where :rowid and :name are required columns.
24
- #
25
- :info:
26
- :bits: [ :rowid, :name, :project, :root, :commit, :commit_time ]
27
- :projects: [ :rowid, :name, :git ]
28
- #
29
- # Each table in the :actions: database must be of the form
30
- # :table_name: [ :rowid, :bit, :status, :column_name_1, :column_name_2 ]
31
- # where :rowid, :bit, and :status are required columns.
32
- #
33
- :actions:
34
- :clones: [ :rowid, :bit, :status, :src ]
35
- :upgrades: [ :rowid, :bit, :status, :component, :file ]
36
- :commits: [ :rowid, :bit, :status, :commit ]
@@ -1,16 +0,0 @@
1
- CREATE TABLE clones (
2
- "bit" INTEGER NOT NULL,
3
- "status" TEXT NOT NULL DEFAULT ('pending'),
4
- "src" INTEGER NOT NULL
5
- );
6
- CREATE TABLE upgrades (
7
- "bit" INTEGER NOT NULL,
8
- "status" TEXT NOT NULL DEFAULT ('pending'),
9
- "component" TEXT NOT NULL,
10
- "file" TEXT NOT NULL
11
- );
12
- CREATE TABLE commits (
13
- "bit" INTEGER NOT NULL,
14
- "status" TEXT NOT NULL DEFAULT ('pending'),
15
- "commit" TEXT
16
- );
@@ -1,15 +0,0 @@
1
- CREATE TABLE "permissions" (
2
- "name" INTEGER NOT NULL,
3
- "bit" INTEGER NOT NULL
4
- );
5
- CREATE TABLE projects (
6
- "name" TEXT NOT NULL,
7
- "git" TEXT NOT NULL
8
- );
9
- CREATE TABLE bits (
10
- "name" TEXT NOT NULL,
11
- "project" INTEGER NOT NULL,
12
- "root" TEXT NOT NULL,
13
- "commit" TEXT,
14
- "commit_time" INTEGER
15
- );
@@ -1,7 +0,0 @@
1
- module Actions
2
-
3
- def upgrades options
4
- puts "upgrading"
5
- end
6
-
7
- end
@@ -1,17 +0,0 @@
1
- # Path to this kit's root directory.
2
- # Absolute or relative to this config file.
3
- # If not specified, defaults to the folder that holds this config file.
4
- #
5
- :kits_path: "../../../kits/my_kit"
6
- #
7
- # Database backend to use. Available options:
8
- # :sqlite3
9
- #
10
- :db_backend: :sqlite3
11
- #
12
- # Path to the files to save each sqlite3 database (since only sqlite3 is supported).
13
- # Absolute or relative to this config file.
14
- #
15
- :db_config:
16
- :info: "info.db"
17
- :actions: "actions.db"
@@ -1,66 +0,0 @@
1
- require 'kit'
2
-
3
- describe Kit do
4
-
5
- MY_KIT_CONFIG = "spec/my_kit/my_kit.yml"
6
-
7
- before :all do
8
- @kit = Kit.new MY_KIT_CONFIG
9
- end
10
-
11
- it "adds a new bit to new project" do
12
- new_bit = { :name => "live", :project_name => "my_project", :root => "./my_kit_spec/my_project", :git => "git path" }
13
- b = @kit.add_bit new_bit
14
-
15
- b.class.should == Bit
16
-
17
- new_bit.each do |key, value|
18
- ( b.send key ).should == value
19
- end
20
- end
21
-
22
- it "doen not add a existing bit to project" do
23
- new_bit = { :name => "live", :project_name => "my_project", :root => "./my_kit_spec/my_project/live" }
24
- b = @kit.add_bit new_bit
25
-
26
- b.should == nil
27
-
28
- end
29
-
30
- it "adds a new task of each type" do
31
-
32
- # old_bit = { :name => "live", :project_name => "my_project" }
33
- # puts Kit::Bit.lookup_id old_bit
34
-
35
- new_bit_2 = { :name => "beta", :project_name => "my_project", :root => "./my_kit_spec/my_project/beta" }
36
- b = @kit.add_bit new_bit_2
37
-
38
- actions = {
39
- :clones => { :bit => 1, :src => 2 },
40
- :upgrades => { :bit => 1, :component => "my_component", :file => "my_file" },
41
- :commits => { :bit => 1, :commit => "3456ABF" }
42
- }
43
-
44
- tasks = {}
45
- actions.each do |key, value|
46
- tasks[key] = @kit.add_task key, value
47
- end
48
-
49
- @kit.action_types.each do |t|
50
- a = @kit.get_tasks_by_status t, :pending
51
- actions[t].merge! ( { :rowid => tasks[t], :action => t, :status => "pending" } )
52
- a.first.should == actions[t]
53
- end
54
-
55
- end
56
-
57
- it "runs added tasks" do
58
- @kit.run_tasks
59
- end
60
-
61
-
62
- after :all do
63
- @kit.delete_dbs
64
- end
65
-
66
- end