Skip to content

Commit

Permalink
tests: cover setup generator
Browse files Browse the repository at this point in the history
  • Loading branch information
bibendi committed Nov 5, 2019
1 parent 2362083 commit 8712842
Show file tree
Hide file tree
Showing 11 changed files with 305 additions and 147 deletions.
8 changes: 3 additions & 5 deletions .dockerdev/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
version: '3.4'
version: '2.4'

services:
app:
image: ruby:2.6
environment:
- GEM_HOME=/bundle
- BUNDLE_PATH=/bundle
- HISTFILE=/app/tmp/.bash_history
working_dir: /app
volumes:
- ..:/app
- bundle:/bundle
- gems:/usr/local/bundle

volumes:
bundle:
gems:
4 changes: 4 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ Metrics/BlockLength:
- 'anycable-rails.gemspec'
- 'lib/rails/generators/**/*.rb'

Metrics/ClassLength:
Exclude:
- 'lib/rails/generators/**/*.rb'

Metrics/CyclomaticComplexity:
Exclude:
- 'spec/**/*.rb'
Expand Down
1 change: 1 addition & 0 deletions anycable-rails.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Gem::Specification.new do |spec|
spec.add_dependency "anycable", "~> 0.6.0"
spec.add_dependency "rails", ">= 5"

spec.add_development_dependency "ammeter", "~> 1.1"
spec.add_development_dependency "bundler", ">= 1.10"
spec.add_development_dependency "pry-byebug"
spec.add_development_dependency "rake", "~> 10.0"
Expand Down
36 changes: 0 additions & 36 deletions lib/rails/generators/anycable/setup/docker/docker_generator.rb

This file was deleted.

96 changes: 0 additions & 96 deletions lib/rails/generators/anycable/setup/local/local_generator.rb

This file was deleted.

188 changes: 178 additions & 10 deletions lib/rails/generators/anycable/setup/setup_generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,35 @@ class SetupGenerator < ::Rails::Generators::Base
namespace "anycable:setup"
source_root File.expand_path("templates", __dir__)

METHODS = %w[skip local docker].freeze
SERVER_VERSION = "v0.6.4"
OS_NAMES = %w[linux darwin freebsd win].freeze
CPU_NAMES = %w[amd64 arm64 386 arm].freeze
SERVER_SOURCES = %w[skip brew binary].freeze
DEFAULT_BIN_PATH = "/usr/local/bin"

class_option :method,
type: :string,
desc: "Select your development environment to run particular installation method (options: #{METHODS.join(', ')})"
class_option :source,
type: :string,
desc: "Install AnyCable-Go server from particular source (options: #{SERVER_SOURCES.join(', ')})"
class_option :bin_path,
type: :string,
desc: "Install AnyCable-Go server binary to directory (default: #{DEFAULT_BIN_PATH})"
class_option :os,
type: :string,
desc: "Download AnyCable-Go server binary for particular OS (options: #{OS_NAMES.join(', ')})"
class_option :cpu,
type: :string,
desc: "Download AnyCable-Go server binary for particular CPU architecture (options: #{CPU_NAMES.join(', ')})"
class_option :skip_heroku,
type: :boolean,
desc: "Do not copy Heroku configs"
class_option :skip_procfile_dev,
type: :boolean,
desc: "Do not create Procfile.dev"

def welcome
say "👋 Welcome to AnyCable interactive installer."
end
Expand Down Expand Up @@ -37,22 +66,26 @@ def cable_url
end

def development_method
answer = nil
answer = METHODS.index(options[:method]) || 99

until [1, 2, 3].include?(answer.to_i)
answer = ask "Which environment do you use for development? (1) Local, (2) Docker, (3) Skip"
until METHODS[answer.to_i]
answer = ask "Which environment do you use for development? (1) Local, (2) Docker, (0) Skip"
end

env = [nil, "local", "docker"][answer.to_i]

return if env.nil?

require "rails/generators/anycable/setup/#{env.underscore}/#{env.underscore}_generator"
"AnyCableRailsGenerators::Setup::#{env.camelize}Generator".constantize.new.invoke_all
case env = METHODS[answer.to_i]
when "skip"
say_status :help, "⚠️ Please, read this guide on how to install AnyCable-Go server 👉 https://docs.anycable.io/#/anycable-go/getting_started", :yellow
else
send "install_for_#{env}"
end
end

def heroku
return unless yes? "Do you use Heroku for deployment?"
if options[:skip_heroku].nil?
return unless yes? "Do you use Heroku for deployment?"
elsif options[:skip_heroku]
return
end

