devup 0.3.2.1 → 0.3.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3e2a14e12cc9c1661134d64021d14f6553df35ab4021c85b3512103d1171503e
4
- data.tar.gz: 9a63920fc33cbe3f0d312ef5dd4bd3e1b220618435ac1dab117e87aab0362267
3
+ metadata.gz: d83b3c98d30a71d2414a1fc5106d9a907612911f4b05a2246404f08215be203c
4
+ data.tar.gz: 772cee331bdcd822f497cc7121a6d6201b971b65b930e47864770d7cbb30df62
5
5
  SHA512:
6
- metadata.gz: 8617036ce5f17bcae494dde0f333faa65c355b71fe2d1b360d9a1f6c41d09762340fe6ca4c8050f547983115e7849f87aa8818c76c396aed9ce430a0f354721f
7
- data.tar.gz: c016d3af0f75c8c64849429ea68e3d4a156ff75cc729a286b123f78fa96d3e5c574193aa78b27e2600a9edd0bc8c883bdd3021aa27e61c14965ef2794b1364d1
6
+ metadata.gz: e29107cb8acd259d0e1f038e93cd7809e5b933abdedace59e17001e974220632ed95fe14aadb8e28007c6164665fbd4b4398268b1b476d35042c89457dde78b7
7
+ data.tar.gz: 7145ada30c07f14547ea5fc4c3d6ef9222a7dee288bb2d38b547a1907d844646e737d43a8f740668739465de60217d7e1a0501601618bb5e270c77e99903e713
data/.gitignore CHANGED
@@ -14,6 +14,7 @@
14
14
  # Editor config
15
15
  .vimrc
16
16
 
17
+ .env.services
17
18
  spec/dummy/.env.services
18
19
  spec/dummy_rails/.env.services
19
20
 
data/Gemfile CHANGED
@@ -8,3 +8,4 @@ gem "rspec", "~> 3.0"
8
8
  gem "standard"
9
9
  gem "simplecov", require: false
10
10
  gem "byebug"
11
+ gem "lefthook"
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- devup (0.3.2.1)
4
+ devup (0.3.3)
5
5
  dotenv
6
6
 
7
7
  GEM
@@ -14,6 +14,7 @@ GEM
14
14
  dotenv (2.7.5)
15
15
  jaro_winkler (1.5.4)
16
16
  json (2.3.0)
17
+ lefthook (0.7.2)
17
18
  parallel (1.19.1)
18
19
  parser (2.7.1.0)
19
20
  ast (~> 2.4.0)
@@ -60,6 +61,7 @@ PLATFORMS
60
61
  DEPENDENCIES
61
62
  byebug
62
63
  devup!
64
+ lefthook
63
65
  rake (~> 12.0)
64
66
  rspec (~> 3.0)
65
67
  simplecov
data/README.md CHANGED
@@ -32,7 +32,7 @@ gem "devup", group: [:development, :test]
32
32
 
33
33
  and
34
34
 
35
- bundle install
35
+ $ bundle install
36
36
 
37
37
 
38
38
  Update your database.yml to use ENV:
@@ -49,11 +49,11 @@ development:
49
49
 
50
50
  You are ready to use rails with PostgreSQL configured
51
51
 
52
- $ bundle exec rake db:create db:migrate
53
- Creating blog_postgres_1 ... done
54
- Created database 'blog_development'
52
+ $ RAILS_ENV=test bundle exec rake db:create
53
+ DevUp! INFO starting up...
54
+ DevUp! INFO up
55
55
 
56
- $ bundle exec rails server
56
+ $ Created database 'dummy_rails_test'
57
57
 
58
58
 
59
59
  ## Without Rails
@@ -71,12 +71,15 @@ DB = Sequel.connect(ENV.fetch("DATABASE_URL"))
71
71
 
72
72
  ## Without Ruby (PHP, nodejs, Java, ...)
73
73
 
74
+ Install DevUp!
75
+
76
+ $ gem install devup
77
+
74
78
  Start up services
75
79
 
76
80
  $ devup
77
- dummy_rails_postgres_1 is up-to-date
78
- dummy_rails_redis_1 is up-to-date
79
- dummy_rails_memcached_1 is up-to-date
81
+ DevUp! INFO starting up...
82
+ DevUp! INFO up
80
83
 
81
84
  $ cat .env.services
