framework 0.0.1
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.
- checksums.yaml +7 -0
- data/LICENSE +22 -0
- data/Rakefile +20 -0
- data/bin/framework +5 -0
- data/lib/framework/application.rb +142 -0
- data/lib/framework/cli.rb +181 -0
- data/lib/framework/db_listener.rb +25 -0
- data/lib/framework/extensions/active_record/base_extension.rb +38 -0
- data/lib/framework/generators/migration_generator.rb +58 -0
- data/lib/framework/logger.rb +48 -0
- data/lib/framework/migration.rb +13 -0
- data/lib/framework/rake.rb +20 -0
- data/lib/framework/tasks/console.rake +21 -0
- data/lib/framework/tasks/db.rake +49 -0
- data/lib/framework/tasks/engine/environment.rake +3 -0
- data/lib/framework/tasks/generators.rake +8 -0
- data/lib/framework/templates/migration.rb.erb +9 -0
- data/lib/framework/version.rb +3 -0
- data/lib/framework.rb +34 -0
- data/spec/spec_helper.rb +21 -0
- metadata +204 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ba75921072b35b2f243539a2c8875c6eaabccd39
|
4
|
+
data.tar.gz: 3091bbda391dcabdc6e04588d40b25cc12ef07e9
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e1c690e3bfed331f6dd5206df9a3d6e1f5ff1f7ce7ab3394d1af9fe2cc0d71e82d9e9c3cc90adf39786467e8e2452e1520abd44947928b47aa00eb30bdb19458
|
7
|
+
data.tar.gz: f09cafc01abb92a531662ae3b6dbb245f9c72f1e721cb9d76e4f820119ff4daf9354e63d005d68423c0f3a148f028941b8a79398c0bb04370c49b5b991a2f033
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 Sergei Zinin
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
$:.unshift(File.expand_path("../lib", __FILE__))
|
2
|
+
ENV['BUNDLE_GEMFILE'] = 'Gemfile'
|
3
|
+
|
4
|
+
require 'framework'
|
5
|
+
require 'rubygems'
|
6
|
+
require 'bundler'
|
7
|
+
require 'rake'
|
8
|
+
require 'rake/testtask'
|
9
|
+
|
10
|
+
begin
|
11
|
+
Bundler.setup(:default, :development)
|
12
|
+
rescue Bundler::BundlerError => e
|
13
|
+
$stderr.puts e.message
|
14
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
15
|
+
exit e.status_code
|
16
|
+
end
|
17
|
+
|
18
|
+
Dir["#{File.expand_path("../lib/framework", __FILE__)}/tasks/engine/*.rake"].each(&method(:load))
|
19
|
+
Dir["#{File.expand_path("../lib/framework", __FILE__)}/tasks/*.rake"].each(&method(:load))
|
20
|
+
Dir["#{Dir.pwd}/app/tasks/**/*.rake"].each(&method(:load))
|
data/bin/framework
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
module Framework
|
2
|
+
class Application
|
3
|
+
CONFIG_PATH = "config/application.yml"
|
4
|
+
|
5
|
+
attr_reader :env
|
6
|
+
attr_accessor :logger
|
7
|
+
delegate :hint, :note, to: :logger
|
8
|
+
|
9
|
+
# @param [String] env Environment from configuration file
|
10
|
+
def initialize(env = nil)
|
11
|
+
@env = env || Framework.env
|
12
|
+
Framework.app = self
|
13
|
+
yield self if block_given?
|
14
|
+
end
|
15
|
+
|
16
|
+
# Entry point for the app
|
17
|
+
# @return [Application]
|
18
|
+
def init!
|
19
|
+
@logger = @config = @database_config = nil
|
20
|
+
|
21
|
+
load_application_config
|
22
|
+
load_database_config
|
23
|
+
note "Loading #{env} environment (#{Framework::VERSION})"
|
24
|
+
autoload
|
25
|
+
note "Establishing database connection"
|
26
|
+
establish_database_connection
|
27
|
+
note "Application has been initialized"
|
28
|
+
self
|
29
|
+
end
|
30
|
+
alias_method :reload!, :init!
|
31
|
+
|
32
|
+
# @return [Hash<String>]
|
33
|
+
def config
|
34
|
+
@config || load_application_config
|
35
|
+
end
|
36
|
+
|
37
|
+
def create_database!(name = nil)
|
38
|
+
name ||= 'default'
|
39
|
+
establish_postgres_connection(name)
|
40
|
+
ActiveRecord::Base.connection.create_database(database_config[name][env]['database'])
|
41
|
+
puts "The database #{database_config[name][env]['database']} has been successfully created"
|
42
|
+
end
|
43
|
+
|
44
|
+
def drop_database!(name = nil)
|
45
|
+
name ||= 'default'
|
46
|
+
establish_postgres_connection(name)
|
47
|
+
ActiveRecord::Base.connection.drop_database(database_config[name][env]['database'])
|
48
|
+
puts "The database #{database_config[name][env]['database']} has been successfully dropped"
|
49
|
+
end
|
50
|
+
|
51
|
+
def migrate_database(version = nil)
|
52
|
+
ActiveRecord::Migrator.migrate "db/migrations", version.try(:to_i)
|
53
|
+
end
|
54
|
+
|
55
|
+
def rollback_database(steps = 1)
|
56
|
+
ActiveRecord::Migrator.rollback "db/migrations", steps
|
57
|
+
end
|
58
|
+
|
59
|
+
# @return [Hash<String>]
|
60
|
+
def database_config
|
61
|
+
@database_config || load_database_config
|
62
|
+
end
|
63
|
+
|
64
|
+
# @return [String] Database name
|
65
|
+
def database
|
66
|
+
adapter = database_config['default'][env]['adapter']
|
67
|
+
database = database_config['default'][env]['database']
|
68
|
+
adapter == 'sqlite3' ? "db/sqlite/#{env}/#{database}.db" : database
|
69
|
+
end
|
70
|
+
|
71
|
+
def self.init!
|
72
|
+
yield Framework::Application.new.init!
|
73
|
+
end
|
74
|
+
|
75
|
+
def db_connection(db_name = 'default')
|
76
|
+
ActiveRecord::Base.establish_connection(database_config[db_name][env])
|
77
|
+
ActiveRecord::Base.connection
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def establish_database_connection
|
83
|
+
if database_config
|
84
|
+
database_config.each do |_, db_config|
|
85
|
+
ActiveRecord::Base.establish_connection(db_config[env])
|
86
|
+
|
87
|
+
if db_config[env]['enable_logging']
|
88
|
+
ActiveRecord::Base.logger = Logger.new(STDOUT)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
# Used to create/drop db
|
95
|
+
def establish_postgres_connection(name = 'default')
|
96
|
+
if database_config[name]
|
97
|
+
ActiveRecord::Base.establish_connection(database_config[name][env].merge('database' => 'postgres',
|
98
|
+
'schema_search_path' => 'public'))
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
# Autoloads all app-specific files
|
103
|
+
def autoload
|
104
|
+
config['autoload_paths'].each do |path|
|
105
|
+
if path.end_with?('.rb')
|
106
|
+
load(path)
|
107
|
+
else
|
108
|
+
load_path(File.join(path, 'concerns'))
|
109
|
+
|
110
|
+
Dir["#{path}/**/*.rb"].each do |path_to_load|
|
111
|
+
load(path_to_load) unless path_to_load.include?('concerns/')
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
# @return [Hash]
|
118
|
+
def load_application_config
|
119
|
+
@config = YAML.load_file(CONFIG_PATH)[env]
|
120
|
+
end
|
121
|
+
|
122
|
+
# @return [Hash]
|
123
|
+
def load_database_config
|
124
|
+
@database_config = YAML.load_file('config/databases.yml')
|
125
|
+
end
|
126
|
+
|
127
|
+
# @param [String] path Relative to project root
|
128
|
+
def load_path(path)
|
129
|
+
Dir["#{path}/**/*.rb"].each(&method(:load))
|
130
|
+
end
|
131
|
+
|
132
|
+
# @return [IO, nil]
|
133
|
+
def log_level
|
134
|
+
config['enable_logging'] ? STDOUT : nil
|
135
|
+
end
|
136
|
+
|
137
|
+
# @return [Framework::Logger]
|
138
|
+
def logger
|
139
|
+
@logger ||= Framework::Logger.new(log_level)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,181 @@
|
|
1
|
+
require 'active_support/core_ext/string/inflections'
|
2
|
+
require 'active_support/core_ext/string/strip'
|
3
|
+
require 'thor'
|
4
|
+
|
5
|
+
require 'framework/version'
|
6
|
+
|
7
|
+
module Framework
|
8
|
+
class AppGenerator < Thor::Group
|
9
|
+
include Thor::Actions
|
10
|
+
|
11
|
+
argument :name
|
12
|
+
|
13
|
+
def self.source_root
|
14
|
+
File.dirname(__FILE__)
|
15
|
+
end
|
16
|
+
|
17
|
+
def create_base_directories
|
18
|
+
empty_directory 'app/migrations'
|
19
|
+
create_file 'app/migrations/.keep'
|
20
|
+
|
21
|
+
empty_directory 'app/models'
|
22
|
+
empty_directory 'app/models/concerns'
|
23
|
+
create_file 'app/models/concerns/.keep'
|
24
|
+
|
25
|
+
empty_directory 'lib'
|
26
|
+
create_file 'lib/.keep'
|
27
|
+
|
28
|
+
empty_directory 'db'
|
29
|
+
empty_directory 'db/migrations'
|
30
|
+
create_file 'db/migrations/.keep'
|
31
|
+
|
32
|
+
end
|
33
|
+
|
34
|
+
def create_application_config
|
35
|
+
create_file 'config/application.yml' do
|
36
|
+
<<-CONFIG.strip_heredoc
|
37
|
+
development: &common
|
38
|
+
enable_logging: yes
|
39
|
+
autoload_paths:
|
40
|
+
- config/initializers
|
41
|
+
- app/models
|
42
|
+
default_timezone: 'Pacific Time (US & Canada)'
|
43
|
+
|
44
|
+
test:
|
45
|
+
<<: *common
|
46
|
+
enable_logging: no
|
47
|
+
|
48
|
+
staging:
|
49
|
+
<<: *common
|
50
|
+
|
51
|
+
production:
|
52
|
+
<<: *common
|
53
|
+
enable_logging: no
|
54
|
+
CONFIG
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def create_database_config
|
59
|
+
db_name = name.underscore
|
60
|
+
|
61
|
+
create_file 'config/databases.yml' do
|
62
|
+
<<-CONFIG.strip_heredoc
|
63
|
+
# Defult database is used by default.
|
64
|
+
# Any models locating at app/models root directory will point to this database by default.
|
65
|
+
default:
|
66
|
+
development: &common
|
67
|
+
adapter: postgresql
|
68
|
+
username:
|
69
|
+
password:
|
70
|
+
database: #{db_name}_development
|
71
|
+
min_messages: WARNING
|
72
|
+
reconnect: true
|
73
|
+
pool: 5
|
74
|
+
encoding: unicode
|
75
|
+
host: localhost
|
76
|
+
|
77
|
+
test:
|
78
|
+
<<: *common
|
79
|
+
database: #{db_name}_test
|
80
|
+
|
81
|
+
production:
|
82
|
+
<<: *common
|
83
|
+
database: #{db_name}_production
|
84
|
+
|
85
|
+
# Custom one. Models located at app/models/second_one path will point to this database by default.
|
86
|
+
second_one:
|
87
|
+
development: &common
|
88
|
+
adapter: postgresql
|
89
|
+
username:
|
90
|
+
password:
|
91
|
+
database: second_sample_development
|
92
|
+
min_messages: WARNING
|
93
|
+
reconnect: true
|
94
|
+
pool: 5
|
95
|
+
encoding: unicode
|
96
|
+
host: localhost
|
97
|
+
|
98
|
+
test:
|
99
|
+
<<: *common
|
100
|
+
database: second_sample_test
|
101
|
+
|
102
|
+
production:
|
103
|
+
<<: *common
|
104
|
+
database: second_sample_production
|
105
|
+
CONFIG
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def create_environment
|
110
|
+
create_file 'config/environment.rb' do
|
111
|
+
<<-CONFIG.strip_heredoc
|
112
|
+
# Set up gems listed in the Gemfile.
|
113
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
|
114
|
+
require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
|
115
|
+
|
116
|
+
require 'framework'
|
117
|
+
|
118
|
+
Bundler.require(:default, Framework.env)
|
119
|
+
|
120
|
+
Framework::Application.new do |app|
|
121
|
+
app.init!
|
122
|
+
end
|
123
|
+
CONFIG
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def create_gemfile
|
128
|
+
create_file 'Gemfile' do
|
129
|
+
<<-CONFIG.strip_heredoc
|
130
|
+
source 'https://rubygems.org'
|
131
|
+
|
132
|
+
gem 'framework', '#{Framework::VERSION}'
|
133
|
+
gem 'pg'
|
134
|
+
CONFIG
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def create_rakefile
|
139
|
+
create_file 'Rakefile' do
|
140
|
+
<<-CONFIG.strip_heredoc
|
141
|
+
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
142
|
+
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
143
|
+
|
144
|
+
require 'framework'
|
145
|
+
require 'framework/rake'
|
146
|
+
|
147
|
+
Dir["\#{Dir.pwd}/app/tasks/**/*.rake"].each(&method(:load))
|
148
|
+
CONFIG
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
def create_sample_tasks
|
153
|
+
empty_directory 'app/tasks'
|
154
|
+
create_file 'app/tasks/hello.rake' do
|
155
|
+
<<-RAKE.strip_heredoc
|
156
|
+
task hello: :environment do
|
157
|
+
Framework::Logger.disappointment("Hello from: Framework v#{Framework::VERSION}")
|
158
|
+
end
|
159
|
+
RAKE
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
def create_sample_initializers
|
164
|
+
empty_directory 'config/initializers'
|
165
|
+
create_file 'config/initializers/time_zone.rb' do
|
166
|
+
<<-CONFIG.strip_heredoc
|
167
|
+
# Sample usage of application config
|
168
|
+
Time.zone = Framework.app.config['default_timezone']
|
169
|
+
CONFIG
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def create_readme
|
174
|
+
create_file 'README.md', "This app utilizes Framework v#{Framework::VERSION} and rocks MIT license."
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
class Cli < Thor
|
179
|
+
register(Framework::AppGenerator, 'new', 'new APP_NAME', 'Generates new application')
|
180
|
+
end
|
181
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module Framework
|
4
|
+
class DbListener
|
5
|
+
attr_reader :db_name, :channel
|
6
|
+
|
7
|
+
def initialize(channel: 'framework_notifications', db_name: 'default')
|
8
|
+
@channel = channel.freeze
|
9
|
+
@db_name = db_name.freeze
|
10
|
+
end
|
11
|
+
|
12
|
+
def listen
|
13
|
+
connection = Framework.app.db_connection(db_name)
|
14
|
+
connection.execute "LISTEN #{channel}"
|
15
|
+
|
16
|
+
loop do
|
17
|
+
connection.raw_connection.wait_for_notify do |event, pid, data|
|
18
|
+
yield data.nil? ? data : JSON.parse(data)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
ensure
|
22
|
+
connection.execute "UNLISTEN #{channel}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Framework
|
2
|
+
module Extensions
|
3
|
+
module ActiveRecord
|
4
|
+
module BaseExtension
|
5
|
+
extend ActiveSupport::Concern
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
|
9
|
+
# @override
|
10
|
+
def inherited(child_class)
|
11
|
+
super
|
12
|
+
|
13
|
+
unless child_class == ::ActiveRecord::SchemaMigration
|
14
|
+
if (chunks = child_class.name.split('::')).many?
|
15
|
+
child_class.store_full_sti_class = false
|
16
|
+
child_class.use_database(chunks.first.downcase)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Makes your model use different databases
|
22
|
+
# @param [String, Symbol] db_name
|
23
|
+
# @param [String] env
|
24
|
+
def use_database(db_name, env = nil)
|
25
|
+
env ||= Framework.app.env
|
26
|
+
env = env.to_s
|
27
|
+
db_name = db_name.to_s
|
28
|
+
|
29
|
+
self.abstract_class = Framework.env != 'test'
|
30
|
+
self.table_name = self.name.split('::').last.tableize if self.superclass == ::ActiveRecord::Base
|
31
|
+
establish_connection(Framework.app.database_config[db_name][env])
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
ActiveRecord::Base.send :include, Framework::Extensions::ActiveRecord::BaseExtension
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
module Framework
|
4
|
+
class MigrationGenerator
|
5
|
+
|
6
|
+
def initialize(db_name: db_name, migration_name: name)
|
7
|
+
@db_name = db_name.underscore
|
8
|
+
@migration_name = migration_name.underscore
|
9
|
+
@timestamp = Time.now.utc.strftime("%Y%m%d%H%M%S")
|
10
|
+
@path = "db/migrations/#{@timestamp}_#@migration_name.rb"
|
11
|
+
end
|
12
|
+
|
13
|
+
def generate
|
14
|
+
context = Context.new(@db_name, @migration_name).template_binding
|
15
|
+
migration_file = File.open(@path, "w+")
|
16
|
+
migration_file << ERB.new(template).result(context)
|
17
|
+
migration_file.close
|
18
|
+
|
19
|
+
Framework.app.hint "Generated migration: #@path"
|
20
|
+
end
|
21
|
+
|
22
|
+
def templates_path
|
23
|
+
File.expand_path(File.join(File.dirname(__FILE__), '../templates'))
|
24
|
+
end
|
25
|
+
|
26
|
+
def template
|
27
|
+
@template ||= File.read(File.join(templates_path, "migration.rb.erb"))
|
28
|
+
end
|
29
|
+
|
30
|
+
class Context
|
31
|
+
attr_accessor :migration_name, :db_name
|
32
|
+
|
33
|
+
def initialize(db_name, migration_name)
|
34
|
+
@migration_name = migration_name.camelize
|
35
|
+
@db_name = db_name.underscore
|
36
|
+
validate!
|
37
|
+
end
|
38
|
+
|
39
|
+
def template_binding
|
40
|
+
binding
|
41
|
+
end
|
42
|
+
|
43
|
+
def load_migrations
|
44
|
+
Dir["./db/migrations/**/*.rb"].each(&method(:load))
|
45
|
+
rescue
|
46
|
+
raise "An error was occurred"
|
47
|
+
end
|
48
|
+
|
49
|
+
def validate!
|
50
|
+
load_migrations
|
51
|
+
Module.const_get(@migration_name)
|
52
|
+
raise "Migration with the same name already exists"
|
53
|
+
rescue NameError
|
54
|
+
true
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
class Framework::Logger < Logger
|
2
|
+
|
3
|
+
# @param [String] message
|
4
|
+
def disappointment(message)
|
5
|
+
info("\e[#{32}mFramework\e[1m \e[#{31}m#{message}\e[0m")
|
6
|
+
end
|
7
|
+
|
8
|
+
# @param [String] message
|
9
|
+
def hint(message)
|
10
|
+
info("\e[#{32}mFramework\e[1m \e[#{33}m#{message}\e[0m")
|
11
|
+
end
|
12
|
+
|
13
|
+
# @param [String] message
|
14
|
+
def note(message)
|
15
|
+
info("\e[#{32}mFramework\e[0m \e[#{33}m#{message}\e[0m")
|
16
|
+
end
|
17
|
+
|
18
|
+
# @param [String] message
|
19
|
+
def whisper(message)
|
20
|
+
info("\e[#{32}mFramework\e[0m \e[#{37}m#{message}\e[0m")
|
21
|
+
end
|
22
|
+
|
23
|
+
# @param [String] message
|
24
|
+
def self.disappointment(message)
|
25
|
+
internal.disappointment(message)
|
26
|
+
end
|
27
|
+
|
28
|
+
# @param [String] message
|
29
|
+
def self.hint(message)
|
30
|
+
internal.hint(message)
|
31
|
+
end
|
32
|
+
|
33
|
+
# @param [String] message
|
34
|
+
def self.note(message)
|
35
|
+
internal.note(message)
|
36
|
+
end
|
37
|
+
|
38
|
+
# @param [String] message
|
39
|
+
def self.whisper(message)
|
40
|
+
internal.whisper(message)
|
41
|
+
end
|
42
|
+
|
43
|
+
# Returns application logger
|
44
|
+
# @return [Framework::Logger]
|
45
|
+
def self.internal
|
46
|
+
Framework.app.try(:logger) || @internal ||= self.new(STDOUT)
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
module Framework
|
2
|
+
class Migration < ActiveRecord::Migration
|
3
|
+
|
4
|
+
def self.use_database(db_name)
|
5
|
+
define_method :connection do
|
6
|
+
@connection ||= begin
|
7
|
+
Framework::Logger.whishper "Using database: #{db_name}"
|
8
|
+
Framework.app.db_connection(db_name)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
$:.unshift(File.expand_path("../../", __FILE__))
|
3
|
+
ENV['BUNDLE_GEMFILE'] = 'Gemfile'
|
4
|
+
|
5
|
+
require 'framework'
|
6
|
+
require 'rubygems'
|
7
|
+
require 'bundler'
|
8
|
+
require 'rake'
|
9
|
+
require 'rake/testtask'
|
10
|
+
|
11
|
+
begin
|
12
|
+
Bundler.setup(:default, :development)
|
13
|
+
rescue Bundler::BundlerError => e
|
14
|
+
$stderr.puts e.message
|
15
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
16
|
+
exit e.status_code
|
17
|
+
end
|
18
|
+
|
19
|
+
Dir["#{File.expand_path("../", __FILE__)}/tasks/engine/*.rake"].each(&method(:load))
|
20
|
+
Dir["#{File.expand_path("../", __FILE__)}/tasks/*.rake"].each(&method(:load))
|
@@ -0,0 +1,21 @@
|
|
1
|
+
desc "Runs irb console and initializes the application"
|
2
|
+
task :console, :env do |_, args|
|
3
|
+
require 'irb'
|
4
|
+
|
5
|
+
unless env = ENV['ANALYTICS_ENV']
|
6
|
+
env = args[:env] || Framework::DEFAULT_ENV
|
7
|
+
end
|
8
|
+
|
9
|
+
system "mkdir -p #{Dir.pwd}/db/#{env}"
|
10
|
+
|
11
|
+
Framework::Application.new(env) do |app|
|
12
|
+
app.init!
|
13
|
+
app.hint("Use `Framework.app` variable to deal with application API")
|
14
|
+
|
15
|
+
require "awesome_print"
|
16
|
+
AwesomePrint.irb!
|
17
|
+
end
|
18
|
+
|
19
|
+
ARGV.clear
|
20
|
+
IRB.start
|
21
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'framework/migration'
|
2
|
+
|
3
|
+
namespace :db do
|
4
|
+
desc "Creates database"
|
5
|
+
task :create, :name do |_, args|
|
6
|
+
puts "Loading #{Framework.env}"
|
7
|
+
Framework::Application.new.create_database!(args[:name])
|
8
|
+
end
|
9
|
+
|
10
|
+
desc "Drops database"
|
11
|
+
task :drop, :name do |_, args|
|
12
|
+
puts "Loading #{Framework.env}"
|
13
|
+
Framework::Application.new.drop_database!(args[:name])
|
14
|
+
end
|
15
|
+
|
16
|
+
desc "Runs migrations"
|
17
|
+
task :migrate, [:version] => :environment do |_, args|
|
18
|
+
Framework.app.migrate_database(args.version)
|
19
|
+
end
|
20
|
+
|
21
|
+
desc "Rolls back"
|
22
|
+
task :rollback, [:num_steps] => :environment do |_, args|
|
23
|
+
Framework.app.rollback_database((args.num_steps || 1).to_i)
|
24
|
+
end
|
25
|
+
|
26
|
+
namespace :test do
|
27
|
+
desc "Creates test database"
|
28
|
+
task :create, :name do |_, args|
|
29
|
+
env = 'test'
|
30
|
+
puts "Loading #{env.inspect}"
|
31
|
+
Framework::Application.new(env).create_database!(args[:name])
|
32
|
+
end
|
33
|
+
|
34
|
+
desc "Drops test database"
|
35
|
+
task :drop, :name do |_, args|
|
36
|
+
env = 'test'
|
37
|
+
puts "Loading #{env.inspect}"
|
38
|
+
Framework::Application.new(env).drop_database!(args[:name])
|
39
|
+
end
|
40
|
+
|
41
|
+
desc "Runs test migrations"
|
42
|
+
task :migrate do
|
43
|
+
env = 'test'
|
44
|
+
puts "Loading #{env.inspect}"
|
45
|
+
Framework::Application.new(env).init!
|
46
|
+
ActiveRecord::Migrator.migrate('db/migrations/')
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
require 'framework/generators/migration_generator'
|
2
|
+
|
3
|
+
namespace :g do
|
4
|
+
desc "Generates migration"
|
5
|
+
task :migration, [:db_name, :migration_name] => :environment do |_, args|
|
6
|
+
Framework::MigrationGenerator.new(db_name: args[:db_name], migration_name: args[:migration_name]).generate
|
7
|
+
end
|
8
|
+
end
|
data/lib/framework.rb
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
require 'bundler'
|
3
|
+
|
4
|
+
require 'framework/version'
|
5
|
+
require 'framework/extensions/active_record/base_extension'
|
6
|
+
require 'framework/logger'
|
7
|
+
require 'framework/application'
|
8
|
+
require 'framework/db_listener'
|
9
|
+
|
10
|
+
module Framework
|
11
|
+
DEFAULT_ENV = 'development'.freeze
|
12
|
+
|
13
|
+
# @return [Framework::Application]
|
14
|
+
def self.app
|
15
|
+
@app
|
16
|
+
end
|
17
|
+
|
18
|
+
# @param [Framework::Application] app
|
19
|
+
def self.app=(app)
|
20
|
+
@app = app
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.env
|
24
|
+
@app ? @app.env : (ENV['FRAMEWORK_ENV'] || DEFAULT_ENV)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
begin
|
29
|
+
Bundler.require(:default, Framework.env)
|
30
|
+
rescue Bundler::BundlerError => e
|
31
|
+
$stderr.puts e.message
|
32
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
33
|
+
exit e.status_code
|
34
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
# This file is copied to spec/ when you run 'rails generate rspec:install'
|
2
|
+
env = ENV["FRAMEWORK_ENV"] ||= 'test'
|
3
|
+
require 'framework'
|
4
|
+
require File.expand_path("../../config/environment", __FILE__)
|
5
|
+
require 'rspec'
|
6
|
+
require 'database_cleaner'
|
7
|
+
|
8
|
+
# Requires supporting ruby files with custom matchers and macros, etc,
|
9
|
+
# in spec/support/ and its subdirectories.
|
10
|
+
Dir[File.expand_path("../../spec/support/**/*.rb", __FILE__)].each(&method(:load))
|
11
|
+
|
12
|
+
# Checks for pending migrations before tests are run.
|
13
|
+
# If you are not using ActiveRecord, you can remove this line.
|
14
|
+
ActiveRecord::Migration.check_pending! if defined?(ActiveRecord::Migration)
|
15
|
+
|
16
|
+
RSpec.configure do |config|
|
17
|
+
config.raise_errors_for_deprecations!
|
18
|
+
config.order = "random"
|
19
|
+
config.color = true
|
20
|
+
config.formatter = :documentation
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,204 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: framework
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sergei Nikolaevich Zinin
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-11-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activerecord
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '4.0'
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 4.0.0
|
23
|
+
type: :runtime
|
24
|
+
prerelease: false
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
26
|
+
requirements:
|
27
|
+
- - "~>"
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '4.0'
|
30
|
+
- - ">="
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 4.0.0
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: activesupport
|
35
|
+
requirement: !ruby/object:Gem::Requirement
|
36
|
+
requirements:
|
37
|
+
- - "~>"
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '4.0'
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 4.0.0
|
43
|
+
type: :runtime
|
44
|
+
prerelease: false
|
45
|
+
version_requirements: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - "~>"
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '4.0'
|
50
|
+
- - ">="
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 4.0.0
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
name: awesome_print
|
55
|
+
requirement: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - "~>"
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '1.2'
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: 1.2.0
|
63
|
+
type: :runtime
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - "~>"
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '1.2'
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: 1.2.0
|
73
|
+
- !ruby/object:Gem::Dependency
|
74
|
+
name: rake
|
75
|
+
requirement: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - "~>"
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '10.3'
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 10.3.2
|
83
|
+
type: :runtime
|
84
|
+
prerelease: false
|
85
|
+
version_requirements: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '10.3'
|
90
|
+
- - ">="
|
91
|
+
- !ruby/object:Gem::Version
|
92
|
+
version: 10.3.2
|
93
|
+
- !ruby/object:Gem::Dependency
|
94
|
+
name: thor
|
95
|
+
requirement: !ruby/object:Gem::Requirement
|
96
|
+
requirements:
|
97
|
+
- - "~>"
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0.19'
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: 0.19.1
|
103
|
+
type: :runtime
|
104
|
+
prerelease: false
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - "~>"
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0.19'
|
110
|
+
- - ">="
|
111
|
+
- !ruby/object:Gem::Version
|
112
|
+
version: 0.19.1
|
113
|
+
- !ruby/object:Gem::Dependency
|
114
|
+
name: bundler
|
115
|
+
requirement: !ruby/object:Gem::Requirement
|
116
|
+
requirements:
|
117
|
+
- - "~>"
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: '1.6'
|
120
|
+
- - ">="
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: 1.6.2
|
123
|
+
type: :development
|
124
|
+
prerelease: false
|
125
|
+
version_requirements: !ruby/object:Gem::Requirement
|
126
|
+
requirements:
|
127
|
+
- - "~>"
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: '1.6'
|
130
|
+
- - ">="
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: 1.6.2
|
133
|
+
- !ruby/object:Gem::Dependency
|
134
|
+
name: rspec
|
135
|
+
requirement: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - "~>"
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: '3.1'
|
140
|
+
- - ">="
|
141
|
+
- !ruby/object:Gem::Version
|
142
|
+
version: 3.1.0
|
143
|
+
type: :development
|
144
|
+
prerelease: false
|
145
|
+
version_requirements: !ruby/object:Gem::Requirement
|
146
|
+
requirements:
|
147
|
+
- - "~>"
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '3.1'
|
150
|
+
- - ">="
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: 3.1.0
|
153
|
+
description: Allows to quickly build well structured complex Ruby apps.
|
154
|
+
email: zinin@xakep.ru
|
155
|
+
executables:
|
156
|
+
- framework
|
157
|
+
extensions: []
|
158
|
+
extra_rdoc_files: []
|
159
|
+
files:
|
160
|
+
- LICENSE
|
161
|
+
- Rakefile
|
162
|
+
- bin/framework
|
163
|
+
- lib/framework.rb
|
164
|
+
- lib/framework/application.rb
|
165
|
+
- lib/framework/cli.rb
|
166
|
+
- lib/framework/db_listener.rb
|
167
|
+
- lib/framework/extensions/active_record/base_extension.rb
|
168
|
+
- lib/framework/generators/migration_generator.rb
|
169
|
+
- lib/framework/logger.rb
|
170
|
+
- lib/framework/migration.rb
|
171
|
+
- lib/framework/rake.rb
|
172
|
+
- lib/framework/tasks/console.rake
|
173
|
+
- lib/framework/tasks/db.rake
|
174
|
+
- lib/framework/tasks/engine/environment.rake
|
175
|
+
- lib/framework/tasks/generators.rake
|
176
|
+
- lib/framework/templates/migration.rb.erb
|
177
|
+
- lib/framework/version.rb
|
178
|
+
- spec/spec_helper.rb
|
179
|
+
homepage: http://github.com/einzige/framework
|
180
|
+
licenses:
|
181
|
+
- MIT
|
182
|
+
metadata: {}
|
183
|
+
post_install_message:
|
184
|
+
rdoc_options: []
|
185
|
+
require_paths:
|
186
|
+
- lib
|
187
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
188
|
+
requirements:
|
189
|
+
- - ">="
|
190
|
+
- !ruby/object:Gem::Version
|
191
|
+
version: 2.0.0
|
192
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
193
|
+
requirements:
|
194
|
+
- - ">="
|
195
|
+
- !ruby/object:Gem::Version
|
196
|
+
version: 2.2.2
|
197
|
+
requirements: []
|
198
|
+
rubyforge_project:
|
199
|
+
rubygems_version: 2.2.2
|
200
|
+
signing_key:
|
201
|
+
specification_version: 4
|
202
|
+
summary: Ruby Application Framework for all your needs.
|
203
|
+
test_files:
|
204
|
+
- spec/spec_helper.rb
|