template "Procfile"
inside("bin") { template "heroku-web" }
Expand All @@ -63,5 +96,140 @@ def heroku
def finish
say_status :info, "✅ AnyCable has been configured successfully!"
end

private

def install_for_docker
say_status :help, "️️⚠️ Docker development configuration could vary", :yellow

say "Here is an example snippet for docker-compose.yml:"
say <<~YML
─────────────────────────────────────────
anycable-ws:
image: anycable/anycable-go:v0.6.4
ports:
- '3334:3334'
environment:
PORT: 3334
REDIS_URL: redis://redis:6379/0
ANYCABLE_RPC_HOST: anycable-rpc:50051
depends_on:
- anycable-rpc
- redis
anycable-rpc:
<<: *backend
command: bundle exec anycable
ports:
- '50051'
─────────────────────────────────────────
YML
end

def install_for_local
install_server
template_proc_files
end

def install_server
answer = SERVER_SOURCES.index(options[:source]) || 99

until SERVER_SOURCES[answer.to_i]
answer = ask "How do you want to install AnyCable-Go WebSocket server? (1) Homebrew, (2) Download binary, (0) Skip"
end

case answer.to_i
when 0
say_status :help, "⚠️ Please, read this guide on how to install AnyCable-Go server 👉 https://docs.anycable.io/#/anycable-go/getting_started", :yellow
return
else
return unless send("install_from_#{SERVER_SOURCES[answer.to_i]}")
end

say_status :info, "✅ AnyCable-Go WebSocket server has been successfully installed"
end

def template_proc_files
file_name = "Procfile.dev"

if File.exist?(file_name)
append_file file_name, 'anycable: bundle exec anycable --server-command "anycable-go --port 3334"'
else
say_status :help, "💡 We recommend using Hivemind to manage multiple processes in development 👉 https://github.com/DarthSim/hivemind", :yellow

if options[:skip_procfile_dev].nil?
return unless yes? "Do you want to create a '#{file_name}' file?"
elsif options[:skip_procfile_dev]
return
end

template file_name
end
end

def install_from_brew
run "brew install anycable-go", abort_on_failure: true
run "anycable-go -v", abort_on_failure: true
end

def install_from_binary
out = options[:bin_path] if options[:bin_path]
out ||= "/usr/local/bin" if options[:method] # User don't want interactive mode
out ||= ask "Please, enter the path to download the AnyCable-Go binary to", default: DEFAULT_BIN_PATH, path: true

os_name = OS_NAMES.find(&Gem::Platform.local.os.method(:==)) ||
options[:os] ||
ask("What is your OS name?", limited_to: OS_NAMES)

cpu_name = CPU_NAMES.find(&current_cpu.method(:==)) ||
options[:cpu] ||
ask("What is your CPU architecture?", limited_to: CPU_NAMES)

download_exe(
"https://github.com/anycable/anycable-go/releases/download/#{SERVER_VERSION}/" \
"anycable-go-#{SERVER_VERSION}-#{os_name}-#{cpu_name}",
to: out,
file_name: "anycable-go"
)

true
end

def download_exe(url, to:, file_name:)
file_path = File.join(to, file_name)

run "#{sudo(to)}curl -L #{url} -o #{file_path}", abort_on_failure: true
run "#{sudo(to)}chmod +x #{file_path}", abort_on_failure: true
run "#{file_path} -v", abort_on_failure: true
end

def sudo!(path)
sudo = ""
unless File.writable?(path)
if yes? "Path is not writable 😕. Do you have sudo privileges?"
sudo = "sudo "
else
say_status :error, "❌ Failed to install AnyCable-Go WebSocket server", :red
raise StandardError, "Path #{path} is not writable!"
end
end

sudo
end

def current_cpu
case Gem::Platform.local.cpu
when "x86_64", "x64"
"amd64"
when "x86_32", "x86", "i386", "i486", "i686"
"i386"
when "aarch64", "aarch64_be", /armv8/
"arm64"
when "arm", /armv7/, /armv6/
"arm"
else
"unknown"
end
end
end
end
3 changes: 3 additions & 0 deletions spec/fixtures/basic_rails_app/Procfile.dev
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
server: bin/rails server
assets: bin/webpack-dev-server
anycable: bundle exec anycable --server-command "anycable-go --port 3334"
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# frozen_string_literal: true

Rails.application.configure do
config.cache_classes = false

# Do not eager load code on boot.
config.eager_load = false
end
Loading

0 comments on commit 8712842

Please sign in to comment.