82
85
  export POSTGRES_HOST=0.0.0.0
@@ -100,6 +103,10 @@ Now you can run app
100
103
 
101
104
  If you don't want devup to setup your dev services, you can disable it by using `DEVUP_ENABLED=false`. Just add it to .env.local file.
102
105
 
106
+ ### Debug
107
+
108
+ $ export DEVUP_LOG_LEVEL=debug
109
+ $ devup
103
110
 
104
111
  ## Development
105
112
 
@@ -0,0 +1,8 @@
1
+ version: '3'
2
+
3
+ services:
4
+ postgres:
5
+ image: postgres:11
6
+ ports:
7
+ - "5432"
8
+
data/exe/devup CHANGED
@@ -2,7 +2,10 @@
2
2
 
3
3
  require "devup/environment"
4
4
 
5
- devup = Devup::Environment.new pwd: `pwd`
5
+ devup = Devup::Environment.new(
6
+ pwd: `pwd`,
7
+ logger: Devup::Logger.build(ENV.fetch("DEVUP_LOG_LEVEL", "info"))
8
+ )
6
9
 
7
10
  # TODO: use dry-cli here
8
11
  case ARGV[0]
@@ -0,0 +1,7 @@
1
+ pre-commit:
2
+ parallel: true
3
+ commands:
4
+ lint:
5
+ files: git diff --name-only --staged
6
+ glob: "*.rb"
7
+ run: standardrb --force-exclusion {files}
@@ -1,5 +1,8 @@
1
1
  if ENV.fetch("DEVUP_ENABLED", "true") == "true"
2
- devup = Devup::Environment.new pwd: `pwd`
2
+ devup = Devup::Environment.new(
3
+ pwd: `pwd`,
4
+ logger: Devup::Logger.build(ENV.fetch("DEVUP_LOG_LEVEL", "info"))
5
+ )
3
6
  devup.up
4
7
 
5
8
  begin
@@ -1,22 +1,22 @@
1
1
  require "yaml"
2
- require "open3"
2
+
3
+ require "devup/compose/ps"
3
4
 
4
5
  module Devup
5
6
  class Compose
6
- attr_reader :path, :project, :logger
7
+ attr_reader :path, :project, :logger, :shell
7
8
 
8
9
  class Error < StandardError; end
9
10
 
10
- def initialize(path, project: "devup", logger:)
11
+ def initialize(path, project: "devup", logger:, shell:)
11
12
  @path = path
12
13
  @project = project
13
14
  @logger = logger
15
+ @shell = shell
14
16
  end
15
17
 
16
18
  def check
17
- _output, status = safe_exec("docker-compose -v")
18
-
19
- status
19
+ true
20
20
  end
21
21
 
22
22
  def services
@@ -24,11 +24,17 @@ module Devup
24
24
  end
25
25
 
26
26
  def service_ports(name)
27
- config["services"][name]["ports"]
27
+ config["services"][name]["ports"].map { |el| el.to_s.split(":")[-1].to_i }
28
+ end
29
+
30
+ def port_mapping(service, port)
31
+ exec("port #{service} #{port}").split(":")[-1].strip.to_i
28
32
  end
29
33
 
30
34
  def up
31
35
  exec "up -d --remove-orphans"
36
+
37
+ wait_alive 3
32
38
  end
33
39
 
34
40
  def stop
@@ -39,22 +45,32 @@ module Devup
39
45
  exec "rm -f"
40
46
  end
41
47
 
42
- def exec(cmd)
43
- output, status = safe_exec "docker-compose -p #{project} -f #{path} #{cmd}"
48
+ private
49
+
50
+ def wait_alive(timeout, retry_sleep: 0.3)
51
+ start = Time.now
44
52
 
45
- raise(Error) unless status
53
+ loop {
54
+ break if alive?
46
55
 
47
- output
56
+ if Time.now - start > timeout
57
+ logger.error "can't run services"
58
+ break
59
+ end
60
+ sleep retry_sleep
61
+ }
48
62
  end
49
63
 
50
- private
64
+ def alive?
65
+ ComposeHelpers::Ps.new(exec("ps")).up?
66
+ end
51
67
 
52
- def safe_exec(cmd)
53
- output, error, status = Open3.capture3(cmd + ";")
68
+ def exec(cmd)
69
+ resp = shell.exec "docker-compose -p #{project} -f #{path} #{cmd}"
54
70
 
