devup 0.1.1 → 0.3.2.1
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 +23 -2
- data/Gemfile.lock +4 -2
- data/README.md +89 -12
- data/devup.gemspec +2 -0
- data/exe/devup +1 -1
- data/lib/devup.rb +3 -5
- data/lib/devup/boot.rb +12 -0
- data/lib/devup/compose.rb +25 -3
- data/lib/devup/dotenv.rb +2 -0
- data/lib/devup/environment.rb +51 -23
- 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 +22 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3e2a14e12cc9c1661134d64021d14f6553df35ab4021c85b3512103d1171503e
|
4
|
+
data.tar.gz: 9a63920fc33cbe3f0d312ef5dd4bd3e1b220618435ac1dab117e87aab0362267
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8617036ce5f17bcae494dde0f333faa65c355b71fe2d1b360d9a1f6c41d09762340fe6ca4c8050f547983115e7849f87aa8818c76c396aed9ce430a0f354721f
|
7
|
+
data.tar.gz: c016d3af0f75c8c64849429ea68e3d4a156ff75cc729a286b123f78fa96d3e5c574193aa78b27e2600a9edd0bc8c883bdd3021aa27e61c14965ef2794b1364d1
|
data/.gitignore
CHANGED
data/.standard.yml
ADDED
data/.travis.yml
CHANGED
@@ -1,11 +1,14 @@
|
|
1
|
+
env:
|
2
|
+
matrix:
|
3
|
+
- BUNDLER_VERSION=2.1.4
|
1
4
|
language: ruby
|
2
5
|
cache: bundler
|
3
6
|
rvm:
|
4
7
|
- 2.7.1
|
8
|
+
- 2.6.6
|
9
|
+
- 2.5.8
|
5
10
|
services:
|
6
11
|
- docker
|
7
|
-
env:
|
8
|
-
- BUNDLER_VERSION=2.1.4
|
9
12
|
before_install:
|
10
13
|
- gem install bundler -v $BUNDLER_VERSION
|
11
14
|
bundler_args: "--jobs=3 --retry=3"
|
@@ -18,3 +21,21 @@ deploy:
|
|
18
21
|
tags: true
|
19
22
|
repo: sergio-fry/devup
|
20
23
|
skip_cleanup: 'true'
|
24
|
+
|
25
|
+
jobs:
|
26
|
+
include:
|
27
|
+
- stage: test
|
28
|
+
name: RSpec
|
29
|
+
before_script:
|
30
|
+
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64
|
31
|
+
> ./cc-test-reporter
|
32
|
+
- chmod +x ./cc-test-reporter
|
33
|
+
- "./cc-test-reporter before-build"
|
34
|
+
script:
|
35
|
+
- bundle exec rake spec
|
36
|
+
after_script:
|
37
|
+
- "./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT"
|
38
|
+
- stage: test
|
39
|
+
name: Lint
|
40
|
+
script:
|
41
|
+
- bundle exec standardrb
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
devup (0.
|
4
|
+
devup (0.3.2.1)
|
5
|
+
dotenv
|
5
6
|
|
6
7
|
GEM
|
7
8
|
remote: https://rubygems.org/
|
@@ -10,6 +11,7 @@ GEM
|
|
10
11
|
byebug (11.1.3)
|
11
12
|
diff-lcs (1.3)
|
12
13
|
docile (1.3.2)
|
14
|
+
dotenv (2.7.5)
|
13
15
|
jaro_winkler (1.5.4)
|
14
16
|
json (2.3.0)
|
15
17
|
parallel (1.19.1)
|
@@ -42,7 +44,7 @@ GEM
|
|
42
44
|
rubocop-performance (1.5.2)
|
43
45
|
rubocop (>= 0.71.0)
|
44
46
|
ruby-progressbar (1.10.1)
|
45
|
-
simplecov (0.
|
47
|
+
simplecov (0.16.1)
|
46
48
|
docile (~> 1.1)
|
47
49
|
json (>= 1.8, < 3)
|
48
50
|
simplecov-html (~> 0.10.0)
|
data/README.md
CHANGED
@@ -1,28 +1,105 @@
|
|
1
|
-
#
|
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
|
-
|
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.
|
4
4
|
|
5
|
-
TODO: Delete this and the text above, and describe your gem
|
6
5
|
|
7
|
-
##
|
6
|
+
## Requirements
|
8
7
|
|
9
|
-
|
8
|
+
* Docker (>= 19.03.8)
|
9
|
+
* Docker Compose (>= 1.25.5)
|
10
|
+
|
11
|
+
|
12
|
+
|
13
|
+
## Rails
|
14
|
+
|
15
|
+
Create a docker-compose.devup.yml with app dependencies like:
|
16
|
+
|
17
|
+
```yaml
|
18
|
+
version: "3"
|
19
|
+
|
20
|
+
services:
|
21
|
+
postgres:
|
22
|
+
image: postgres:10-alpine
|
23
|
+
ports:
|
24
|
+
- "5432"
|
25
|
+
```
|
26
|
+
|
27
|
+
Add **DevUp!** to your Gemfile
|
10
28
|
|
11
29
|
```ruby
|
12
|
-
gem
|
30
|
+
gem "devup", group: [:development, :test]
|
31
|
+
```
|
32
|
+
|
33
|
+
and
|
34
|
+
|
35
|
+
bundle install
|
36
|
+
|
37
|
+
|
38
|
+
Update your database.yml to use ENV:
|
39
|
+
|
40
|
+
```yaml
|
41
|
+
test:
|
42
|
+
url: <%= ENV.fetch("DATABASE_URL") %>
|
43
|
+
|
44
|
+
development:
|
45
|
+
url: <%= ENV.fetch("DATABASE_URL") %>
|
46
|
+
|
13
47
|
```
|
14
48
|
|
15
|
-
And then execute:
|
16
49
|
|
17
|
-
|
50
|
+
You are ready to use rails with PostgreSQL configured
|
51
|
+
|
52
|
+
$ bundle exec rake db:create db:migrate
|
53
|
+
Creating blog_postgres_1 ... done
|
54
|
+
Created database 'blog_development'
|
55
|
+
|
56
|
+
$ bundle exec rails server
|
57
|
+
|
58
|
+
|
59
|
+
## Without Rails
|
60
|
+
|
61
|
+
ENV vars from .env.services are loaded with dotenv automatically.
|
62
|
+
|
63
|
+
|
64
|
+
```ruby
|
65
|
+
require "devup"
|
66
|
+
require "sequel"
|
67
|
+
|
68
|
+
DB = Sequel.connect(ENV.fetch("DATABASE_URL"))
|
69
|
+
```
|
70
|
+
|
71
|
+
|
72
|
+
## Without Ruby (PHP, nodejs, Java, ...)
|
73
|
+
|
74
|
+
Start up services
|
75
|
+
|
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), ...)
|
90
|
+
|
91
|
+
Or load ENV vars manually
|
92
|
+
|
93
|
+
$ source .env.services
|
94
|
+
|
95
|
+
Now you can run app
|
18
96
|
|
19
|
-
|
97
|
+
## How To
|
20
98
|
|
21
|
-
|
99
|
+
### Disable **DevUp!**
|
22
100
|
|
23
|
-
|
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.
|
24
102
|
|
25
|
-
TODO: Write usage instructions here
|
26
103
|
|
27
104
|
## Development
|
28
105
|
|
data/devup.gemspec
CHANGED
data/exe/devup
CHANGED
data/lib/devup.rb
CHANGED
data/lib/devup/boot.rb
ADDED
@@ -0,0 +1,12 @@
|
|
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
|
@@ -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/dotenv.rb
ADDED
data/lib/devup/environment.rb
CHANGED
@@ -1,48 +1,47 @@
|
|
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
|
20
|
-
|
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
|
22
|
+
def env
|
23
|
+
services.map { |s| service_env(s) }.join("\n\n")
|
35
24
|
end
|
36
25
|
|
37
26
|
def up
|
27
|
+
logger.info "DevUp! is starting up services..."
|
28
|
+
check
|
38
29
|
compose.up
|
39
30
|
write_dotenv
|
31
|
+
logger.info "DevUp! is up"
|
32
|
+
rescue
|
33
|
+
clear_dotenv
|
34
|
+
logger.info "DevUp! halted"
|
40
35
|
end
|
41
36
|
|
42
37
|
def down
|
38
|
+
logger.info "DevUp! is shutting down services..."
|
43
39
|
compose.stop
|
44
40
|
compose.rm
|
45
41
|
clear_dotenv
|
42
|
+
logger.info "DevUp! is down"
|
43
|
+
rescue
|
44
|
+
logger.info "DevUp! halted"
|
46
45
|
end
|
47
46
|
|
48
47
|
def root
|
@@ -51,6 +50,32 @@ module Devup
|
|
51
50
|
|
52
51
|
private
|
53
52
|
|
53
|
+
def check
|
54
|
+
return false if missing_config
|
55
|
+
|
56
|
+
compose.check
|
57
|
+
|
58
|
+
true
|
59
|
+
end
|
60
|
+
|
61
|
+
def missing_config
|
62
|
+
if File.exist?(compose.path)
|
63
|
+
false
|
64
|
+
else
|
65
|
+
logger.error "missing #{compose.path}"
|
66
|
+
|
67
|
+
true
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def services
|
72
|
+
@services ||= compose.services.map { |name| Service.new(compose, name) }
|
73
|
+
end
|
74
|
+
|
75
|
+
def service_env(service)
|
76
|
+
ServicePresenter.new(service, project: project).call
|
77
|
+
end
|
78
|
+
|
54
79
|
def write_dotenv
|
55
80
|
File.open(root.join(".env.services"), "w") { |f| f.write dotenv }
|
56
81
|
end
|
@@ -61,11 +86,14 @@ module Devup
|
|
61
86
|
|
62
87
|
def dotenv
|
63
88
|
<<~DOTENV
|
64
|
-
|
65
|
-
#
|
66
|
-
|
89
|
+
####################################################
|
90
|
+
# This file is generated by devup command. #
|
91
|
+
# Home: https://github.com/sergio-fry/devup #
|
92
|
+
####################################################
|
67
93
|
# START
|
68
|
-
|
94
|
+
|
95
|
+
#{env}
|
96
|
+
|
69
97
|
# END
|
70
98
|
|
71
99
|
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,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: devup
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.2.1
|
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-
|
12
|
-
dependencies:
|
11
|
+
date: 2020-06-09 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: dotenv
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
13
27
|
description:
|
14
28
|
email:
|
15
29
|
- sergei@udalovs.ru
|
@@ -21,6 +35,7 @@ files:
|
|
21
35
|
- ".gitignore"
|
22
36
|
- ".rspec"
|
23
37
|
- ".ruby-version"
|
38
|
+
- ".standard.yml"
|
24
39
|
- ".travis.yml"
|
25
40
|
- ".vimrc"
|
26
41
|
- CODE_OF_CONDUCT.md
|
@@ -34,9 +49,13 @@ files:
|
|
34
49
|
- devup.gemspec
|
35
50
|
- exe/devup
|
36
51
|
- lib/devup.rb
|
52
|
+
- lib/devup/boot.rb
|
37
53
|
- lib/devup/compose.rb
|
54
|
+
- lib/devup/dotenv.rb
|
38
55
|
- lib/devup/environment.rb
|
56
|
+
- lib/devup/logger.rb
|
39
57
|
- lib/devup/service.rb
|
58
|
+
- lib/devup/service_presenter.rb
|
40
59
|
- lib/devup/version.rb
|
41
60
|
homepage: https://github.com/sergio-fry/devup
|
42
61
|
licenses:
|