diff --git a/.rubocop.yml b/.rubocop.yml index 7347891..069e181 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -2,6 +2,7 @@ AllCops: Exclude: - tmp/**/* + - vendor/**/* TargetRubyVersion: 2.5 Documentation: @@ -34,9 +35,21 @@ Security/MarshalLoad: Style/DoubleNegation: Enabled: false +Style/GuardClause: + Enabled: false + Style/StringLiterals: Enabled: false +Style/WordArray: + Enabled: false + +Naming/PredicateName: + Enabled: false + +Naming/MemoizedInstanceVariableName: + Enabled: false + Layout/DotPosition: EnforcedStyle: trailing diff --git a/.travis.yml b/.travis.yml index f6b4de9..0415650 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,4 +4,9 @@ language: ruby cache: bundler rvm: - 2.5.1 -before_install: gem install bundler -v 1.16.3 + +before_install: gem install bundler + +script: + - bundle exec rspec + - bundle exec rubocop diff --git a/Gemfile b/Gemfile index 3e1c203..b47d6b8 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,8 @@ +# frozen_string_literal: true + source "https://rubygems.org" -git_source(:github) {|repo_name| "https://github.com/#{repo_name}" } +git_source(:github) { |repo_name| "https://github.com/#{repo_name}" } # Specify your gem's dependencies in dip.gemspec gemspec diff --git a/Rakefile b/Rakefile index b7e9ed5..b6ae734 100644 --- a/Rakefile +++ b/Rakefile @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require "bundler/gem_tasks" require "rspec/core/rake_task" RSpec::Core::RakeTask.new(:spec) -task :default => :spec +task default: :spec diff --git a/bin/console b/bin/console index 5fd4ac4..2b3cc62 100755 --- a/bin/console +++ b/bin/console @@ -1,4 +1,5 @@ #!/usr/bin/env ruby +# frozen_string_literal: true require "bundler/setup" require "dip" diff --git a/dip.gemspec b/dip.gemspec index 4cfe346..03c954a 100644 --- a/dip.gemspec +++ b/dip.gemspec @@ -1,8 +1,10 @@ +# frozen_string_literal: true -lib = File.expand_path("../lib", __FILE__) +lib = File.expand_path("lib", __dir__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require "dip/version" +# rubocop:disable Metrics/BlockLength Gem::Specification.new do |spec| spec.name = "dip" spec.license = "MIT" @@ -11,8 +13,8 @@ Gem::Specification.new do |spec| spec.email = ["merkushin.m.s@gmail.com"] spec.summary = "Ruby gem CLI tool for better interacting docker-compose files." - spec.description = %q{DIP - docker-compose interaction process. - CLI tool for better development experience when interacting with docker-compose.} + spec.description = "DIP - Docker Interaction Process." \ + "CLI tool for better development experience when interacting with docker and docker-compose." spec.homepage = "https://github.com/bibendi/dip" # Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host' @@ -37,7 +39,8 @@ Gem::Specification.new do |spec| spec.add_development_dependency "pry-byebug", "~> 3" spec.add_development_dependency "rake", "~> 10.0" spec.add_development_dependency "rspec", "~> 3.0" - spec.add_development_dependency "rubocop", "~> 0.58" + spec.add_development_dependency "rubocop", "~> 0.59" spec.add_development_dependency "simplecov", '~> 0.16' spec.add_development_dependency "test-unit", "~> 3" end +# rubocop:enable Metrics/BlockLength diff --git a/exe/dip b/exe/dip index 8137781..7fbf4d6 100755 --- a/exe/dip +++ b/exe/dip @@ -2,7 +2,8 @@ # frozen_string_literal: true lib_path = File.expand_path('../lib', __dir__) -$:.unshift(lib_path) if !$:.include?(lib_path) +$LOAD_PATH.unshift(lib_path) unless $LOAD_PATH.include?(lib_path) + require 'dip' require 'dip/cli' require 'pry-byebug' if Dip.debug? @@ -18,7 +19,7 @@ begin ARGV.each do |arg| if !run_vars.frozen? && arg.include?("=") key, val = arg.split("=", 2) - run_vars << "#{"--x-dip-run-vars=" if run_vars.empty?}#{key}:#{val}" + run_vars << "#{'--x-dip-run-vars=' if run_vars.empty?}#{key}:#{val}" else run_vars.freeze end diff --git a/lib/dip/cli.rb b/lib/dip/cli.rb index 92bf30a..050f522 100644 --- a/lib/dip/cli.rb +++ b/lib/dip/cli.rb @@ -7,7 +7,7 @@ class CLI < Thor class << self def retrieve_command_name(args) meth = args.first.to_sym unless args.empty? - args.unshift("run") if ::Dip.config.interaction.key?(meth.to_sym) if meth + args.unshift("run") if meth && ::Dip.config.interaction.key?(meth.to_sym) super(args) end @@ -15,6 +15,7 @@ def retrieve_command_name(args) # Hackery. Take the run method away from Thor so that we can redefine it. def is_thor_reserved_word?(word, type) return false if word == "run" + super end end @@ -22,7 +23,7 @@ def is_thor_reserved_word?(word, type) desc 'version', 'dip version' def version require_relative 'version' - puts "#{Dip::VERSION}" + puts Dip::VERSION end map %w(--version -v) => :version @@ -41,7 +42,8 @@ def compose(cmd, *argv) desc 'CMD or dip run CMD [OPTIONS]', 'Run configured command in a docker-compose service' method_option :help, aliases: '-h', type: :boolean, desc: 'Display usage information' - method_option :x_dip_run_vars, type: :hash, + method_option :x_dip_run_vars, + type: :hash, desc: "Enforce environment variables into container, recommended run like 'dip FOO=bar cmd'" def run(cmd, subcmd = nil, *argv) if options[:help] diff --git a/lib/dip/cli/dns.rb b/lib/dip/cli/dns.rb index b798705..63b282d 100644 --- a/lib/dip/cli/dns.rb +++ b/lib/dip/cli/dns.rb @@ -22,6 +22,7 @@ class DNS < Thor desc: 'Docker image name' method_option :domain, aliases: '-d', type: :string, default: "docker", desc: 'Top level domain' + # rubocop:disable Metrics/AbcSize, Metrics/MethodLength def up if options[:help] invoke :help, ['up'] @@ -36,6 +37,7 @@ def up ).execute end end + # rubocop:enable Metrics/AbcSize, Metrics/MethodLength desc "dns down", "Stop dnsdock container" method_option :help, aliases: '-h', type: :boolean, diff --git a/lib/dip/cli/nginx.rb b/lib/dip/cli/nginx.rb index 0dfea42..727c164 100644 --- a/lib/dip/cli/nginx.rb +++ b/lib/dip/cli/nginx.rb @@ -22,6 +22,7 @@ class Nginx < Thor desc: 'Docker image name' method_option :domain, aliases: '-d', type: :string, default: "docker", desc: 'Top level domain' + # rubocop:disable Metrics/AbcSize, Metrics/MethodLength def up if options[:help] invoke :help, ['up'] @@ -36,6 +37,7 @@ def up ).execute end end + # rubocop:enable Metrics/AbcSize, Metrics/MethodLength desc "nginx down", "Stop nginx container" method_option :help, aliases: '-h', type: :boolean, diff --git a/lib/dip/cli/ssh.rb b/lib/dip/cli/ssh.rb index 6cdc15f..e8f3256 100644 --- a/lib/dip/cli/ssh.rb +++ b/lib/dip/cli/ssh.rb @@ -22,9 +22,10 @@ def up if options[:help] invoke :help, ['up'] else - Dip::Commands::SSH::Up.new(key: options.fetch(:key), - volume: options.fetch(:volume), - interactive: options.nonteractive? ? false : options.interactive? + Dip::Commands::SSH::Up.new( + key: options.fetch(:key), + volume: options.fetch(:volume), + interactive: options.nonteractive? ? false : options.interactive? ).execute end end diff --git a/lib/dip/command.rb b/lib/dip/command.rb index 4b51637..a4ae09a 100644 --- a/lib/dip/command.rb +++ b/lib/dip/command.rb @@ -6,8 +6,7 @@ module Dip class Command extend Forwardable - def_delegators self, :shell, - :subshell + def_delegators self, :shell, :subshell class ExecRunner def self.call(cmd, argv, env: {}, **options) @@ -16,21 +15,21 @@ def self.call(cmd, argv, env: {}, **options) end class SubshellRunner - def self.call(cmd, argv, env: {}, **options) - ::Kernel.system(env, cmd, *argv, options) + def self.call(cmd, argv, env: {}, panic: true, **options) + return if ::Kernel.system(env, cmd, *argv, options) + raise Dip::Error, "Command '#{([cmd] + argv).join(' ')}' executed with error." if panic end end class << self - def shell(cmd, argv = [], subshell: false, panic: true, **options) + def shell(cmd, argv = [], subshell: false, **options) cmd = Dip.env.interpolate(cmd) argv = argv.map { |arg| Dip.env.interpolate(arg) } puts [Dip.env.vars, cmd, argv].inspect if Dip.debug? runner = subshell ? SubshellRunner : ExecRunner - return if runner.call(cmd, argv, env: Dip.env.vars, **options) - raise Dip::Error, "Command '#{([cmd] + argv).join(' ')}' executed with error." if panic + runner.call(cmd, argv, env: Dip.env.vars, **options) end def subshell(*args, **kwargs) diff --git a/lib/dip/commands/compose.rb b/lib/dip/commands/compose.rb index 5c2561d..cbf96f3 100644 --- a/lib/dip/commands/compose.rb +++ b/lib/dip/commands/compose.rb @@ -30,9 +30,10 @@ def find_files return unless (files = @config[:files]) if files.is_a?(Array) - result = files.each_with_object([]) do |file_name, memo| + files.each_with_object([]) do |file_name, memo| file_name = ::Dip.env.interpolate(file_name) next unless File.exist?(file_name) + memo << "--file" memo << file_name end diff --git a/lib/dip/commands/dns.rb b/lib/dip/commands/dns.rb index 954a08a..f25b48e 100644 --- a/lib/dip/commands/dns.rb +++ b/lib/dip/commands/dns.rb @@ -52,10 +52,11 @@ def initialize(name:, net:) end def execute(**options) - subshell("docker", "inspect " \ - "--format '{{ .NetworkSettings.Networks.#{@net}.IPAddress }}' " \ - "#{@name}".shellsplit, - **options) + subshell("docker", + "inspect " \ + "--format '{{ .NetworkSettings.Networks.#{@net}.IPAddress }}' " \ + "#{@name}".shellsplit, + **options) end end end diff --git a/lib/dip/commands/run.rb b/lib/dip/commands/run.rb index 01c418c..03bf536 100644 --- a/lib/dip/commands/run.rb +++ b/lib/dip/commands/run.rb @@ -15,6 +15,8 @@ def initialize(cmd, subcmd = nil, argv = [], run_vars: nil) @config = ::Dip.config.interaction end + # TODO: Refactor + # rubocop:disable Metrics/AbcSize, Metrics/MethodLength def execute command = @config.fetch(@cmd) command[:subcommands] ||= {} @@ -22,8 +24,8 @@ def execute if (subcommand = command[:subcommands].fetch(@subcmd, {})).any? subcommand[:command] ||= nil command.merge!(subcommand) - else - @argv.unshift(@subcmd.to_s) if @subcmd + elsif @subcmd + @argv.unshift(@subcmd.to_s) end Dip.env.merge(command[:environment]) if command[:environment] @@ -40,6 +42,7 @@ def execute Dip::Commands::Compose.new(compose_method, compose_argv).execute end + # rubocop:enable Metrics/AbcSize, Metrics/MethodLength def prepare_compose_run_options(value) return [] unless value diff --git a/lib/dip/config.rb b/lib/dip/config.rb index 2253dbb..44c367d 100644 --- a/lib/dip/config.rb +++ b/lib/dip/config.rb @@ -5,8 +5,6 @@ module Dip class Config - DEFAULT_CONFIG = {} - def initialize(config_path) load_or_default(config_path) end @@ -41,7 +39,7 @@ def load_or_default(config_path) symbolize_names: true ) else - DEFAULT_CONFIG + {} end end end diff --git a/lib/dip/version.rb b/lib/dip/version.rb index 4efef35..402d54e 100644 --- a/lib/dip/version.rb +++ b/lib/dip/version.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + module Dip VERSION = "3.0.0" end diff --git a/spec/lib/commands/dns_spec.rb b/spec/lib/commands/dns_spec.rb index 667a1f4..804f365 100644 --- a/spec/lib/commands/dns_spec.rb +++ b/spec/lib/commands/dns_spec.rb @@ -70,7 +70,9 @@ describe Dip::Commands::DNS::IP do context "when without arguments" do before { cli.start "ip".shellsplit } - it { expected_subshell("docker", array_including("inspect", "--format", /Networks.frontend.IPAddress/, "dnsdock")) } + it do + expected_subshell("docker", array_including("inspect", "--format", /Networks.frontend.IPAddress/, "dnsdock")) + end end context "when option `name` is present" do diff --git a/spec/lib/commands/run_spec.rb b/spec/lib/commands/run_spec.rb index 3f390c3..5ea7ea9 100644 --- a/spec/lib/commands/run_spec.rb +++ b/spec/lib/commands/run_spec.rb @@ -92,9 +92,9 @@ before { cli.start "run rails refresh-test-db".shellsplit } it do - expected_exec("docker-compose", ["run", "--rm", "app", - "rake", "db:drop", "db:tests:prepare", "db:migrate"], - env: hash_including("RAILS_ENV" => "test")) + expected_exec("docker-compose", + ["run", "--rm", "app", "rake", "db:drop", "db:tests:prepare", "db:migrate"], + env: hash_including("RAILS_ENV" => "test")) end end end diff --git a/spec/lib/commands/ssh_spec.rb b/spec/lib/commands/ssh_spec.rb index 8226099..b566e4e 100644 --- a/spec/lib/commands/ssh_spec.rb +++ b/spec/lib/commands/ssh_spec.rb @@ -15,8 +15,11 @@ it { expected_subshell("docker", array_including("volume", "create")) } it { expected_subshell("docker", array_including("run", "--name=ssh-agent", "whilp/ssh-agent")) } - it { expected_subshell("docker", array_including("run", "--volume", "/user:/user", "--interactive", "--tty", - "whilp/ssh-agent", "ssh-add", "/user/.ssh/id_rsa")) } + it do + expected_subshell("docker", + array_including("run", "--volume", "/user:/user", "--interactive", "--tty", + "whilp/ssh-agent", "ssh-add", "/user/.ssh/id_rsa")) + end end context "when option `key` is present" do diff --git a/spec/lib/dip_spec.rb b/spec/lib/dip_spec.rb index dc8ed8f..bfd1a59 100644 --- a/spec/lib/dip_spec.rb +++ b/spec/lib/dip_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + describe Dip do it "has a version number" do expect(Dip::VERSION).not_to be nil diff --git a/spec/lib/environment_spec.rb b/spec/lib/environment_spec.rb index f471931..18a8f2c 100644 --- a/spec/lib/environment_spec.rb +++ b/spec/lib/environment_spec.rb @@ -6,7 +6,6 @@ let(:vars) { {} } subject { described_class.new(vars) } - context "when vars is empty" do it { is_expected.to be_truthy } end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 11830e2..c212686 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require "bundler/setup" ENV["DIP_ENV"] = "test" diff --git a/spec/support/shared_contexts/config.rb b/spec/support/shared_contexts/config.rb index 005c758..b7e3ee4 100644 --- a/spec/support/shared_contexts/config.rb +++ b/spec/support/shared_contexts/config.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + shared_context "dip config", config: true do before do Dip.config.merge(config) diff --git a/spec/support/shared_contexts/environment.rb b/spec/support/shared_contexts/environment.rb index fa6b1a6..40655c8 100644 --- a/spec/support/shared_contexts/environment.rb +++ b/spec/support/shared_contexts/environment.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + shared_context "replace environment vars", env: true do around(:each) do |ex| original = {} diff --git a/spec/support/shared_contexts/runner.rb b/spec/support/shared_contexts/runner.rb index baa79d9..616090a 100644 --- a/spec/support/shared_contexts/runner.rb +++ b/spec/support/shared_contexts/runner.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + shared_context "dip command", runner: true do let(:exec_runner) { spy("exec runner") } let(:subshell_runner) { spy("subshell runner") } @@ -8,7 +10,6 @@ end end - def expected_exec(cmd, argv, options = kind_of(Hash)) argv = Array(argv) if argv.is_a?(String) expect(exec_runner).to have_received(:call).with(cmd, argv, options)