55
- logger.error(error) unless status.success?
71
+ raise(Error) unless resp.success?
56
72
 
57
- [output, status.success?]
73
+ resp.data
58
74
  end
59
75
 
60
76
  def config
@@ -0,0 +1,30 @@
1
+ module Devup
2
+ module ComposeHelpers
3
+ class Ps
4
+ attr_reader :output
5
+ def initialize(output)
6
+ @output = output
7
+ end
8
+
9
+ def up?
10
+ service_lines.map { |line|
11
+ line.match(/Up/) && !line.match(/Exit/)
12
+ }.all?
13
+ end
14
+
15
+ def port_mapping(port)
16
+ m = output.match(/\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}:(\d+)->#{port}\/tcp/)
17
+
18
+ return if m.nil?
19
+
20
+ m[1].to_i
21
+ end
22
+
23
+ private
24
+
25
+ def service_lines
26
+ output.split("\n")[2..-1]
27
+ end
28
+ end
29
+ end
30
+ end
@@ -4,15 +4,17 @@ require "devup/logger"
4
4
  require "devup/compose"
5
5
  require "devup/service"
6
6
  require "devup/service_presenter"
7
+ require "devup/shell"
7
8
 
8
9
  module Devup
9
10
  class Environment
10
- attr_reader :pwd, :compose, :logger
11
+ attr_reader :pwd, :logger, :shell
11
12
 
12
- def initialize(pwd:, compose: nil, logger: Logger.default)
13
+ def initialize(pwd:, compose: nil, logger: Logger.build, shell: Shell.new(pwd: pwd, logger: logger))
13
14
  @pwd = pwd.to_s.strip
14
- @compose = compose || Compose.new(root.join("docker-compose.devup.yml"), project: project, logger: logger)
15
+ @compose = compose
15
16
  @logger = logger
17
+ @shell = shell
16
18
  end
17
19
 
18
20
  def project
@@ -24,24 +26,26 @@ module Devup
24
26
  end
25
27
 
26
28
  def up
27
- logger.info "DevUp! is starting up services..."
29
+ logger.info "starting up..."
28
30
  check
29
31
  compose.up
30
32
  write_dotenv
31
- logger.info "DevUp! is up"
32
- rescue
33
+ logger.info "up"
34
+ rescue => ex
33
35
  clear_dotenv
34
- logger.info "DevUp! halted"
36
+ logger.debug ex
37
+ logger.error "halted"
35
38
  end
36
39
 
37
40
  def down
38
- logger.info "DevUp! is shutting down services..."
41
+ logger.info "shutting down..."
39
42
  compose.stop
40
43
  compose.rm
41
44
  clear_dotenv
42
- logger.info "DevUp! is down"
43
- rescue
44
- logger.info "DevUp! halted"
45
+ logger.info "down"
46
+ rescue => ex
47
+ logger.debug ex
48
+ logger.info "halted"
45
49
  end
46
50
 
47
51
  def root
@@ -51,11 +55,8 @@ module Devup
51
55
  private
52
56
 
53
57
  def check
54
- return false if missing_config
55
-
58
+ raise if missing_config
56
59
  compose.check
57
-
58
- true
59
60
  end
60
61
 
61
62
  def missing_config
@@ -98,5 +99,14 @@ module Devup
98
99
 
99
100
  DOTENV
100
101
  end
102
+
103
+ def compose
104
+ @compose ||= begin
105
+ Compose.new(
106
+ root.join("docker-compose.devup.yml"),
107
+ project: project, logger: logger, shell: shell
108
+ )
109
+ end
110
+ end
101
111
  end
102
112
  end
@@ -2,9 +2,13 @@ require "logger"
2
2
 
3
3
  module Devup
4
4
  class Logger < ::Logger
5
- def self.default
6
- formatter = ->(_severity, _time, _progname, msg) { "#{msg}\n" }
7
- new(STDOUT, formatter: formatter)
5
+ def self.build(level = :info)
6
+ formatter = ->(severity, _time, _progname, msg) { "DevUp! #{severity} #{msg}\n" }
7
+ logger = new(STDOUT, formatter: formatter)
8
+
9
+ logger.level = level
10
+
11
+ logger
8
12
  end
9
13
  end
10
14
  end
