devup 0.5.3 → 0.6.0

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: f63ff0ee5ffd8b69739caec5f9feee5c9f881e34f866de04a3f1e379ae1cb792
4
- data.tar.gz: 51d840a02ce6e6469dc056d1992c87c450020bad0eeeb3cfe7e465f61508cd20
3
+ metadata.gz: a73dd3dfc833e3fd92c4960b1ad1655a96ffd26db828fda47a9a7cea89c16742
4
+ data.tar.gz: 36682d3cb1e60d6f0d4a830c4c1f0f49f0d0f1db0a902e5c431eeb958a1ddc74
5
5
  SHA512:
6
- metadata.gz: 887ddd31283c4a6220c2a28ce119f0f22a6b22cfbd812c73baf9957af1d21fe3dc46c3799abbcdf647572c6ee41fce197093489e96d51c9f97891f5aa52dbfa2
7
- data.tar.gz: db5711a5e2a3c5a47532693908f67514b3c69214ab0e30c29fa52b3836fec9980c4e372df15c89de7d26fb142e39b9ab4d633da7daf29b53a6962ad563ad431f
6
+ metadata.gz: e9058dbbe0cab9580659df18b1d4b306efca5cdeadb2d8d6436539db8aecc474917f9b8db83da9c7375468e72d82b6810aae854c16aeb305546f033887ae10a6
7
+ data.tar.gz: 9003d6bf8c3b6b2ec2a59d087b9943738763138d6917f20bf9449e5b152db9045ddcf259d1f745e5ebd2b5cd6b1296d6a4833f302bca4451e430ad6d03aae679
data/.gitignore CHANGED
@@ -9,12 +9,14 @@
9
9
  /tmp/
10
10
 
11
11
  # rspec failure tracking
12
- .rspec_status
12
+ /spec/examples.txt
13
13
 
14
14
  # Editor config
15
15
  .vimrc
16
+ .nvimrc
16
17
 
17
- .env.services
18
+ /.env.services
19
+ /.env.local
18
20
  spec/dummy/.env.services
19
21
  spec/dummy_rails/.env.services
20
22
 
data/.rspec CHANGED
@@ -1,3 +1,4 @@
1
- --format documentation
1
+ --format progress
2
2
  --color
3
3
  --require spec_helper
4
+ --tag ~@integration
data/.travis.yml CHANGED
@@ -23,7 +23,8 @@ jobs:
23
23
  - chmod +x ./cc-test-reporter
24
24
  - "./cc-test-reporter before-build"
25
25
  script:
26
- - bundle exec rake spec
26
+ - bundle exec rspec
27
+ - SIMPLECOV_COMMAND_NAME=integration bundle exec rspec --tag @integration
27
28
  after_script:
28
29
  - "./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT"
29
30
  - stage: test
data/.vimrc CHANGED
@@ -1 +1,3 @@
1
+ let g:ale_linters = {'ruby': ['standardrb'], 'javascript': ['standard'], 'json': ['jsonlint']}
2
+ let g:ale_fixers = {'ruby': ['standardrb'], 'javascript': ['standard'], 'json': ['jq']}
1
3
  let g:ale_fix_on_save = 1
data/CHANGELOG.md ADDED
@@ -0,0 +1,71 @@
1
+ # Change Log
2
+
3
+ ## master (unreleased)
4
+
5
+ ## 0.6.0
6
+ * Docker Compose v2.x support added
7
+ * refactoring
8
+
9
+
10
+ ## 0.5.3
11
+
12
+ * readme updated
13
+ * fix disabled mode
14
+
15
+ ## 0.5.2
16
+
17
+ * NameError rescue
18
+ * version display fixed
19
+
20
+ ## 0.5.0
21
+
22
+ * local envs
23
+ * readme updated
24
+
25
+ ## 0.4.3.1
26
+
27
+ * env shortcut for a first port
28
+
29
+ ## 0.4.2
30
+
31
+ * performance optimization
32
+
33
+ ## 0.4.0
34
+
35
+ * commands rework with dry-cli
36
+ * hits of code metric added
37
+ * better spring support
38
+ * no port errro fixed
39
+
40
+ ## 0.3.3
41
+
42
+ * refactoring
43
+ * debug option added
44
+ * up timeout added
45
+ * magic env names removed
46
+
47
+ ## 0.3.2
48
+
49
+ * reverted "remove old volumes (--renew-anon-volumes)"
50
+
51
+ ## 0.3.1
52
+
53
+ * do not clear env each time
54
+
55
+ ## 0.3.0
56
+
57
+ * magic ENV names for postgres, redis, mysql
58
+ * readme updated
59
+ * Spring integaration
60
+ * ability to disable
61
+ * log errors
62
+ * remove old volumes (--renew-anon-volumes)
63
+
64
+ ## 0.2.0
65
+
66
+ * CI configured
67
+ * proof of concept
68
+
69
+ ## 0.1.0
70
+
71
+ * repo init
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- devup (0.5.3)
4
+ devup (0.6.0)
5
5
  dotenv
6
6
  dry-cli
7
7
 
@@ -12,7 +12,7 @@ GEM
12
12
  byebug (11.1.3)
13
13
  concurrent-ruby (1.1.7)
14
14
  diff-lcs (1.4.4)
15
- docile (1.3.2)
15
+ docile (1.4.0)
16
16
  dotenv (2.7.6)
17
17
  dry-cli (0.6.0)
18
18
  concurrent-ruby (~> 1.0)
@@ -50,10 +50,12 @@ GEM
50
50
  rubocop-performance (1.6.1)
51
51
  rubocop (>= 0.71.0)
52
52
  ruby-progressbar (1.10.1)
53
- simplecov (0.18.5)
53
+ simplecov (0.21.2)
54
54
  docile (~> 1.1)
55
55
  simplecov-html (~> 0.11)
56
- simplecov-html (0.12.2)
56
+ simplecov_json_formatter (~> 0.1)
57
+ simplecov-html (0.12.3)
58
+ simplecov_json_formatter (0.1.3)
57
59
  standard (0.4.7)
58
60
  rubocop (~> 0.85.0)
59
61
  rubocop-performance (~> 1.6.0)
data/devup.gemspec CHANGED
@@ -11,7 +11,7 @@ Gem::Specification.new do |spec|
11
11
  spec.email = ["sergei@udalovs.ru"]
12
12
 
13
13
  spec.summary = "A tool to manage docker-compose for development"
14
- # spec.description = %q{TODO: Write a longer description or delete this line.}
14
+ spec.description = "Describe development services with YAML"
15
15
  spec.homepage = "https://github.com/sergio-fry/devup"
16
16
  spec.license = "MIT"
17
17
  spec.required_ruby_version = Gem::Requirement.new(">= 2.3.0")
@@ -20,7 +20,7 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.metadata["homepage_uri"] = spec.homepage
22
22
  spec.metadata["source_code_uri"] = spec.homepage
23
- # spec.metadata["changelog_uri"] = "TODO: Put your gem's CHANGELOG.md URL here."
23
+ spec.metadata["changelog_uri"] = "https://github.com/sergio-fry/devup/blob/master/CHANGELOG.md"
24
24
 
25
25
  # Specify which files should be added to the gem when it is released.
26
26
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
@@ -25,7 +25,7 @@ module Devup
25
25
  def devup
26
26
  @devup ||= Devup::Environment.new(
27
27
  pwd: `pwd`,
28
- logger: Devup::Logger.build(log_level)
28
+ logger: Devup::Logger.new(level: log_level)
29
29
  )
30
30
  end
31
31
 
@@ -13,7 +13,7 @@ module Devup
13
13
  attr_reader :opts
14
14
 
15
15
  def logger
16
- @logger ||= Devup::Logger.build(log_level)
16
+ @logger ||= Devup::Logger.new(level: log_level)
17
17
  end
18
18
 
19
19
  def log_level
