devup 0.5.3 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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