@@ -0,0 +1,16 @@
1
+ require "socket"
2
+ require "timeout"
3
+
4
+ module Devup
5
+ class PortChecker
6
+ def call(port)
7
+ s = TCPSocket.new("0.0.0.0", port)
8
+ s.write "1"
9
+ s.close
10
+
11
+ true
12
+ rescue Errno::ECONNREFUSED, Errno::EHOSTUNREACH
13
+ false
14
+ end
15
+ end
16
+ end
@@ -16,10 +16,10 @@ module Devup
16
16
  private
17
17
 
18
18
  def fetch_ports
19
- compose.service_ports(name).map { |el| el.to_s.split(":")[-1] }.map do |from|
19
+ compose.service_ports(name).map do |from|
20
20
  OpenStruct.new(
21
- from: from.to_i,
22
- to: compose.exec("port #{name} #{from}").split(":")[-1].strip.to_i
21
+ from: from,
22
+ to: compose.port_mapping(name, from)
23
23
  )
24
24
  end
25
25
  end
@@ -11,7 +11,6 @@ module Devup
11
11
  res = []
12
12
 
13
13
  res << "# #{service.name}"
14
- res << magic if magic?
15
14
 
16
15
  if has_ports?
17
16
  res << host_env
@@ -53,36 +52,12 @@ module Devup
53
52
  service.ports.size > 0
54
53
  end
55
54
 
56
- def magic?
57
- %w[postgres redis mysql memcached].include? service.name
58
- end
59
-
60
- def magic
61
- case service.name
62
- when "postgres"
63
- "export DATABASE_URL=postgres://postgres@0.0.0.0:#{port_to(5432)}/#{database_name}"
64
- when "mysql"
65
- "export DATABASE_URL=mysql2://root@0.0.0.0:#{port_to(3306)}/#{database_name}"
66
- when "redis"
67
- "export REDIS_URL=redis://0.0.0.0:#{port_to(6379)}"
68
- when "memcached"
69
- "export MEMCACHE_SERVERS=0.0.0.0:#{port_to(11211)}"
70
- end
71
- end
72
-
73
55
  def port_to(from)
74
56
  service.ports.find { |p| p.from == from }&.to
75
57
  end
76
58
 
77
59
  def database_name
78
- if defined? Rails
79
- [
80
- project,
81
- Rails.env
82
- ].join("_")
83
- else
84
- "db"
85
- end
60
+ "db"
86
61
  end
87
62
  end
88
63
  end
@@ -0,0 +1,28 @@
1
+ require "open3"
2
+
3
+ module Devup
4
+ class Shell
5
+ attr_reader :pwd, :logger
6
+
7
+ def initialize(pwd:, logger:)
8
+ @pwd = pwd
9
+ @logger = logger
10
+ end
11
+
12
+ Result = Struct.new(:data, :status) {
13
+ def success?
14
+ status
15
+ end
16
+ }
17
+
18
+ def exec(cmd)
19
+ logger.debug "$ #{cmd}"
20
+
21
+ output, error, status = Open3.capture3(cmd + ";")
22
+
23
+ logger.error(error) unless status.success?
24
+
25
+ Result.new(output, status.success?)
26
+ end
27
+ end
28
+ end
@@ -1,3 +1,3 @@
1
1
  module Devup
2
- VERSION = "0.3.2.1"
2
+ VERSION = "0.3.3"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: devup
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2.1
4
+ version: 0.3.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sergei O. Udalov
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-06-09 00:00:00.000000000 Z
11
+ date: 2020-06-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dotenv
@@ -47,15 +47,20 @@ files:
47
47
  - bin/console
48
48
  - bin/setup
49
49
  - devup.gemspec
50
+ - docker-compose.devup.yml
50
51
  - exe/devup
52
+ - lefthook.yml
51
53
  - lib/devup.rb
52
54
  - lib/devup/boot.rb
53
55
  - lib/devup/compose.rb
56
+ - lib/devup/compose/ps.rb
54
57
  - lib/devup/dotenv.rb
55
58
  - lib/devup/environment.rb
56
59
  - lib/devup/logger.rb
60
+ - lib/devup/port_checker.rb
57
61
  - lib/devup/service.rb
58
62
  - lib/devup/service_presenter.rb
63
+ - lib/devup/shell.rb
59
64
  - lib/devup/version.rb
60
65
  homepage: https://github.com/sergio-fry/devup
61
66
  licenses: