djin 0.1.1 → 0.2.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: 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