@@ -0,0 +1,17 @@
1
+ module Devup
2
+ module Compose
3
+ class PortConfig
4
+ def initialize(config)
5
+ @config = config
6
+ end
7
+
8
+ def from
9
+ @config.split(":")[-1].to_i
10
+ end
11
+
12
+ def ==(another)
13
+ from == another.from
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,103 @@
1
+ require "yaml"
2
+
3
+ require "devup/compose/v1/processes"
4
+ require "devup/compose/port_config"
5
+
6
+ module Devup
7
+ module Compose
8
+ module V1
9
+ class Compose
10
+ attr_reader :path, :project, :logger, :shell
11
+
12
+ class Error < StandardError; end
13
+
14
+ def initialize(path, project: "devup", logger:, shell:)
15
+ @path = path
16
+ @project = project
17
+ @logger = logger
18
+ @shell = shell
19
+ end
20
+
21
+ def check
22
+ true
23
+ end
24
+
25
+ def services
26
+ config["services"].keys
27
+ end
28
+
29
+ def service_ports(name)
30
+ return [] if config["services"][name]["ports"].nil?
31
+
32
+ config["services"][name]["ports"].map { |el| PortConfig.new(el.to_s) }
33
+ end
34
+
35
+ def port_mapping(port)
36
+ processes.port_mapping(port)
37
+ end
38
+
39
+ def up
40
+ exec "up -d --remove-orphans"
41
+
42
+ wait_alive 3
43
+ end
44
+
45
+ def stop
46
+ exec "stop"
47
+ end
48
+
49
+ def rm
50
+ exec "rm -f"
51
+ end
52
+
53
+ private
54
+
55
+ def wait_alive(timeout, retry_sleep: 0.3)
56
+ start = Time.now
57
+
58
+ loop {
59
+ break if alive?
60
+
61
+ if Time.now - start > timeout
62
+ logger.error "can't run services"
63
+ break
64
+ end
65
+ sleep retry_sleep
66
+ }
67
+ end
68
+
69
+ def alive?
70
+ processes(cached: false).up?
71
+ end
72
+
73
+ def processes(cached: true)
74
+ Processes.new(cached ? exec_ps_cached : exec_ps)
75
+ end
76
+
77
+ def exec_ps
78
+ @exec_ps_output = exec("ps")
79
+ end
80
+
81
+ def exec_ps_cached
82
+ @exec_ps_output ||= exec("ps")
83
+ end
84
+
85
+ def exec(cmd)
86
+ resp = shell.exec "docker-compose -p #{project} -f #{path} #{cmd}"
87
+
88
+ raise(Error) unless resp.success?
89
+
90
+ resp.data
91
+ end
92
+
93
+ def config
94
+ YAML.safe_load(config_content)
95
+ end
96
+
97
+ def config_content
98
+ File.read(path)
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,34 @@
1
+ require "devup/port_mapping"
2
+
3
+ module Devup
4
+ module Compose
5
+ module V1
6
+ class Processes
7
+ attr_reader :output
8
+ def initialize(output)
9
+ @output = output
10
+ end
11
+
12
+ def up?
13
+ service_lines.map { |line|
14
+ line.match(/Up/) && !line.match(/Exit/)
15
+ }.all?
16
+ end
17
+
18
+ def port_mapping(port)
19
+ m = output.match(/\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}:(\d+)->#{port}\/tcp/)
20
+
21
+ return PortMapping.new(port, nil) if m.nil?
22
+
23
+ PortMapping.new(port, m[1].to_i)
24
+ end
25
+
26
+ private
27
+
28
+ def service_lines
29
+ output.split("\n")[2..-1]
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,14 @@
1
+ require "devup/compose/v1/compose"
2
+ require "devup/compose/v2/processes"
3
+
4
+ module Devup
5
+ module Compose
6
+ module V2
7
+ class Compose < V1::Compose
8
+ def processes(cached: true)
9
+ Processes.new(cached ? exec_ps_cached : exec_ps)
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,21 @@
1
+ require "devup/compose/v1/processes"
2
+
3
+ module Devup
4
+ module Compose
5
+ module V2
6
+ class Processes < V1::Processes
7
+ def up?
8
+ service_lines.map { |line|
9
+ line.match(/running/) && !line.match(/exited/)
10
+ }.all?
11
+ end
12
+
13
+ private
14
+
15
+ def service_lines
16
+ output.split("\n")[1..-1]
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
data/lib/devup/compose.rb CHANGED
@@ -1,94 +1,17 @@
1
- require "yaml"
2
-
3
- require "devup/compose/ps"
1
+ require "devup/compose/v1/compose"
2
+ require "devup/compose/v2/compose"
4
3
 
5
4
  module Devup
