djin 0.1.1 → 0.2.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: 9b1c6e4a65fd3d45dda2ccea34bafb2a33e927d59b25d273486152968629956d
4
- data.tar.gz: 7d5bac09875862642943dcf43bdfb61e9874203b6264c16aceeb918669fd4939
3
+ metadata.gz: 8941dba802fcd1d42ea6f6e52639928f8311b4f5379470a38082f3474985a3fb
4
+ data.tar.gz: 818fe3e599d48da784364fe96e8a9c413def53a4268adf44f3760d43235a2398
5
5
  SHA512:
6
- metadata.gz: 0ab09434fc83b94f14a2f2eed6bc23cbb1319a36083e9d110621e71b540953294e62eca5d59d7d4daa667066bd713d20595079c742aa8fe60d41d709e1f9323b
7
- data.tar.gz: 85628587736a959d29946c56ffea2e9379bd9184a0f6b9ad939967630d8a71b3004c276a203086bf3b510bfe11902c9c24d3ad279569044686af750a0ec17577
6
+ metadata.gz: 259f4f7a133336dd41286ecc43a0b7c4e91de62eb51fea4de258b7b934abd54bb7628e12707668b37acea748d32b3bea04c148a13e3c167669de45430b4ead23
7
+ data.tar.gz: 10f7bb94540315c5f72fc4fdddeb4bae8221c61d7e87dc3a346937bf354105ae6bc9d534f04d6347f44cab5f9862777a3a65ccf9340c5d1320ab2fb4c420a2b8
@@ -0,0 +1,20 @@
1
+ name: Ruby
2
+
3
+ on: [push]
4
+
5
+ jobs:
6
+ build:
7
+ runs-on: ubuntu-16.04
8
+ strategy:
9
+ matrix:
10
+ ruby: [ '2.4', '2.5', '2.6' ]
11
+ name: Ruby ${{ matrix.ruby }}
12
+ steps:
13
+ - uses: actions/checkout@v2
14
+ - uses: actions/setup-ruby@v1
15
+ with:
16
+ ruby-version: ${{ matrix.ruby }}
17
+ - run: |
18
+ gem install bundler
19
+ bundle install --jobs 4 --retry 3
20
+ bundle exec rake
data/Gemfile.lock CHANGED
@@ -1,10 +1,11 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- djin (0.1.1)
4
+ djin (0.2.0)
5
5
  dry-cli (~> 0.5.0)
6
6
  dry-struct (~> 1.3.0)
7
7
  dry-validation (~> 1.5.0)
8
+ vseries (~> 0.1.0)
8
9
 
9
10
  GEM
10
11
  remote: https://rubygems.org/
@@ -14,7 +15,7 @@ GEM
14
15
  diff-lcs (1.3)
15
16
  dry-cli (0.5.1)
16
17
  concurrent-ruby (~> 1.0)
17
- dry-configurable (0.11.3)
18
+ dry-configurable (0.11.5)
18
19
  concurrent-ruby (~> 1.0)
19
20
  dry-core (~> 0.4, >= 0.4.7)
20
21
  dry-equalizer (~> 0.2)
@@ -58,7 +59,7 @@ GEM
58
59
  dry-initializer (~> 3.0)
59
60
  dry-schema (~> 1.5)
60
61
  ice_nine (0.11.2)
61
- rake (10.5.0)
62
+ rake (13.0.1)
62
63
  rspec (3.9.0)
63
64
  rspec-core (~> 3.9.0)
64
65
  rspec-expectations (~> 3.9.0)
@@ -72,6 +73,7 @@ GEM
72
73
  diff-lcs (>= 1.2.0, < 2.0)
73
74
  rspec-support (~> 3.9.0)
74
75
  rspec-support (3.9.2)
76
+ vseries (0.1.0)
75
77
 
76
78
  PLATFORMS
77
79
  ruby
@@ -80,7 +82,7 @@ DEPENDENCIES
80
82
  bundler (~> 2.0)
81
83
  byebug
82
84
  djin!
83
- rake (~> 10.0)
85
+ rake (~> 13.0)
84
86
  rspec (~> 3.0)
85
87
 
86
88
  BUNDLED WITH
data/README.md CHANGED
@@ -1,16 +1,32 @@
1
1
  # Djin
2
2
 
