jun 0.0.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +13 -0
  3. data/Gemfile +3 -1
  4. data/LICENSE.txt +1 -1
  5. data/README.md +18 -20
  6. data/Rakefile +13 -3
  7. data/bin/console +3 -9
  8. data/exe/jun +7 -0
  9. data/jun.gemspec +28 -18
  10. data/lib/jun/action_controller/base.rb +16 -0
  11. data/lib/jun/action_controller/callbacks.rb +46 -0
  12. data/lib/jun/action_controller/metal.rb +22 -0
  13. data/lib/jun/action_controller/redirecting.rb +17 -0
  14. data/lib/jun/action_controller/rendering.rb +84 -0
  15. data/lib/jun/action_dispatch/routing/mapper.rb +54 -0
  16. data/lib/jun/action_dispatch/routing/route_set.rb +112 -0
  17. data/lib/jun/action_dispatch/routing/welcome.html.erb +41 -0
  18. data/lib/jun/action_view/base.rb +26 -0
  19. data/lib/jun/action_view/helpers/url_helper.rb +13 -0
  20. data/lib/jun/action_view/helpers.rb +11 -0
  21. data/lib/jun/active_record/base.rb +52 -0
  22. data/lib/jun/active_record/migration.rb +76 -0
  23. data/lib/jun/active_record/migrator.rb +80 -0
  24. data/lib/jun/active_record/persistence.rb +60 -0
  25. data/lib/jun/active_record/relation.rb +42 -0
  26. data/lib/jun/active_support/core_ext/array/access.rb +27 -0
  27. data/lib/jun/active_support/core_ext/array/conversion.rb +10 -0
  28. data/lib/jun/active_support/core_ext/hash/transformation.rb +19 -0
  29. data/lib/jun/active_support/core_ext/string/access.rb +18 -0
  30. data/lib/jun/active_support/core_ext/string/inflector.rb +119 -0
  31. data/lib/jun/active_support/core_ext.rb +5 -0
  32. data/lib/jun/active_support/dependencies.rb +31 -0
  33. data/lib/jun/application.rb +45 -0
  34. data/lib/jun/cli/commands/base.rb +17 -0
  35. data/lib/jun/cli/commands/db/create.rb +35 -0
  36. data/lib/jun/cli/commands/db/drop.rb +18 -0
  37. data/lib/jun/cli/commands/db/migrate.rb +15 -0
  38. data/lib/jun/cli/commands/db/rollback.rb +15 -0
  39. data/lib/jun/cli/commands/db/schema/dump.rb +24 -0
  40. data/lib/jun/cli/commands/db/schema/load.rb +43 -0
  41. data/lib/jun/cli/commands/db/seed.rb +19 -0
  42. data/lib/jun/cli/commands/generate/migration.rb +27 -0
  43. data/lib/jun/cli/commands/new.rb +62 -0
  44. data/lib/jun/cli/commands/server.rb +17 -0
  45. data/lib/jun/cli/commands/version.rb +13 -0
  46. data/lib/jun/cli/generator_templates/migration.rb.erb +11 -0
  47. data/lib/jun/cli/generator_templates/new_app/Gemfile.erb +9 -0
  48. data/lib/jun/cli/generator_templates/new_app/README.md.erb +3 -0
  49. data/lib/jun/cli/generator_templates/new_app/app/controllers/application_controller.rb.erb +4 -0
  50. data/lib/jun/cli/generator_templates/new_app/app/helpers/application_helper.rb.erb +4 -0
  51. data/lib/jun/cli/generator_templates/new_app/app/models/application_record.rb.erb +4 -0
  52. data/lib/jun/cli/generator_templates/new_app/app/views/layouts/application.html.erb.erb +11 -0
  53. data/lib/jun/cli/generator_templates/new_app/bin/console.erb +8 -0
  54. data/lib/jun/cli/generator_templates/new_app/config/application.rb.erb +12 -0
  55. data/lib/jun/cli/generator_templates/new_app/config/environment.rb.erb +7 -0
  56. data/lib/jun/cli/generator_templates/new_app/config/routes.rb.erb +4 -0
  57. data/lib/jun/cli/generator_templates/new_app/config.ru.erb +6 -0
  58. data/lib/jun/cli/generator_templates/new_app/db/seeds.rb.erb +9 -0
  59. data/lib/jun/cli.rb +33 -0
  60. data/lib/jun/connection_adapters/sqlite_adapter.rb +19 -0
  61. data/lib/jun/version.rb +3 -1
  62. data/lib/jun.rb +50 -2
  63. metadata +129 -24
  64. data/.gitignore +0 -10
  65. data/.rspec +0 -2
  66. data/.travis.yml +0 -4
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jun
4
+ module CLI
5
+ module Commands
6
+ module DB
7
+ class Rollback < Base
8
+ def process(*args)
9
+ ActiveRecord::Migrator.new(direction: :down).call
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jun
4
+ module CLI
5
+ module Commands
6
+ module DB
7
+ module Schema
8
+ class Dump < Base
9
+ def process(*args)
10
+ schema_filepath = Jun.root.join("db/schema.sql")
11
+ db_filepath = Jun.root.join("db/app.db")
12
+
13
+ Bundler.with_original_env do
14
+ system("bundle exec sqlite3 #{db_filepath} .schema > #{schema_filepath}")
15
+ end
16
+
17
+ puts "Database schema updated."
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jun
4
+ module CLI
5
+ module Commands
6
+ module DB
7
+ module Schema
8
+ class Load < Base
9
+ def process(*args)
10
+ schema_filepath = Jun.root.join("db/schema.sql")
11
+ db_filepath = Jun.root.join("db/app.db")
12
+
13
+ Bundler.with_original_env do
14
+ system("bundle exec sqlite3 #{db_filepath} < #{schema_filepath}")
15
+ end
16
+
17
+ populate_schema_migrations!
18
+
19
+ puts "Database schema loaded."
20
+ end
21
+
22
+ private
23
+
24
+ def populate_schema_migrations!
25
+ migration_files = Dir.glob(Jun.root.join("db/migrate/*.rb")).sort
26
+
27
+ migration_files.each do |filepath|
28
+ filename = filepath.split("/").last.sub(".rb", "")
29
+ migration_version = filename.split("_").first
30
+
31
+ add_to_schema_migrations(migration_version)
32
+ end
33
+ end
34
+
35
+ def add_to_schema_migrations(version)
36
+ ActiveRecord::Base.connection.execute("INSERT INTO schema_migrations (version) VALUES (#{version});")
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jun
4
+ module CLI
5
+ module Commands
6
+ module DB
7
+ class Seed < Base
8
+ def process(*args)
9
+ seed_filepath = Jun.root.join("db/seed.rb")
10
+ abort("No seed file found.") unless File.exist?(seed_filepath)
11
+
12
+ load seed_filepath
13
+ puts "Seeding complete."
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jun
4
+ module CLI
5
+ module Commands
6
+ module Generate
7
+ class Migration < Base
8
+ def process(*args)
9
+ migration_name = args.first
10
+
11
+ template_filepath = File.expand_path("../../generator_templates/migration.rb.erb", __dir__)
12
+ template = Tilt::ERBTemplate.new(template_filepath)
13
+ template_locals = { migration_name: migration_name }
14
+
15
+ filename = "#{Time.now.to_i}_#{migration_name}.rb"
16
+ filepath = Jun.root.join("db/migrate/#{filename}")
17
+ file_body = template.render(nil, template_locals)
18
+
19
+ filepath.dirname.mkpath
20
+ File.open(filepath, "w") { |f| f.write(file_body) }
21
+ puts "created #{filename}"
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler"
4
+ require "fileutils"
5
+
6
+ module Jun
7
+ module CLI
8
+ module Commands
9
+ class New < Base
10
+ def process(*args)
11
+ if Jun.root
12
+ puts "Already in a Jun app..."
13
+ else
14
+ generate_new_app(args.first)
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def generate_new_app(app_name)
21
+ puts "Generating new Jun app (#{app_name})..."
22
+
23
+ templates = [
24
+ "config.ru",
25
+ "Gemfile",
26
+ "README.md",
27
+ "app/controllers/application_controller.rb",
28
+ "app/helpers/application_helper.rb",
29
+ "app/models/application_record.rb",
30
+ "app/views/layouts/application.html.erb",
31
+ "bin/console",
32
+ "config/application.rb",
33
+ "config/environment.rb",
34
+ "config/routes.rb",
35
+ "db/seeds.rb"
36
+ ]
37
+
38
+ FileUtils.mkdir_p(app_name)
39
+
40
+ FileUtils.chdir(app_name) do
41
+ templates.each do |filepath|
42
+ template_filepath = File.expand_path("../generator_templates/new_app/#{filepath}.erb", __dir__)
43
+ template = Tilt::ERBTemplate.new(template_filepath)
44
+ template_locals = { app_name: app_name }
45
+ file_body = template.render(nil, template_locals)
46
+
47
+ FileUtils.mkdir_p(File.dirname(filepath))
48
+
49
+ File.open(filepath, "w") { |f| f.write(file_body) }
50
+ puts "created #{filepath}"
51
+ end
52
+
53
+ FileUtils.chmod("u+x", "bin/console")
54
+
55
+ puts "Installing dependencies..."
56
+ Bundler.with_original_env { system("bundle install") }
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jun
4
+ module CLI
5
+ module Commands
6
+ class Server < Base
7
+ def process(*args)
8
+ if Jun.root
9
+ system("rerun --background -- rackup -p 6291")
10
+ else
11
+ abort("Command \"#{self.class.command_name}\" must be run inside of a Jun app.")
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Jun
4
+ module CLI
5
+ module Commands
6
+ class Version < Base
7
+ def process(*args)
8
+ puts "Jun #{Jun::VERSION}"
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ class <%= migration_name.camelize %> < ActiveRecord::Migration
4
+ def up
5
+
6
+ end
7
+
8
+ def down
9
+
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ source "https://rubygems.org"
2
+
3
+ gem "jun", path: "/Users/zoran/dev/jun"
4
+ gem "puma"
5
+
6
+ group :development do
7
+ gem "pry"
8
+ gem "rerun"
9
+ end
@@ -0,0 +1,3 @@
1
+ # New Jun App
2
+
3
+ Your newly created Jun app.
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ApplicationController < Jun::ActionController::Base
4
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ApplicationHelper
4
+ end
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ class ApplicationRecord < ActiveRecord::Base
4
+ end
@@ -0,0 +1,11 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <title>Jun App</title>
5
+ <meta name="viewport" content="width=device-width, initial-scale=1">
6
+ </head>
7
+
8
+ <body>
9
+ <%%= yield %>
10
+ </body>
11
+ </html>
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require "bundler/setup"
5
+ require "jun"
6
+
7
+ require "irb"
8
+ IRB.start(__FILE__)
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "jun"
4
+
5
+ # Require gems listed in the Gemfile, including any gems specified
6
+ # in the current environment group (e.g. :development, :production).
7
+ Bundler.require(*Jun.groups)
8
+
9
+ module <%= app_name.camelize %>
10
+ class Application < Jun::Application
11
+ end
12
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Load the Jun application.
4
+ require_relative "application"
5
+
6
+ # Initialize the application.
7
+ Jun.application.initialize!
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ Jun.application.routes.draw do
4
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/setup"
4
+ require_relative "config/environment"
5
+
6
+ run Jun.application
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is used by the `jun db:seed` command and should include
4
+ # any necessary logic for seeding the database.
5
+ #
6
+ # Example:
7
+ #
8
+ # User.create(name: "Sam", occupation: "author")
9
+ # Post.create(title: "How to Build a Bird House")
data/lib/jun/cli.rb ADDED
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ Dir[File.expand_path("cli/commands/**/*.rb", __dir__)].each do |filepath|
4
+ require_relative filepath
5
+ end
6
+
7
+ module Jun
8
+ module CLI
9
+ class << self
10
+ COMMAND_KLASSES = [
11
+ Jun::CLI::Commands::New,
12
+ Jun::CLI::Commands::DB::Create,
13
+ Jun::CLI::Commands::DB::Migrate,
14
+ Jun::CLI::Commands::DB::Rollback,
15
+ Jun::CLI::Commands::DB::Seed,
16
+ Jun::CLI::Commands::DB::Drop,
17
+ Jun::CLI::Commands::DB::Schema::Dump,
18
+ Jun::CLI::Commands::DB::Schema::Load,
19
+ Jun::CLI::Commands::Generate::Migration,
20
+ Jun::CLI::Commands::Server,
21
+ Jun::CLI::Commands::Version
22
+ ].freeze
23
+
24
+ def process_command(argv)
25
+ command_name = argv.shift
26
+ command_klass = COMMAND_KLASSES.find { |klass| klass.command_name == command_name }
27
+ abort("Command \"#{command_name}\" not found.") if command_klass.nil?
28
+
29
+ command_klass.new.process(*argv)
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "sqlite3"
4
+
5
+ class SqliteAdapter
6
+ def initialize
7
+ @db = SQLite3::Database.new(Jun.root.join("db/app.db").to_s, results_as_hash: true)
8
+ end
9
+
10
+ def execute(sql)
11
+ @db.execute(sql).each do |row|
12
+ row.keys.each { |key| row[(key.to_sym rescue key) || key] = row.delete(key) }
13
+ end
14
+ end
15
+
16
+ def columns(table_name)
17
+ @db.table_info(table_name).map { |info| info["name"].to_sym }
18
+ end
19
+ end
data/lib/jun/version.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Jun
2
- VERSION = "0.0.1"
4
+ VERSION = "0.3.0"
3
5
  end
