antfarm-core 0.5.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,166 @@
1
+ ################################################################################
2
+ # #
3
+ # Copyright (2008-2010) Sandia Corporation. Under the terms of Contract #
4
+ # DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains #
5
+ # certain rights in this software. #
6
+ # #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy #
8
+ # of this software and associated documentation files (the "Software"), to #
9
+ # deal in the Software without restriction, including without limitation the #
10
+ # rights to use, copy, modify, merge, publish, distribute, distribute with #
11
+ # modifications, sublicense, and/or sell copies of the Software, and to permit #
12
+ # persons to whom the Software is furnished to do so, subject to the following #
13
+ # conditions: #
14
+ # #
15
+ # The above copyright notice and this permission notice shall be included in #
16
+ # all copies or substantial portions of the Software. #
17
+ # #
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #
21
+ # ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, #
22
+ # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR #
23
+ # IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE #
24
+ # SOFTWARE. #
25
+ # #
26
+ # Except as contained in this notice, the name(s) of the above copyright #
27
+ # holders shall not be used in advertising or otherwise to promote the sale, #
28
+ # use or other dealings in this Software without prior written authorization. #
29
+ # #
30
+ ################################################################################
31
+
32
+ require 'antfarm/plugin'
33
+
34
+ module Antfarm
35
+ class Framework
36
+ attr_reader :plugin
37
+
38
+ def version
39
+ return Antfarm.version
40
+ end
41
+
42
+ # If this method is called first, ALL plugins will be
43
+ # loaded and cached for the duration of process.
44
+ def plugins
45
+ return @plugins ||= Antfarm::Plugin.load
46
+ end
47
+
48
+ def clean_db
49
+ message = "Deleting #{ANTFARM_ENV} log file..."
50
+ Antfarm::Helpers.output message
51
+ Antfarm::Helpers.log :info, message
52
+
53
+ FileUtils.rm "#{Antfarm::Helpers.log_file(ANTFARM_ENV)}" if File.exists?(Antfarm::Helpers.log_file(ANTFARM_ENV))
54
+
55
+ message = "Deleted #{ANTFARM_ENV} log file successfully."
56
+ Antfarm::Helpers.output message
57
+ Antfarm::Helpers.log :info, message
58
+
59
+ config = YAML::load(IO.read(Antfarm::Helpers.defaults_file))
60
+
61
+ # TODO <scrapcoder>: can this stuff be done using the postgres gem instead?
62
+ if config && config[ANTFARM_ENV] && config[ANTFARM_ENV]['adapter'] == 'postgres'
63
+ message = "Dropping PostgreSQL #{ANTFARM_ENV} database..."
64
+ Antfarm::Helpers.output message
65
+ Antfarm::Helpers.log :info, message
66
+
67
+ exec "dropdb #{ANTFARM_ENV}"
68
+
69
+ message = "Dropped PostgreSQL #{ANTFARM_ENV} database successfully."
70
+ Antfarm::Helpers.output message
71
+ Antfarm::Helpers.log :info, message
72
+ else
73
+ message = "Dropping SQLite3 #{ANTFARM_ENV} database..."
74
+ Antfarm::Helpers.output message
75
+ Antfarm::Helpers.log :info, message
76
+
77
+ FileUtils.rm "#{Antfarm::Helpers.db_file(ANTFARM_ENV)}" if File.exists?(Antfarm::Helpers.db_file(ANTFARM_ENV))
78
+
79
+ message = "Dropped SQLite3 #{ANTFARM_ENV} database successfully."
80
+ Antfarm::Helpers.output message
81
+ Antfarm::Helpers.log :info, message
82
+ end
83
+ end
84
+
85
+ # Creates a new database and schema file. The location of the newly created
86
+ # database file is set in the initializer class via the user
87
+ # configuration hash, and is based on the current ANTFARM environment.
88
+ def migrate_db
89
+ begin
90
+ message = 'Migrating database...'
91
+ Antfarm::Helpers.output message
92
+ Antfarm::Helpers.log :info, message
93
+
94
+ DataMapper.auto_upgrade!
95
+
96
+ message = 'Database successfully migrated.'
97
+ Antfarm::Helpers.output message
98
+ Antfarm::Helpers.log :info, message
99
+ rescue => e # TODO: better error catching - not EVERY error is PostreSQL...
100
+ message = "No PostgreSQL database exists for the #{ANTFARM_ENV} environment. Creating PostgreSQL database..."
101
+ Antfarm::Helpers.output message
102
+ Antfarm::Helpers.log :info, message
103
+
104
+ exec "createdb #{ANTFARM_ENV}"
105
+
106
+ message = 'PostgreSQL database for this environment created. Continuing on with migration.'
107
+ Antfarm::Helpers.output message
108
+ Antfarm::Helpers.log :info, message
109
+
110
+ DataMapper.auto_upgrade!
111
+
112
+ message = 'Database successfully migrated.'
113
+ Antfarm::Helpers.output message
114
+ Antfarm::Helpers.log :info, message
115
+ end
116
+ end
117
+
118
+ # Forces a destructive migration
119
+ def reset_db
120
+ clean_db
121
+ migrate_db
122
+ end
123
+
124
+ def use(plugin)
125
+ @plugin = load_plugin(plugin)
126
+ end
127
+
128
+ def back
129
+ @plugin_name = nil
130
+ @plugin = nil
131
+ end
132
+
133
+ def run(options = Hash.new)
134
+ raise Antfarm::AntfarmError, 'No plugin loaded' unless @plugin
135
+
136
+ if @plugin.options.nil?
137
+ @plugin.run
138
+ else
139
+ @plugin.run(options)
140
+ end
141
+ end
142
+
143
+ def method_missing(method, *args)
144
+ raise Antfarm::AntfarmError, "Command '#{method}' not recognized"
145
+ end
146
+
147
+ #######
148
+ private
149
+ #######
150
+
151
+ def load_plugin(plugin)
152
+ raise Antfarm::AntfarmError, 'Must supply name of one plugin to use' if plugin.nil? or plugin.empty?
153
+
154
+ @plugins ||= Hash.new
155
+ return @plugins[plugin] if @plugins.has_key?(plugin)
156
+
157
+ # Load and save the plugin. An exception will be
158
+ # thrown if the plugin cannot be found or loaded.
159
+ @plugins[plugin] = Antfarm::Plugin.load(plugin)
160
+
161
+ # will not get here if plugin doesn't exist.
162
+ # Exception will have been thrown by now.
163
+ return @plugins[plugin]
164
+ end
165
+ end
166
+ end
@@ -0,0 +1,146 @@
1
+ ################################################################################
2
+ # #
3
+ # Copyright (2008-2010) Sandia Corporation. Under the terms of Contract #
4
+ # DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains #
5
+ # certain rights in this software. #
6
+ # #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy #
8
+ # of this software and associated documentation files (the "Software"), to #
9
+ # deal in the Software without restriction, including without limitation the #
10
+ # rights to use, copy, modify, merge, publish, distribute, distribute with #
11
+ # modifications, sublicense, and/or sell copies of the Software, and to permit #
12
+ # persons to whom the Software is furnished to do so, subject to the following #
13
+ # conditions: #
14
+ # #
15
+ # The above copyright notice and this permission notice shall be included in #
16
+ # all copies or substantial portions of the Software. #
17
+ # #
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #
21
+ # ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, #
22
+ # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR #
23
+ # IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE #
24
+ # SOFTWARE. #
25
+ # #
26
+ # Except as contained in this notice, the name(s) of the above copyright #
27
+ # holders shall not be used in advertising or otherwise to promote the sale, #
28
+ # use or other dealings in this Software without prior written authorization. #
29
+ # #
30
+ ################################################################################
31
+
32
+ require 'fileutils'
33
+
34
+ module Antfarm
35
+ module Helpers
36
+ # Symbolic marker points on the fuzzy logic certainty factor scale.
37
+ # Certainty Factors (CF)
38
+ CF_PROVEN_TRUE = 1.0000
39
+ CF_LIKELY_TRUE = 0.5000
40
+ CF_LACK_OF_PROOF = 0.0000
41
+ CF_LIKELY_FALSE = -0.5000
42
+ CF_PROVEN_FALSE = -1.0000
43
+
44
+ # Amount by which a value can differ and still be considered the same.
45
+ # Mainly used as a buffer against floating point round-off errors.
46
+ CF_VARIANCE = 0.0001
47
+
48
+ @user_dir = nil
49
+ @logger_callback = nil
50
+ class << self
51
+ attr_accessor :logger_callback
52
+ attr_accessor :outputter
53
+ attr_accessor :user_dir
54
+ end
55
+
56
+ def self.clamp(x, low = CF_PROVEN_FALSE, high = CF_PROVEN_TRUE)
57
+ if x < low
58
+ return low
59
+ elsif x > high
60
+ return high
61
+ else
62
+ return x
63
+ end
64
+ end
65
+
66
+ def self.simplify_interfaces
67
+ #TODO
68
+ end
69
+
70
+ def self.timestamp
71
+ return Time.now.utc.xmlschema
72
+ end
73
+
74
+ def self.output(message)
75
+ @outputter.puts(message) unless @outputter.nil?
76
+ end
77
+
78
+ def self.log(level, *msg)
79
+ @logger_callback.call(level, msg.join) if @logger_callback
80
+ end
81
+
82
+ def self.db_dir
83
+ return File.expand_path("#{self.user_dir}/db")
84
+ end
85
+
86
+ def self.db_file(environment)
87
+ return File.expand_path("#{self.user_dir}/db/#{environment}.db")
88
+ end
89
+
90
+ def self.log_dir
91
+ return File.expand_path("#{self.user_dir}/log")
92
+ end
93
+
94
+ def self.log_file(environment)
95
+ return File.expand_path("#{self.user_dir}/log/#{environment}.log")
96
+ end
97
+
98
+ def self.defaults_file
99
+ return File.expand_path("#{self.user_dir}/config/defaults.yml")
100
+ end
101
+
102
+ def self.history_file
103
+ return File.expand_path("#{self.user_dir}/history")
104
+ end
105
+
106
+ def self.user_plugins_dir
107
+ return File.expand_path("#{self.user_dir}/plugins")
108
+ end
109
+
110
+ #######
111
+ private
112
+ #######
113
+
114
+ USER_DIRECTORIES = ['config', 'db', 'log', 'plugins']
115
+
116
+ def self.user_dir
117
+ return @user_dir unless @user_dir.nil?
118
+ return self.create_user_directory
119
+ end
120
+
121
+ # Initializes a suitable directory structure for the user
122
+ def self.create_user_directory
123
+ USER_DIRECTORIES.each do |directory|
124
+ path = "#{ENV['HOME']}/.antfarm/#{directory}"
125
+ # Just to be safe... don't want to wipe out existing user data!
126
+ unless File.exists?(path)
127
+ FileUtils.makedirs(path)
128
+ Antfarm::Helpers.log :info, "User '#{directory}' directory created in #{ENV['HOME'] + '/.antfarm'}"
129
+ end
130
+ end
131
+
132
+ defaults_file = "#{ENV['HOME']}/.antfarm/config/defaults.yml"
133
+ # Just to be safe... don't want to wipe out existing user data!
134
+ unless File.exists?(defaults_file)
135
+ File.open(defaults_file, 'w') do |file|
136
+ file.puts '---'
137
+ file.puts 'environment: antfarm'
138
+ file.puts 'log_level: warn'
139
+ end
140
+ Antfarm::Helpers.log :info, "Default config file created at #{ENV['HOME'] + '/.antfarm/config/defaults.yml'}"
141
+ end
142
+
143
+ return @user_dir = (ENV['HOME'] + '/.antfarm').dup
144
+ end
145
+ end
146
+ end
@@ -0,0 +1,160 @@
1
+ ################################################################################
2
+ # #
3
+ # Copyright (2008-2010) Sandia Corporation. Under the terms of Contract #
4
+ # DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains #
5
+ # certain rights in this software. #
6
+ # #
7
+ # Permission is hereby granted, free of charge, to any person obtaining a copy #
8
+ # of this software and associated documentation files (the "Software"), to #
9
+ # deal in the Software without restriction, including without limitation the #
10
+ # rights to use, copy, modify, merge, publish, distribute, distribute with #
11
+ # modifications, sublicense, and/or sell copies of the Software, and to permit #
12
+ # persons to whom the Software is furnished to do so, subject to the following #
13
+ # conditions: #
14
+ # #
15
+ # The above copyright notice and this permission notice shall be included in #
16
+ # all copies or substantial portions of the Software. #
17
+ # #
18
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #
19
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, #
20
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE #
21
+ # ABOVE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, #
22
+ # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR #
23
+ # IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE #
24
+ # SOFTWARE. #
25
+ # #
26
+ # Except as contained in this notice, the name(s) of the above copyright #
27
+ # holders shall not be used in advertising or otherwise to promote the sale, #
28
+ # use or other dealings in this Software without prior written authorization. #
29
+ # #
30
+ ################################################################################
31
+
32
+ require 'yaml'
33
+
34
+ require 'rubygems'
35
+ require 'dm-core'
36
+
37
+ module Antfarm
38
+ class Initializer
39
+ attr_reader :configuration
40
+
41
+ # Run the initializer, first making the configuration object available
42
+ # to the user, then creating a new initializer object, then running the
43
+ # given command.
44
+ def self.run(command = :process, configuration = Configuration.new)
45
+ yield configuration if block_given?
46
+ initializer = new configuration
47
+ initializer.send(command)
48
+ end
49
+
50
+ def initialize(configuration)
51
+ @configuration = configuration
52
+ end
53
+
54
+ def process
55
+ initialize_database
56
+ initialize_logger
57
+ load_requirements
58
+ end
59
+
60
+ def setup
61
+ # Set application load paths
62
+ load_paths = configuration.load_paths
63
+ load_paths.reverse_each { |path| $LOAD_PATH.unshift(path) if File.directory?(path) }
64
+ $LOAD_PATH.uniq!
65
+
66
+ # Load the Antfarm::Helpers module
67
+ load_helpers
68
+
69
+ # Load the general Antfarm error classes
70
+ load_errors
71
+
72
+ # Make sure an application directory exists for the current user
73
+ Antfarm::Helpers.create_user_directory
74
+ end
75
+
76
+ #######
77
+ private
78
+ #######
79
+
80
+ def load_helpers
81
+ require 'antfarm/helpers'
82
+ end
83
+
84
+ def load_errors
85
+ require 'antfarm/errors'
86
+ end
87
+
88
+ # Currently, SQLite3 and PostgreSQL databases are the only ones supported.
89
+ # The name of the ANTFARM environment (which defaults to 'antfarm') is the
90
+ # name used for the database file and the log file.
91
+ def initialize_database
92
+ config = YAML::load(IO.read(Antfarm::Helpers.defaults_file))
93
+ # Database setup based on adapter specified
94
+ if config && config[ANTFARM_ENV] && config[ANTFARM_ENV].has_key?('adapter')
95
+ if config[ANTFARM_ENV]['adapter'] == 'sqlite3'
96
+ config[ANTFARM_ENV]['database'] = Antfarm::Helpers.db_file(ANTFARM_ENV)
97
+ elsif config[ANTFARM_ENV]['adapter'] == 'postgres'
98
+ config[ANTFARM_ENV]['database'] = ANTFARM_ENV
99
+ else
100
+ # If adapter specified isn't one of sqlite3 or postgresql,
101
+ # default to SQLite3 database configuration.
102
+ config = nil
103
+ end
104
+ else
105
+ # If the current environment configuration doesn't specify a
106
+ # database adapter, default to SQLite3 database configuration.
107
+ config = nil
108
+ end
109
+ # Default to SQLite3 database configuration
110
+ config ||= { ANTFARM_ENV => { 'adapter' => 'sqlite3', 'database' => Antfarm::Helpers.db_file(ANTFARM_ENV) } }
111
+ if config[ANTFARM_ENV]['adapter'] == 'postgres'
112
+ DataMapper.setup(:default, "postgres:///#{config[ANTFARM_ENV]['database']}")
113
+ else
114
+ DataMapper.setup(:default, "sqlite3://#{config[ANTFARM_ENV]['database']}")
115
+ end
116
+ end
117
+
118
+ def initialize_logger
119
+ @logger = DataMapper::Logger.new(Antfarm::Helpers.log_file(ANTFARM_ENV), configuration.log_level)
120
+ Antfarm::Helpers.logger_callback = lambda do |severity,msg|
121
+ @logger.send(severity,msg)
122
+ end
123
+ end
124
+
125
+ def load_requirements
126
+ # This will most likely already have been required by RubyGems, but let's
127
+ # keep it in here anyway just in case...
128
+ #
129
+ # Note that 'antfarm-core' calls for boot strapping the ANTFARM
130
+ # environment. However, that shouldn't lead to a circular dependency
131
+ # here since this 'load_requirements' method is called by the initializer
132
+ # 'process' method, not the boot strap's 'setup' method.
133
+ require 'antfarm-core'
134
+ end
135
+ end
136
+
137
+ class Configuration
138
+ attr_accessor :load_paths
139
+ attr_accessor :log_level
140
+
141
+ def initialize
142
+ self.load_paths = default_load_paths
143
+ self.log_level = default_log_level
144
+ end
145
+
146
+ #######
147
+ private
148
+ #######
149
+
150
+ def default_load_paths
151
+ paths = Array.new
152
+ paths << File.expand_path(ANTFARM_ROOT + "/lib")
153
+ return paths
154
+ end
155
+
156
+ def default_log_level
157
+ return :warn
158
+ end
159
+ end
160
+ end