devup 0.2.0 → 0.3.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 +4 -4
- data/.gitignore +1 -0
- data/.standard.yml +2 -0
- data/.travis.yml +2 -0
- data/Gemfile.lock +1 -1
- data/README.md +47 -38
- data/lib/devup/boot.rb +12 -2
- data/lib/devup/compose.rb +26 -4
- data/lib/devup/environment.rb +47 -22
- data/lib/devup/logger.rb +10 -0
- data/lib/devup/service.rb +8 -2
- data/lib/devup/service_presenter.rb +88 -0
- data/lib/devup/version.rb +1 -1
- metadata +5 -3
- data/demo.gif +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f3111015b0f138014ede5086a6df15c4e3e4f1b30d1bd7a199ec16a69b7eb84e
|
4
|
+
data.tar.gz: afab2b2376b8137be5bbbc2a3f85d3464720f63312d1a7cefbc948abbf07168d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 58a825f460fce341d66aa22e3b6c257c920908967a1ae64a207f274ebf051144cfba56a19e526e8555c5061d4f2bc37b14ae86bafc3f03a35315352d78aa98ee
|
7
|
+
data.tar.gz: c6897be6a6378476b21e65a0a7d59402641658a400bbc20b655f234d19ab5144e5d23b2bdd764558248519c63fdfc81eee7951c17bcadd779d4c2104377df091
|
data/.gitignore
CHANGED
data/.standard.yml
ADDED
data/.travis.yml
CHANGED
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -1,96 +1,105 @@
|
|
1
|
-
# DevUp!
|
1
|
+
# DevUp! [](https://travis-ci.com/github/sergio-fry/devup) [](https://rubygems.org/gems/devup) [](https://codeclimate.com/github/sergio-fry/devup) [](https://codeclimate.com/github/sergio-fry/devup) [](https://rubygems.org/gems/devup)
|
2
2
|
|
3
|
-
|
4
|
-
[](https://rubygems.org/gems/devup)
|
5
|
-
[](https://codeclimate.com/github/sergio-fry/devup)
|
6
|
-
[](https://codeclimate.com/github/sergio-fry/devup)
|
7
|
-
[](https://rubygems.org/gems/devup)
|
3
|
+
Describe development dependencies with docker-compose. It is not required to remember any fancy command to start docker. Just start developing your app. Rails is a first-class citizen, but could be used without ruby.
|
8
4
|
|
9
|
-
**DevUp!** is a tool to run dev dependencies. It builds ENV vars with dynamic exposed ports for services defined in a docker-compose.yml to access from application.
|
10
5
|
|
11
|
-
|
6
|
+
## Requirements
|
12
7
|
|
13
|
-
|
8
|
+
* Docker (>= 19.03.8)
|
9
|
+
* Docker Compose (>= 1.25.5)
|
14
10
|
|
15
|
-
$ gem install devup
|
16
11
|
|
17
|
-
## Usage
|
18
12
|
|
13
|
+
## Rails
|
19
14
|
|
20
|
-
Create a docker-compose.yml with app dependencies like:
|
15
|
+
Create a docker-compose.devup.yml with app dependencies like:
|
21
16
|
|
22
17
|
```yaml
|
23
|
-
version:
|
18
|
+
version: "3"
|
24
19
|
|
25
20
|
services:
|
26
21
|
postgres:
|
27
|
-
image: postgres
|
22
|
+
image: postgres:10-alpine
|
28
23
|
ports:
|
29
24
|
- "5432"
|
30
25
|
```
|
31
26
|
|
32
|
-
Add
|
27
|
+
Add **DevUp!** to your Gemfile
|
33
28
|
|
34
|
-
|
35
|
-
|
36
|
-
|
29
|
+
```ruby
|
30
|
+
gem "devup", group: [:development, :test]
|
31
|
+
```
|
37
32
|
|
38
|
-
|
39
|
-
POSTGRES_PORT=5432
|
33
|
+
and
|
40
34
|
|
41
|
-
|
35
|
+
bundle install
|
42
36
|
|
43
37
|
|
44
38
|
Update your database.yml to use ENV:
|
45
39
|
|
46
40
|
```yaml
|
47
|
-
|
48
|
-
|
49
|
-
encoding: unicode
|
50
|
-
host: <%= ENV.fetch("POSTGRES_HOST") %>
|
51
|
-
port: <%= ENV.fetch("POSTGRES_PORT") %>
|
52
|
-
username: postgres
|
53
|
-
password:
|
41
|
+
test:
|
42
|
+
url: <%= ENV.fetch("DATABASE_URL") %>
|
54
43
|
|
55
44
|
development:
|
56
|
-
|
57
|
-
database: development
|
45
|
+
url: <%= ENV.fetch("DATABASE_URL") %>
|
58
46
|
|
59
|
-
test:
|
60
|
-
<<: *default
|
61
|
-
database: test
|
62
47
|
```
|
63
48
|
|
64
49
|
|
65
|
-
You are ready to
|
50
|
+
You are ready to use rails with PostgreSQL configured
|
66
51
|
|
67
52
|
$ bundle exec rake db:create db:migrate
|
53
|
+
Creating blog_postgres_1 ... done
|
54
|
+
Created database 'blog_development'
|
55
|
+
|
68
56
|
$ bundle exec rails server
|
69
57
|
|
70
58
|
|
71
|
-
|
59
|
+
## Without Rails
|
60
|
+
|
61
|
+
ENV vars from .env.services are loaded with dotenv automatically.
|
72
62
|
|
73
63
|
|
74
64
|
```ruby
|
75
65
|
require "devup"
|
76
66
|
require "sequel"
|
77
67
|
|
78
|
-
DB = Sequel.connect(
|
68
|
+
DB = Sequel.connect(ENV.fetch("DATABASE_URL"))
|
79
69
|
```
|
80
70
|
|
81
71
|
|
82
|
-
|
72
|
+
## Without Ruby (PHP, nodejs, Java, ...)
|
83
73
|
|
84
74
|
Start up services
|
85
75
|
|
86
76
|
$ 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
|
80
|
+
|
81
|
+
$ cat .env.services
|
82
|
+
export POSTGRES_HOST=0.0.0.0
|
83
|
+
export POSTGRES_PORT=32944
|
84
|
+
export POSTGRES_PORT_5432=32944
|
85
|
+
export MEMCACHED_HOST=0.0.0.0
|
86
|
+
export MEMCACHED_PORT=32943
|
87
|
+
...
|
88
|
+
|
89
|
+
Use your favourite dotenv extension to load vars from .env.services ([node-dotenv](https://www.npmjs.com/package/dotenv), [python-dotenv](https://pypi.org/project/python-dotenv/), [phpdotenv](https://github.com/vlucas/phpdotenv), ...)
|
87
90
|
|
88
|
-
|
91
|
+
Or load ENV vars manually
|
89
92
|
|
90
93
|
$ source .env.services
|
91
94
|
|
92
95
|
Now you can run app
|
93
96
|
|
97
|
+
## How To
|
98
|
+
|
99
|
+
### Disable **DevUp!**
|
100
|
+
|
101
|
+
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
|
+
|
94
103
|
|
95
104
|
## Development
|
96
105
|
|
data/lib/devup/boot.rb
CHANGED
@@ -1,2 +1,12 @@
|
|
1
|
-
|
2
|
-
devup.
|
1
|
+
if ENV.fetch("DEVUP_ENABLED", "true") == "true"
|
2
|
+
devup = Devup::Environment.new pwd: `pwd`
|
3
|
+
devup.up
|
4
|
+
|
5
|
+
begin
|
6
|
+
require "spring/commands"
|
7
|
+
|
8
|
+
Spring.watch devup.root.join("docker-compose.yml")
|
9
|
+
rescue LoadError, ArgumentError
|
10
|
+
# Spring is not available
|
11
|
+
end
|
12
|
+
end
|
data/lib/devup/compose.rb
CHANGED
@@ -1,12 +1,22 @@
|
|
1
1
|
require "yaml"
|
2
|
+
require "open3"
|
2
3
|
|
3
4
|
module Devup
|
4
5
|
class Compose
|
5
|
-
attr_reader :path, :project
|
6
|
+
attr_reader :path, :project, :logger
|
6
7
|
|
7
|
-
|
8
|
+
class Error < StandardError; end
|
9
|
+
|
10
|
+
def initialize(path, project: "devup", logger:)
|
8
11
|
@path = path
|
9
12
|
@project = project
|
13
|
+
@logger = logger
|
14
|
+
end
|
15
|
+
|
16
|
+
def check
|
17
|
+
_output, status = safe_exec("docker-compose -v")
|
18
|
+
|
19
|
+
status
|
10
20
|
end
|
11
21
|
|
12
22
|
def services
|
@@ -18,7 +28,7 @@ module Devup
|
|
18
28
|
end
|
19
29
|
|
20
30
|
def up
|
21
|
-
exec "up -d --remove-orphans"
|
31
|
+
exec "up -d --remove-orphans --renew-anon-volumes"
|
22
32
|
end
|
23
33
|
|
24
34
|
def stop
|
@@ -30,11 +40,23 @@ module Devup
|
|
30
40
|
end
|
31
41
|
|
32
42
|
def exec(cmd)
|
33
|
-
|
43
|
+
output, status = safe_exec "docker-compose -p #{project} -f #{path} #{cmd}"
|
44
|
+
|
45
|
+
raise(Error) unless status
|
46
|
+
|
47
|
+
output
|
34
48
|
end
|
35
49
|
|
36
50
|
private
|
37
51
|
|
52
|
+
def safe_exec(cmd)
|
53
|
+
output, error, status = Open3.capture3(cmd + ";")
|
54
|
+
|
55
|
+
logger.error(error) unless status.success?
|
56
|
+
|
57
|
+
[output, status.success?]
|
58
|
+
end
|
59
|
+
|
38
60
|
def config
|
39
61
|
YAML.safe_load(config_content)
|
40
62
|
end
|
data/lib/devup/environment.rb
CHANGED
@@ -1,52 +1,49 @@
|
|
1
1
|
require "yaml"
|
2
2
|
|
3
|
+
require "devup/logger"
|
3
4
|
require "devup/compose"
|
4
5
|
require "devup/service"
|
6
|
+
require "devup/service_presenter"
|
5
7
|
|
6
8
|
module Devup
|
7
9
|
class Environment
|
8
|
-
attr_reader :pwd, :compose
|
10
|
+
attr_reader :pwd, :compose, :logger
|
9
11
|
|
10
|
-
def initialize(pwd:, compose: nil)
|
12
|
+
def initialize(pwd:, compose: nil, logger: Logger.default)
|
11
13
|
@pwd = pwd.to_s.strip
|
12
|
-
@compose = compose || Compose.new(root.join("docker-compose.yml"), project: project)
|
14
|
+
@compose = compose || Compose.new(root.join("docker-compose.devup.yml"), project: project, logger: logger)
|
15
|
+
@logger = logger
|
13
16
|
end
|
14
17
|
|
15
18
|
def project
|
16
19
|
pwd.split("/")[-1].strip
|
17
20
|
end
|
18
21
|
|
19
|
-
def vars
|
20
|
-
compose.services.map { |name| Service.new(compose, name) }.map { |service|
|
21
|
-
res = []
|
22
|
-
|
23
|
-
res << {"#{service.name}_HOST".upcase => "0.0.0.0"}
|
24
|
-
|
25
|
-
if service.ports.size > 0
|
26
|
-
res << {"#{service.name}_PORT".upcase => service.ports.first.to}
|
27
|
-
|
28
|
-
service.ports.each do |port|
|
29
|
-
res << {"#{service.name}_PORT_#{port.from}".upcase => port.to}
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
res
|
34
|
-
}.flatten
|
35
|
-
end
|
36
|
-
|
37
22
|
def env
|
38
|
-
|
23
|
+
services.map { |s| service_env(s) }.join("\n\n")
|
39
24
|
end
|
40
25
|
|
41
26
|
def up
|
27
|
+
logger.info "DevUp! is starting up services..."
|
28
|
+
check
|
42
29
|
compose.up
|
43
30
|
write_dotenv
|
31
|
+
logger.info "DevUp! is up"
|
32
|
+
clear_dotenv
|
33
|
+
|
34
|
+
rescue StandardError
|
35
|
+
logger.info "DevUp! halted"
|
44
36
|
end
|
45
37
|
|
46
38
|
def down
|
39
|
+
logger.info "DevUp! is shutting down services..."
|
47
40
|
compose.stop
|
48
41
|
compose.rm
|
49
42
|
clear_dotenv
|
43
|
+
logger.info "DevUp! is down"
|
44
|
+
|
45
|
+
rescue StandardError
|
46
|
+
logger.info "DevUp! halted"
|
50
47
|
end
|
51
48
|
|
52
49
|
def root
|
@@ -55,6 +52,32 @@ module Devup
|
|
55
52
|
|
56
53
|
private
|
57
54
|
|
55
|
+
def check
|
56
|
+
return false if missing_config
|
57
|
+
|
58
|
+
compose.check
|
59
|
+
|
60
|
+
true
|
61
|
+
end
|
62
|
+
|
63
|
+
def missing_config
|
64
|
+
if File.exist?(compose.path)
|
65
|
+
false
|
66
|
+
else
|
67
|
+
logger.error "missing #{compose.path}"
|
68
|
+
|
69
|
+
true
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def services
|
74
|
+
@services ||= compose.services.map { |name| Service.new(compose, name) }
|
75
|
+
end
|
76
|
+
|
77
|
+
def service_env(service)
|
78
|
+
ServicePresenter.new(service, project: project).call
|
79
|
+
end
|
80
|
+
|
58
81
|
def write_dotenv
|
59
82
|
File.open(root.join(".env.services"), "w") { |f| f.write dotenv }
|
60
83
|
end
|
@@ -70,7 +93,9 @@ module Devup
|
|
70
93
|
# Home: https://github.com/sergio-fry/devup #
|
71
94
|
####################################################
|
72
95
|
# START
|
96
|
+
|
73
97
|
#{env}
|
98
|
+
|
74
99
|
# END
|
75
100
|
|
76
101
|
DOTENV
|
data/lib/devup/logger.rb
ADDED
data/lib/devup/service.rb
CHANGED
@@ -10,10 +10,16 @@ module Devup
|
|
10
10
|
end
|
11
11
|
|
12
12
|
def ports
|
13
|
+
@ports ||= fetch_ports
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def fetch_ports
|
13
19
|
compose.service_ports(name).map { |el| el.to_s.split(":")[-1] }.map do |from|
|
14
20
|
OpenStruct.new(
|
15
|
-
from: from,
|
16
|
-
to: compose.exec("port #{name} #{from}").split(":")[-1].strip
|
21
|
+
from: from.to_i,
|
22
|
+
to: compose.exec("port #{name} #{from}").split(":")[-1].strip.to_i
|
17
23
|
)
|
18
24
|
end
|
19
25
|
end
|
@@ -0,0 +1,88 @@
|
|
1
|
+
module Devup
|
2
|
+
class ServicePresenter
|
3
|
+
attr_reader :service, :project
|
4
|
+
|
5
|
+
def initialize(service, project: nil)
|
6
|
+
@service = service
|
7
|
+
@project = project
|
8
|
+
end
|
9
|
+
|
10
|
+
def call
|
11
|
+
res = []
|
12
|
+
|
13
|
+
res << "# #{service.name}"
|
14
|
+
res << magic if magic?
|
15
|
+
|
16
|
+
if has_ports?
|
17
|
+
res << host_env
|
18
|
+
res << ports_env
|
19
|
+
else
|
20
|
+
res << "# no exposed ports"
|
21
|
+
end
|
22
|
+
|
23
|
+
res.join "\n"
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def host_env
|
29
|
+
"export #{service.name.upcase}_HOST=0.0.0.0"
|
30
|
+
end
|
31
|
+
|
32
|
+
def ports_env
|
33
|
+
res = []
|
34
|
+
|
35
|
+
res << port_env(to: service.ports.first.to) if service.ports.size == 1
|
36
|
+
|
37
|
+
service.ports.each do |port|
|
38
|
+
res << port_env(from: port.from, to: port.to)
|
39
|
+
end
|
40
|
+
|
41
|
+
res.join "\n"
|
42
|
+
end
|
43
|
+
|
44
|
+
def port_env(from: nil, to:)
|
45
|
+
if from.nil?
|
46
|
+
"export #{service.name.upcase}_PORT=#{to}"
|
47
|
+
else
|
48
|
+
"export #{service.name.upcase}_PORT_#{from}=#{to}"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def has_ports?
|
53
|
+
service.ports.size > 0
|
54
|
+
end
|
55
|
+
|
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
|
+
def port_to(from)
|
74
|
+
service.ports.find { |p| p.from == from }&.to
|
75
|
+
end
|
76
|
+
|
77
|
+
def database_name
|
78
|
+
if defined? Rails
|
79
|
+
[
|
80
|
+
project,
|
81
|
+
Rails.env
|
82
|
+
].join("_")
|
83
|
+
else
|
84
|
+
"db"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
data/lib/devup/version.rb
CHANGED
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.
|
4
|
+
version: 0.3.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: 2020-06-
|
11
|
+
date: 2020-06-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: dotenv
|
@@ -35,6 +35,7 @@ files:
|
|
35
35
|
- ".gitignore"
|
36
36
|
- ".rspec"
|
37
37
|
- ".ruby-version"
|
38
|
+
- ".standard.yml"
|
38
39
|
- ".travis.yml"
|
39
40
|
- ".vimrc"
|
40
41
|
- CODE_OF_CONDUCT.md
|
@@ -45,7 +46,6 @@ files:
|
|
45
46
|
- Rakefile
|
46
47
|
- bin/console
|
47
48
|
- bin/setup
|
48
|
-
- demo.gif
|
49
49
|
- devup.gemspec
|
50
50
|
- exe/devup
|
51
51
|
- lib/devup.rb
|
@@ -53,7 +53,9 @@ files:
|
|
53
53
|
- lib/devup/compose.rb
|
54
54
|
- lib/devup/dotenv.rb
|
55
55
|
- lib/devup/environment.rb
|
56
|
+
- lib/devup/logger.rb
|
56
57
|
- lib/devup/service.rb
|
58
|
+
- lib/devup/service_presenter.rb
|
57
59
|
- lib/devup/version.rb
|
58
60
|
homepage: https://github.com/sergio-fry/devup
|
59
61
|
licenses:
|
data/demo.gif
DELETED
Binary file
|