data/lib/jun.rb CHANGED
@@ -1,5 +1,53 @@
1
- require "jun/version"
1
+ # frozen_string_literal: true
2
+
3
+ require "pathname"
4
+
5
+ require_relative "jun/version"
6
+ require_relative "jun/active_support/core_ext"
7
+ require_relative "jun/active_support/dependencies"
8
+ require_relative "jun/action_dispatch/routing/route_set"
9
+ require_relative "jun/active_record/base"
10
+ require_relative "jun/active_record/migration"
11
+ require_relative "jun/active_record/migrator"
12
+ require_relative "jun/active_record/relation"
13
+ require_relative "jun/action_controller/base"
14
+ require_relative "jun/application"
2
15
 
3
16
  module Jun
4
-
17
+ class << self
18
+ attr_accessor :app_class
19
+
20
+ def application
21
+ @application ||= app_class&.new
22
+ end
23
+
24
+ def root
25
+ project_root_path
26
+ end
27
+
28
+ def env
29
+ ENV["JUN_ENV"] || ENV["RACK_ENV"] || "development"
30
+ end
31
+
32
+ def groups
33
+ [:default, env]
34
+ end
35
+
36
+ private
37
+
38
+ def project_root_path
39
+ current_dir = Dir.pwd
40
+ root_file = "config.ru"
41
+
42
+ while current_dir && File.directory?(current_dir) && !File.exist?("#{current_dir}/#{root_file}")
43
+ parent_dir = File.dirname(current_dir)
44
+ current_dir = parent_dir != current_dir && parent_dir
45
+ end
46
+
47
+ root_dir = current_dir if File.exist?("#{current_dir}/#{root_file}")
48
+ return if root_dir.nil?
49
+
50
+ Pathname.new(File.realpath(root_dir))
51
+ end
52
+ end
5
53
  end