3
+ ![](https://github.com/catks/djin/workflows/Ruby/badge.svg?branch=master)
4
+
5
+ Djin is a make-like utility for docker containers
6
+
3
7
  ## Installation
4
8
 
5
9
  Djin is distributed as a Ruby Gem, to install simple run:
6
10
 
7
11
  $ gem install djin
8
12
 
13
+ ### With Rbenv
14
+
15
+ If you use Rbenv you can install djin only once and create a alias in your .basrc, .zshrc, etc:
16
+
17
+ #### ZSH
18
+ $ RBENV_VERSION=$(rbenv global) gem install djin && echo "alias djin='RBENV_VERSION=$(rbenv global) djin'" >> ~/.zshrc
19
+
20
+ ### Bash
21
+ $ RBENV_VERSION=$(rbenv global) gem install djin && echo "alias djin='RBENV_VERSION=$(rbenv global) djin'" >> ~/.bashrc
22
+
9
23
  ## Usage
10
24
 
11
25
  To use djin first you need to create a djin.yml file:
12
26
 
13
27
  ```yaml
28
+ djin_version: '0.2.0'
29
+
14
30
  # With a docker image
15
31
  script:
16
32
  docker:
@@ -30,6 +46,36 @@ test:
30
46
 
31
47
  ```
32
48
 
49
+ You can also set task dependencies with depends_on option:
50
+
51
+
52
+ ```yaml
53
+ djin_version: '0.2.0'
54
+
55
+ _default_run_options: &default_run_options
56
+ options: "--rm"
57
+
58
+ "db:create":
59
+ docker-compose:
60
+ service: app
61
+ run:
62
+ commands: rake db:create
63
+ <<: *default_run_options
64
+
65
+ "db:migrate":
66
+ docker-compose:
67
+ service: app
68
+ run:
69
+ commands: rake db:migrate
70
+ <<: *default_run_options
71
+
72
+ "db:setup":
73
+ depends_on:
74
+ - "db:create"
75
+ - "db:migrate"
76
+
77
+ ```
78
+
33
79
  After that you can run `djin {{task_name}}`, like `djin script` or `djin test`
34
80
 
35
81
  ## Development
@@ -40,8 +86,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
40
86
 
41
87
  ## TODO:
42
88
 
43
- 1. Add `depends_on` to run dependent tasks
44
- 2. Adds a `-f` option to load custom djin files
89
+ 1. Adds a `-f` option to load custom djin files
45
90
 
46
91
  ## Contributing
47
92
 
data/djin.gemspec CHANGED
@@ -28,8 +28,9 @@ Gem::Specification.new do |spec|
28
28
  spec.add_dependency "dry-struct", "~> 1.3.0"
29
29
  spec.add_dependency "dry-cli", "~> 0.5.0"
30
30
  spec.add_dependency "dry-validation", "~> 1.5.0"
31
+ spec.add_dependency "vseries", "~> 0.1.0"
31
32
  spec.add_development_dependency "bundler", "~> 2.0"
32
- spec.add_development_dependency "rake", "~> 10.0"
33
+ spec.add_development_dependency "rake", "~> 13.0"
33
34
  spec.add_development_dependency "rspec", "~> 3.0"
34
35
  spec.add_development_dependency "byebug"
35
36
  end
data/djin.yml CHANGED
@@ -1,13 +1,18 @@
1
+ djin_version: '0.2.0'
2
+
3
+ _default_run_options: &default_run_options
4
+ options: "--rm --entrypoint=''"
5
+
1
6
  test:
2
7
  docker-compose:
3
8
  service: app
4
9
  run:
5
10
  commands: "cd /usr/src/djin && rspec"
6
- options: "--rm --entrypoint=''"
11
+ <<: *default_run_options
12
+
7
13
  sh:
8
14
  docker-compose:
9
15
  service: app
10
16
  run:
11
17
  commands: "sh"
12
- options: "--rm --entrypoint=''"
13
-
18
+ <<: *default_run_options
@@ -3,7 +3,8 @@ module Djin
3
3
  attribute :name, Types::String
4
4
  attribute :description, Types::String.optional.default(nil)
5
5
  attribute :build_command, Types::String.optional.default(nil)
6
- attribute :command, Types::String
6
+ attribute :command, Types::String.optional.default(nil)
7
+ attribute :depends_on, Types::Array.of(Types::String).optional.default([].freeze)
7
8
 
8
9
  def ==(other)
9
10
  name == other.name &&
data/lib/djin/executor.rb CHANGED
@@ -1,16 +1,28 @@
1
1
  module Djin
2
2
  class Executor
3
- def call(*tasks)
4
- tasks.each do |task|
5
- run task.build_command if task.build_command
6
- run task.command
7
- end
8
- end
3
+ def initialize(task_repository: Djin.task_repository)
4
+ @task_repository = task_repository
5
+ end
9
6
 
10
- private
7
+ def call(*tasks)
8
+ tasks.each do |task|
9
+ run_task(task)
10
+ end
11
+ end
11
12
 
12
- def run(command)
13
- system command
14
- end
13
+ private
14
+
15
+ def run_task(task)
16
+ @task_repository.find_by_names(task.depends_on).each do |dependent_task|
17
+ run_task dependent_task
18
+ end
19
+
20
+ run task.build_command if task.build_command
21
+ run task.command if task.command
22
+ end
23
+
24
+ def run(command)
25
+ system command
26
+ end
15
27
  end
16
28
  end
@@ -2,22 +2,37 @@ module Djin
2
2
  class Interpreter
3
3
  using Djin::HashExtensions
4
4
 
5
- RESERVED_WORDS = %w[_version _default_options].freeze
5
+ RESERVED_WORDS = %w[djin_version _default_options].freeze
6
6
 
7
- InvalidSyntax = Class.new(StandardError)
7
+ InvalidConfigurationError = Class.new(StandardError)
8
+ MissingVersionError = Class.new(InvalidConfigurationError)
9
+ VersionNotSupportedError = Class.new(InvalidConfigurationError)
10
+ InvalidSyntaxError = Class.new(InvalidConfigurationError)
8
11
 
9
12
  class << self
10
13
  def load!(params)
11
- task_params = params.except(*RESERVED_WORDS)
14
+ version = params['djin_version']
15
+ raise MissingVersionError, 'Missing djin_version' unless version
16
+ raise VersionNotSupportedError, "Version #{version} is not supported, use #{Djin::VERSION} or higher" unless version_supported?(version)
17
+
18
+ tasks_params = params.except(*RESERVED_WORDS).reject { |task| task.start_with?('_') }
12
19
  contract = TaskContract.new
13
20
 
14
- task_params.map do |task_name, options|
21
+ tasks_params.map do |task_name, options|
15
22
  result = contract.call(options)
16
23
 
17
- raise InvalidSyntax, result.errors.to_h if result.failure?
24
+ raise InvalidSyntaxError, result.errors.to_h if result.failure?
18
25
 
19
26
  command, build_command = build_commands(options, task_name: task_name)
20
- Djin::Task.new(name: task_name, build_command: build_command, command: command)
27
+
28
+ task_params = {
29
+ name: task_name,
30
+ build_command: build_command,
31
+ command: command,
32
+ depends_on: options['depends_on']
33
+ }.compact
34
+
35
+ Djin::Task.new(**task_params)
21
36
  end
22
37
  end
23
38
 
@@ -76,6 +91,14 @@ module Djin
76
91
 
77
92
  [run_command, run_options]
78
93
  end
94
+
95
+ def validate_version!(version)
96
+
97
+ end
98
+
99
+ def version_supported?(version)
100
+ Vseries::SemanticVersion.new(Djin::VERSION) >= Vseries::SemanticVersion.new(version)
101
+ end
79
102
  end
80
103
  end
81
104
  end
@@ -0,0 +1,17 @@
1
+ class TaskRepository
2
+ def initialize(tasks = [])
3
+ @tasks = tasks
4
+ end
5
+
6
+ def add(*tasks)
7
+ @tasks += tasks
8
+ end
9
+
10
+ def all
11
+ @tasks
12
+ end
13
+
14
+ def find_by_names(names)
15
+ @tasks.select { |task| names.include?(task.name) }
16
+ end
17
+ end
@@ -32,14 +32,16 @@ module Djin
32
32
  optional(:"docker-compose").filled do
33
33
  hash(DockerComposeSchema)
34
34
  end
35
+
36
+ optional(:depends_on).each(:str?)
35
37
  end
36
38
 
37
- rule(:docker, :"docker-compose") do
38
- key.failure('docker or docker-compose key is required') unless values[:docker] || values[:"docker-compose"]
39
+ rule(:docker, :"docker-compose", :depends_on) do
40
+ key.failure('docker, docker-compose or depends_on key is required') unless values[:docker] || values[:"docker-compose"] || values[:depends_on]
39
41
  end
40
42
 
41
- rule(:'docker-compose',docker: [:image, :build]) do
42
- key.failure('image or build param is required for docker tasks') unless values.dig(:docker, :image) || values.dig(:docker, :build) || values[:'docker-compose']
43
+ rule(:depends_on, :'docker-compose',docker: [:image, :build]) do
44
+ key.failure('image or build param is required for docker tasks') unless values.dig(:docker, :image) || values.dig(:docker, :build) || values[:'docker-compose'] || values[:depends_on]
43
45
  end
44
46
 
45
47
  rule(docker: :build) do
data/lib/djin/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Djin
2
- VERSION = "0.1.1"
2
+ VERSION = "0.2.0"
3
3
  end
data/lib/djin.rb CHANGED
@@ -3,6 +3,7 @@ require "pathname"
3
3
  require "yaml"
4
4
  require "dry-struct"
5
5
  require "dry-validation"
6
+ require "vseries"
6
7
  require "dry/cli"
7
8
  require "djin/extensions/hash_extensions"
8
9
  require "djin/extensions/custom_predicates"
@@ -12,6 +13,7 @@ require "djin/interpreter"
12
13
  require "djin/executor"
13
14
  require "djin/cli"
14
15
  require "djin/task_contract"
16
+ require "djin/repositories/task_repository"
15
17
 
16
18
  module Djin
17
19
  class Error < StandardError; end
@@ -20,17 +22,22 @@ module Djin
20
22
  def self.load_tasks!(path = Pathname.getwd.join('djin.yml'))
21
23
  abort 'Error: djin.yml not found' unless path.exist?
22
24
 
23
- djin_file = YAML.load(path.read)
24
- @tasks = Djin::Interpreter.load!(djin_file)
25
+ djin_file = YAML.safe_load(path.read, [], [], true)
26
+ tasks = Djin::Interpreter.load!(djin_file)
25
27
 
26
- CLI.load_tasks!(@tasks)
28
+ @task_repository = TaskRepository.new(tasks)
29
+ CLI.load_tasks!(tasks)
27
30
 
28
- rescue Djin::Interpreter::InvalidSyntax => ex
31
+ rescue Djin::Interpreter::InvalidConfigurationError => ex
29
32
  abort(ex.message)
30
33
  end
31
34
 
32
35
  def self.tasks
33
- @tasks || []
36
+ task_repository.all
37
+ end
38
+
39
+ def self.task_repository
40
+ @task_repository ||= TaskRepository.new
34
41
  end
35
42
  end
36
43
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: djin
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Carlos Atkinson
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-03-13 00:00:00.000000000 Z
11
+ date: 2020-03-31 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-struct
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: 1.5.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: vseries
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.1.0
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.1.0
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: bundler
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -72,14 +86,14 @@ dependencies:
72
86
  requirements:
73
87
  - - "~>"
74
88
  - !ruby/object:Gem::Version
75
- version: '10.0'
89
+ version: '13.0'
76
90
  type: :development
77
91
  prerelease: false
78
92
  version_requirements: !ruby/object:Gem::Requirement
79
93
  requirements:
80
94
  - - "~>"
81
95
  - !ruby/object:Gem::Version
82
- version: '10.0'
96
+ version: '13.0'
83
97
  - !ruby/object:Gem::Dependency
84
98
  name: rspec
85
99
  requirement: !ruby/object:Gem::Requirement
@@ -116,6 +130,7 @@ executables:
116
130
  extensions: []
117
131
  extra_rdoc_files: []
118
132
  files:
133
+ - ".github/workflows/ruby.yml"
119
134
  - ".gitignore"
120
135
  - ".rspec"
121
136
  - ".travis.yml"
@@ -140,6 +155,7 @@ files:
140
155
  - lib/djin/extensions/custom_predicates.rb
141
156
  - lib/djin/extensions/hash_extensions.rb
142
157
  - lib/djin/interpreter.rb
158
+ - lib/djin/repositories/task_repository.rb
143
159
  - lib/djin/task_contract.rb
144
160
  - lib/djin/version.rb
145
161
  homepage: https://github.com/catks/djin