6
- class Compose
7
- attr_reader :path, :project, :logger, :shell
8
-
9
- class Error < StandardError; end
10
-
11
- def initialize(path, project: "devup", logger:, shell:)
12
- @path = path
13
- @project = project
14
- @logger = logger
15
- @shell = shell
16
- end
17
-
18
- def check
19
- true
20
- end
21
-
22
- def services
23
- config["services"].keys
24
- end
25
-
26
- def service_ports(name)
27
- return [] if config["services"][name]["ports"].nil?
28
-
29
- config["services"][name]["ports"].map { |el| el.to_s.split(":")[-1].to_i }
30
- end
31
-
32
- def port_mapping(port)
33
- ComposeHelpers::Ps.new(exec_ps_cached).port_mapping(port)
34
- end
35
-
36
- def up
37
- exec "up -d --remove-orphans"
38
-
39
- wait_alive 3
40
- end
41
-
42
- def stop
43
- exec "stop"
44
- end
45
-
46
- def rm
47
- exec "rm -f"
48
- end
49
-
50
- private
51
-
52
- def wait_alive(timeout, retry_sleep: 0.3)
53
- start = Time.now
54
-
55
- loop {
56
- break if alive?
57
-
58
- if Time.now - start > timeout
59
- logger.error "can't run services"
60
- break
61
- end
62
- sleep retry_sleep
63
- }
64
- end
65
-
66
- def alive?
67
- ComposeHelpers::Ps.new(exec_ps).up?
68
- end
69
-
70
- def exec_ps
71
- @exec_ps_output = exec("ps")
72
- end
73
-
74
- def exec_ps_cached
75
- @exec_ps_output ||= exec("ps")
76
- end
77
-
78
- def exec(cmd)
79
- resp = shell.exec "docker-compose -p #{project} -f #{path} #{cmd}"
80
-
81
- raise(Error) unless resp.success?
82
-
83
- resp.data
84
- end
85
-
86
- def config
87
- YAML.safe_load(config_content)
88
- end
89
-
90
- def config_content
91
- File.read(path)
5
+ module Compose
6
+ def self.current_version(version = `docker-compose -v`)
7
+ case version.match(/(\d).\d+.\d+/)[1].to_i
8
+ when 1
9
+ V1::Compose
10
+ when 2
11
+ V2::Compose
12
+ else
13
+ raise "Can't detect compose version"
14
+ end
92
15
  end
93
16
  end
94
17
  end
@@ -1,7 +1,7 @@
1
1
  module Devup
2
2
  class DotenvLoadList
3
3
  def initialize(env: nil)
4
- @env = env.to_sym unless env.nil?
4
+ @env = env&.to_sym
5
5
  end
6
6
 
7
7
  def to_a
@@ -1,16 +1,17 @@
1
1
  require "yaml"
2
2
 
3
3
  require "devup/logger"
4
- require "devup/compose"
5
4
  require "devup/service"
6
- require "devup/service_presenter"
5
+ require "devup/service_dotenv"
7
6
  require "devup/shell"
8
7
 
8
+ require "devup/compose"
9
+
9
10
  module Devup
10
11
  class Environment
11
12
  attr_reader :pwd, :logger, :shell
12
13
 
13
- def initialize(pwd:, compose: nil, logger: Logger.build, shell: Shell.new(pwd: pwd, logger: logger))
14
+ def initialize(pwd:, compose: nil, logger:, shell: Shell.new(pwd: pwd, logger: logger))
14
15
  @pwd = pwd.to_s.strip
15
16
  @compose = compose
16
17
  @logger = logger
@@ -75,7 +76,7 @@ module Devup
75
76
  end
76
77
 
77
78
  def service_env(service)
78
- ServicePresenter.new(service, project: project).call
79
+ ServiceDotenv.new(service, project: project).text
79
80
  end
80
81
 
81
82
  def write_dotenv
@@ -103,7 +104,7 @@ module Devup
103
104
 
104
105
  def compose
105
106
  @compose ||= begin
106
- Compose.new(
107
+ Compose.current_version.new(
107
108
  root.join("docker-compose.devup.yml"),
108
109
  project: project, logger: logger, shell: shell
109
110
  )
data/lib/devup/logger.rb CHANGED
@@ -1,14 +1,36 @@
1
1
  require "logger"
2
2
 
3
3
  module Devup
4
- class Logger < ::Logger
5
- def self.build(level = :info)
6
- formatter = ->(severity, _time, _progname, msg) { "DevUp! #{severity} #{msg}\n" }
7
- logger = new(STDOUT, formatter: formatter)
4
+ class Logger
5
+ def initialize(device: STDOUT, level: :info)
6
+ @level = level
7
+ @device = device
8
+ end
9
+
10
+ def debug(msg)
11
+ logger.debug msg
12
+ end
8
13
 
9
- logger.level = level
14
+ def info(msg)
15
+ logger.info msg
16
+ end
17
+
18
+ def error(msg)
19
+ logger.error msg
20
+ end
21
+
22
+ private
23
+
24
+ def logger
25
+ logger = ::Logger.new(@device, formatter: formatter)
26
+
27
+ logger.level = @level
10
28
 
11
29
  logger
12
30
  end
31
+
32
+ def formatter
33
+ ->(severity, _time, _progname, msg) { "DevUp! #{severity} #{msg}\n" }
34
+ end
13
35
  end
14
36
  end
@@ -2,6 +2,7 @@ require "socket"
2
2
  require "timeout"
3
3
 
4
4
  module Devup
5
+ # TODO we should use this to check ports are ready
5
6
  class PortChecker
6
7
  def call(port)
7
8
  s = TCPSocket.new("0.0.0.0", port)
@@ -0,0 +1,14 @@
1
+ module Devup
2
+ class PortMapping
3
+ def initialize(from, to)
4
+ @from = from
5
+ @to = to
6
+ end
7
+
8
+ attr_reader :from, :to
9
+
10
+ def ==(another)
11
+ @from == another.from && @to == another.to
12
+ end
13
+ end
14
+ end
data/lib/devup/service.rb CHANGED
@@ -1,4 +1,4 @@
1
- require "ostruct"
1
+ require_relative "port_mapping"
2
2
 
3
3
  module Devup
4
4
  class Service
@@ -16,11 +16,8 @@ module Devup
16
16
  private
17
17
 
18
18
  def fetch_ports
19
- compose.service_ports(name).map do |from|
20
- OpenStruct.new(
21
- from: from,
22
- to: compose.port_mapping(from)
23
- )
19
+ compose.service_ports(name).map do |el|
20
+ compose.port_mapping(el.from)
24
21
  end
25
22
  end
26
23
  end
@@ -1,5 +1,5 @@
1
1
  module Devup
2
- class ServicePresenter
2
+ class ServiceDotenv
3
3
  attr_reader :service, :project
4
4
 
5
5
  def initialize(service, project: nil)
@@ -7,7 +7,7 @@ module Devup
7
7
  @project = project
8
8
  end
9
9
 
10
- def call
10
+ def text
11
11
  res = []
12
12
 
13
13
  res << "# #{service.name}"
data/lib/devup/shell.rb CHANGED
@@ -9,6 +9,7 @@ module Devup
9
9
  @logger = logger
10
10
  end
11
11
 
12
+ # TODO maybe it should become somthing like ExecutedShellCommand ?
12
13
  Result = Struct.new(:data, :status) {
13
14
  def success?
14
15
  status
data/lib/devup/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Devup
2
- VERSION = "0.5.3"
2
+ VERSION = "0.6.0"
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.5.3
4
+ version: 0.6.0
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: 2021-02-02 00:00:00.000000000 Z
11
+ date: 2021-11-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dotenv
@@ -38,7 +38,7 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
- description:
41
+ description: Describe development services with YAML
42
42
  email:
43
43
  - sergei@udalovs.ru
44
44
  executables:
@@ -52,6 +52,7 @@ files:
52
52
  - ".standard.yml"
53
53
  - ".travis.yml"
54
54
  - ".vimrc"
55
+ - CHANGELOG.md
55
56
  - CODE_OF_CONDUCT.md
56
57
  - Gemfile
57
58
  - Gemfile.lock
@@ -70,13 +71,18 @@ files:
70
71
  - lib/devup/cli/commands/down.rb
71
72
  - lib/devup/cli/commands/up.rb
72
73
  - lib/devup/compose.rb
73
- - lib/devup/compose/ps.rb
74
+ - lib/devup/compose/port_config.rb
75
+ - lib/devup/compose/v1/compose.rb
76
+ - lib/devup/compose/v1/processes.rb
77
+ - lib/devup/compose/v2/compose.rb
78
+ - lib/devup/compose/v2/processes.rb
74
79
  - lib/devup/dotenv_load_list.rb
75
80
  - lib/devup/environment.rb
76
81
  - lib/devup/logger.rb
77
82
  - lib/devup/port_checker.rb
83
+ - lib/devup/port_mapping.rb
78
84
  - lib/devup/service.rb
79
- - lib/devup/service_presenter.rb
85
+ - lib/devup/service_dotenv.rb
80
86
  - lib/devup/shell.rb
81
87
  - lib/devup/version.rb
82
88
  homepage: https://github.com/sergio-fry/devup
@@ -85,6 +91,7 @@ licenses:
85
91
  metadata:
86
92
  homepage_uri: https://github.com/sergio-fry/devup
87
93
  source_code_uri: https://github.com/sergio-fry/devup
94
+ changelog_uri: https://github.com/sergio-fry/devup/blob/master/CHANGELOG.md
88
95
  post_install_message:
89
96
  rdoc_options: []
90
97
  require_paths:
@@ -1,30 +0,0 @@
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