meepo 1.5.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +1 -0
  3. data/.gitignore +16 -0
  4. data/.rspec +2 -0
  5. data/.rubocop.yml +29 -0
  6. data/.travis.yml +10 -0
  7. data/Dockerfile +7 -0
  8. data/Gemfile +13 -0
  9. data/MIT-LICENSE +20 -0
  10. data/Rakefile +15 -0
  11. data/TODO +5 -0
  12. data/bin/invoker +7 -0
  13. data/contrib/completion/invoker-completion.bash +70 -0
  14. data/contrib/completion/invoker-completion.zsh +62 -0
  15. data/examples/hello_sinatra.rb +26 -0
  16. data/examples/sample.ini +3 -0
  17. data/invoker.gemspec +43 -0
  18. data/lib/invoker.rb +152 -0
  19. data/lib/invoker/cli.rb +159 -0
  20. data/lib/invoker/cli/pinger.rb +23 -0
  21. data/lib/invoker/cli/question.rb +15 -0
  22. data/lib/invoker/cli/tail.rb +34 -0
  23. data/lib/invoker/cli/tail_watcher.rb +34 -0
  24. data/lib/invoker/command_worker.rb +60 -0
  25. data/lib/invoker/commander.rb +95 -0
  26. data/lib/invoker/daemon.rb +126 -0
  27. data/lib/invoker/dns_cache.rb +23 -0
  28. data/lib/invoker/errors.rb +17 -0
  29. data/lib/invoker/event/manager.rb +79 -0
  30. data/lib/invoker/ipc.rb +45 -0
  31. data/lib/invoker/ipc/add_command.rb +12 -0
  32. data/lib/invoker/ipc/add_http_command.rb +10 -0
  33. data/lib/invoker/ipc/base_command.rb +24 -0
  34. data/lib/invoker/ipc/client_handler.rb +26 -0
  35. data/lib/invoker/ipc/dns_check_command.rb +17 -0
  36. data/lib/invoker/ipc/list_command.rb +11 -0
  37. data/lib/invoker/ipc/message.rb +170 -0
  38. data/lib/invoker/ipc/message/list_response.rb +35 -0
  39. data/lib/invoker/ipc/message/tail_response.rb +10 -0
  40. data/lib/invoker/ipc/ping_command.rb +10 -0
  41. data/lib/invoker/ipc/reload_command.rb +12 -0
  42. data/lib/invoker/ipc/remove_command.rb +12 -0
  43. data/lib/invoker/ipc/server.rb +26 -0
  44. data/lib/invoker/ipc/tail_command.rb +11 -0
  45. data/lib/invoker/ipc/unix_client.rb +60 -0
  46. data/lib/invoker/logger.rb +13 -0
  47. data/lib/invoker/parsers/config.rb +184 -0
  48. data/lib/invoker/parsers/procfile.rb +86 -0
  49. data/lib/invoker/power/balancer.rb +131 -0
  50. data/lib/invoker/power/config.rb +77 -0
  51. data/lib/invoker/power/dns.rb +38 -0
  52. data/lib/invoker/power/http_parser.rb +68 -0
  53. data/lib/invoker/power/http_response.rb +81 -0
  54. data/lib/invoker/power/pf_migrate.rb +64 -0
  55. data/lib/invoker/power/port_finder.rb +49 -0
  56. data/lib/invoker/power/power.rb +3 -0
  57. data/lib/invoker/power/powerup.rb +29 -0
  58. data/lib/invoker/power/setup.rb +90 -0
  59. data/lib/invoker/power/setup/distro/arch.rb +15 -0
  60. data/lib/invoker/power/setup/distro/base.rb +57 -0
  61. data/lib/invoker/power/setup/distro/debian.rb +11 -0
  62. data/lib/invoker/power/setup/distro/mint.rb +10 -0
  63. data/lib/invoker/power/setup/distro/opensuse.rb +11 -0
  64. data/lib/invoker/power/setup/distro/redhat.rb +11 -0
  65. data/lib/invoker/power/setup/distro/ubuntu.rb +10 -0
  66. data/lib/invoker/power/setup/files/invoker_forwarder.sh.erb +17 -0
  67. data/lib/invoker/power/setup/files/socat_invoker.service +12 -0
  68. data/lib/invoker/power/setup/linux_setup.rb +105 -0
  69. data/lib/invoker/power/setup/osx_setup.rb +137 -0
  70. data/lib/invoker/power/templates/400.html +40 -0
  71. data/lib/invoker/power/templates/404.html +40 -0
  72. data/lib/invoker/power/templates/503.html +40 -0
  73. data/lib/invoker/power/url_rewriter.rb +40 -0
  74. data/lib/invoker/process_manager.rb +198 -0
  75. data/lib/invoker/process_printer.rb +43 -0
  76. data/lib/invoker/reactor.rb +37 -0
  77. data/lib/invoker/reactor/reader.rb +54 -0
  78. data/lib/invoker/version.rb +47 -0
  79. data/readme.md +25 -0
  80. data/spec/invoker/cli/pinger_spec.rb +22 -0
  81. data/spec/invoker/cli/tail_watcher_spec.rb +39 -0
  82. data/spec/invoker/cli_spec.rb +27 -0
  83. data/spec/invoker/command_worker_spec.rb +45 -0
  84. data/spec/invoker/commander_spec.rb +152 -0
  85. data/spec/invoker/config_spec.rb +361 -0
  86. data/spec/invoker/daemon_spec.rb +34 -0
  87. data/spec/invoker/event/manager_spec.rb +67 -0
  88. data/spec/invoker/invoker_spec.rb +71 -0
  89. data/spec/invoker/ipc/client_handler_spec.rb +54 -0
  90. data/spec/invoker/ipc/dns_check_command_spec.rb +32 -0
  91. data/spec/invoker/ipc/message/list_response_spec.rb +24 -0
  92. data/spec/invoker/ipc/message_spec.rb +49 -0
  93. data/spec/invoker/ipc/unix_client_spec.rb +29 -0
  94. data/spec/invoker/power/balancer_spec.rb +22 -0
  95. data/spec/invoker/power/config_spec.rb +18 -0
  96. data/spec/invoker/power/http_parser_spec.rb +32 -0
  97. data/spec/invoker/power/http_response_spec.rb +34 -0
  98. data/spec/invoker/power/pf_migrate_spec.rb +87 -0
  99. data/spec/invoker/power/port_finder_spec.rb +16 -0
  100. data/spec/invoker/power/setup/linux_setup_spec.rb +103 -0
  101. data/spec/invoker/power/setup/osx_setup_spec.rb +105 -0
  102. data/spec/invoker/power/setup_spec.rb +4 -0
  103. data/spec/invoker/power/url_rewriter_spec.rb +70 -0
  104. data/spec/invoker/power/web_sockets_spec.rb +61 -0
  105. data/spec/invoker/process_manager_spec.rb +130 -0
  106. data/spec/invoker/reactor_spec.rb +6 -0
  107. data/spec/spec_helper.rb +43 -0
  108. metadata +389 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 8e35faa500696cc5542b9dc9c6fca84001c6a13f
4
+ data.tar.gz: 23ba208f8530500e940b3e5347e0a96fca110ed0
5
+ SHA512:
6
+ metadata.gz: 34a76856707b1f0c815eb036b1d3e06fabf5690c33340ea8bd4763ec99d32ea8e8f5da56383b3e1c3113428e1b39f8f081e6043f29e0ea2fa2552f6727d85f20
7
+ data.tar.gz: 879537d558df60ac59ac1a5780940cd57d7515cc78249e09f3eccb449a8f0adec718642f83381403384f03722093eb15af830fd3ad2a8da3af1284b68a2c3d93
@@ -0,0 +1 @@
1
+ service_name: travis-ci
@@ -0,0 +1,16 @@
1
+ invoker.ini
2
+ config/
3
+ *.gem
4
+ pkg/
5
+ tags
6
+ .rvmrc
7
+ vendor/
8
+ _site
9
+ .bundle
10
+ coverage
11
+ invoker_profile/
12
+ *.pid
13
+ .ruby-version
14
+ Gemfile.lock
15
+ .overcommit.yml
16
+ Procfile
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
@@ -0,0 +1,29 @@
1
+ AllCops:
2
+ Excludes:
3
+ - db/**
4
+
5
+ HashSyntax:
6
+ Description: 'Use either hash rocket or 1.9 styled hashes.'
7
+ Enabled: false
8
+
9
+ LineLength:
10
+ Max: 100
11
+
12
+ # Disable Certain Tests
13
+
14
+ Documentation:
15
+ Description: 'Document classes and non-namespace modules.'
16
+ Enabled: false
17
+
18
+ StringLiterals:
19
+ Description: 'Checks if uses of quotes match the configured preference.'
20
+ Enabled: false
21
+
22
+ Encoding:
23
+ Description: 'Use UTF-8 as the source file encoding.'
24
+ Enabled: false
25
+
26
+ SignalException:
27
+ Description: 'Do not enforce use of fail when raising exceptions.'
28
+ # Valid values are: semantic, only_raise and only_fail
29
+ EnforcedStyle: only_raise
@@ -0,0 +1,10 @@
1
+ language: ruby
2
+ cache: bundler
3
+ sudo: false
4
+ rvm:
5
+ - 2.0.0
6
+ - 2.1.0
7
+ - 2.2.0
8
+ - 2.3.0
9
+
10
+ script: bundle exec rake spec
@@ -0,0 +1,7 @@
1
+ FROM ruby:2.3
2
+
3
+ MAINTAINER hemant@codemancers.com
4
+
5
+ RUN apt-get update && apt-get -y install dnsmasq socat
6
+
7
+ CMD cd /invoker && bundle install --path vendor/ && bundle exec rake spec
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ gem 'websocket-eventmachine-server', require: false
6
+ gem 'websocket-eventmachine-client', require: false
7
+
8
+ group :development do
9
+ gem 'pry'
10
+ gem 'tins', '~>1.4.0'
11
+ gem 'coveralls', require: false
12
+ gem "simplecov", require: false
13
+ end
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2013-2014 Hemant Kumar
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,15 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new
5
+
6
+ task :default => :spec
7
+ task :test => :spec
8
+
9
+ current_directory = File.expand_path(File.dirname(__FILE__))
10
+
11
+ desc "run specs inside docker"
12
+ task :docker_spec do
13
+ system("docker build -t invoker-ruby . ")
14
+ system("docker run --name invoker-rspec --rm -v #{current_directory}:/invoker -t invoker-ruby")
15
+ end
data/TODO ADDED
@@ -0,0 +1,5 @@
1
+ Todos for current release
2
+
3
+ * Implement port support via config file
4
+ * Fix setup command and make it eaiser for people who have pow configured.
5
+ * Possibly add support for foreman?
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ invoker_lib_path = File.expand_path('../../lib', __FILE__)
4
+ $:.unshift(invoker_lib_path)
5
+ require "invoker"
6
+
7
+ Invoker::CLI.start(ARGV)
@@ -0,0 +1,70 @@
1
+ # BASH completion function for Invoker
2
+
3
+ # source it from bashrc
4
+ # dependencies:
5
+ # 1) netcat
6
+ # 2) find
7
+
8
+ check_open_port()
9
+ {
10
+ local port=$1
11
+ if [[ $(which nc) ]]; then
12
+ local open=$(nc -z -w2 localhost $port > /dev/null; echo $?)
13
+ if [[ "$open" == "1" ]]; then
14
+ COMPREPLY=( $(compgen -W "${port}" -- ${cur}) )
15
+ else
16
+ check_open_port $(($port+1))
17
+ fi
18
+ fi
19
+ }
20
+ _invoker()
21
+ {
22
+ local cur prev opts
23
+ COMPREPLY=()
24
+ cur="${COMP_WORDS[COMP_CWORD]}"
25
+ prev="${COMP_WORDS[COMP_CWORD-1]}"
26
+ opts="add add_http help list reload remove setup"
27
+ opts="$opts start stop tail uninstall version"
28
+
29
+ case "${prev}" in
30
+ add | add_http | list | reload | remove | setup | stop | tail \
31
+ | uninstall | version)
32
+ COMPREPLY=()
33
+ ;;
34
+ -d | --daemon | --no-daemon)
35
+ local extra_opts=("--port")
36
+ COMPREPLY=( $(compgen -W "${extra_opts}" -- ${cur}) )
37
+ ;;
38
+ --port)
39
+ # auto-suggest port
40
+ check_open_port 9000
41
+ ;;
42
+ help)
43
+ # Show opts again, but only once; don't infinitely recurse
44
+ local prev2="${COMP_WORDS[COMP_CWORD-2]}"
45
+ if [ "$prev2" == "help" ]; then
46
+ COMPREPLY=()
47
+ else
48
+ COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
49
+ fi
50
+ ;;
51
+ start)
52
+ local filename=$(find . -type f -name "*.ini")
53
+ if [[ $filename ]]; then
54
+ COMPREPLY=( $(compgen -W "${filename}" -- ${cur}) )
55
+ else
56
+ COMPREPLY=()
57
+ fi
58
+ ;;
59
+ *.ini)
60
+ local start_opts="-d --daemon --no-daemon --port"
61
+ COMPREPLY=( $(compgen -W "${start_opts}" -- ${cur}) )
62
+ ;;
63
+ invoker)
64
+ COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
65
+ ;;
66
+ esac
67
+
68
+ return 0
69
+ }
70
+ complete -F _invoker invoker
@@ -0,0 +1,62 @@
1
+ #compdef invoker
2
+
3
+ # ZSH completion function for Invoker
4
+ #
5
+ # Drop this file somewhere in your $fpath
6
+ # and rename it _invoker
7
+ #
8
+ # The recommended way to install this script is to copy to '~/.zsh/_invoker'
9
+ # and then add the following to your ~/.zshrc file:
10
+ #
11
+ # fpath=(~/.zsh $fpath)
12
+ #
13
+ # You may also need to force rebuild 'zcompdump':
14
+ #
15
+ # rm -f ~/.zcompdump*; compinit
16
+
17
+ local curcontext="$curcontext" state line ret=1
18
+
19
+ _arguments -C \
20
+ '1: :->cmds' \
21
+ '*:: :->args' && ret=0
22
+
23
+ case $state in
24
+ cmds)
25
+ _values 'invoker command' \
26
+ 'add[Add a program to Invoker server]' \
27
+ 'add_http[Add an external process to Invoker DNS server]' \
28
+ 'help[Describe available commands or one specific command]' \
29
+ 'list[List all running processes]' \
30
+ 'reload[Reload a process managed by Invoker]' \
31
+ 'remove[Stop a process managed by Invoker]' \
32
+ 'setup[Run Invoker setup]' \
33
+ 'start[Start Invoker server]' \
34
+ 'stop[Stop Invoker daemon]' \
35
+ 'tail[Tail a particular process]' \
36
+ 'uninstall[Uninstall Invoker and all installed files]' \
37
+ 'version[Print Invoker version]'
38
+ ret=0
39
+ ;;
40
+
41
+ args)
42
+ case $line[1] in
43
+ help)
44
+ if (( CURRENT == 2 )); then
45
+ _values 'commands' \
46
+ 'add' 'add_http' 'list' 'reload' 'remove' 'setup' 'start' 'stop' 'tail' 'uninstall' 'version'
47
+ fi
48
+ ret=0
49
+ ;;
50
+
51
+ start)
52
+ _arguments \
53
+ '(-d --daemon)'{-d,--daemon}'[Daemonize the server into the background]' \
54
+ '(--port)--port[Port series to be used for starting rack servers]' \
55
+ '1:config file:_path_files'
56
+ ret=0
57
+ ;;
58
+ esac
59
+ ;;
60
+ esac
61
+
62
+ return ret
@@ -0,0 +1,26 @@
1
+ # myapp.rb
2
+ require 'sinatra'
3
+
4
+ get '/' do
5
+ 'Hello world!'
6
+ end
7
+
8
+ get "/emacs" do
9
+ redirect to("/vim")
10
+ end
11
+
12
+ get "/vim" do
13
+ "vim rules"
14
+ end
15
+
16
+
17
+ post '/foo' do
18
+ puts request.env
19
+ "done"
20
+ end
21
+
22
+
23
+ post "/api/v1/datapoints" do
24
+ puts request.env
25
+ "done"
26
+ end
@@ -0,0 +1,3 @@
1
+ [rails]
2
+ directory = ./examples
3
+ command = ruby hello_sinatra.rb -p $PORT
@@ -0,0 +1,43 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ GEM_NAME = "meepo"
4
+
5
+ lib = File.expand_path("../lib", __FILE__)
6
+ $: << lib unless $:.include?(lib)
7
+
8
+ require "invoker/version"
9
+
10
+ Gem::Specification.new do |s|
11
+ s.name = GEM_NAME
12
+ s.version = Invoker::VERSION
13
+
14
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
15
+ s.authors = ["Hemant Kumar", "Amitava Basak"]
16
+ s.description = %q{Something small for process management}
17
+ s.email = %q{hemant@codemancers.com}
18
+
19
+ s.files = `git ls-files`.split("\n")
20
+ s.test_files = `git ls-files -- {spec,features}/*`.split("\n")
21
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
22
+ s.require_paths = ["lib"]
23
+
24
+ s.homepage = %q{http://invoker.codemancers.com}
25
+ s.licenses = ["MIT"]
26
+ s.require_paths = ["lib"]
27
+ s.summary = %q{Something small for Process management}
28
+ s.add_dependency("thor", "~> 0.19")
29
+ s.add_dependency("rainbow", "~> 2.0")
30
+ s.add_dependency("iniparse", "~> 1.1")
31
+ s.add_dependency("formatador", "~> 0.2")
32
+ s.add_dependency("eventmachine", "~> 1.0.4")
33
+ s.add_dependency("em-proxy", "~> 0.1")
34
+ s.add_dependency("rubydns", "~> 0.8.5")
35
+ s.add_dependency("uuid", "~> 2.3")
36
+ s.add_dependency("facter", "~> 2.2")
37
+ s.add_dependency("http-parser-lite", "~> 0.6")
38
+ s.add_dependency("dotenv", "~> 2.0")
39
+ s.add_development_dependency("rspec", "~> 3.0")
40
+ s.add_development_dependency("mocha")
41
+ s.add_development_dependency("rake")
42
+ s.add_development_dependency('fakefs')
43
+ end
@@ -0,0 +1,152 @@
1
+ $: << File.dirname(__FILE__) unless $:.include?(File.expand_path(File.dirname(__FILE__)))
2
+
3
+ require "fileutils"
4
+ require "formatador"
5
+
6
+ require "ostruct"
7
+ require "uuid"
8
+ require "json"
9
+ require "rainbow"
10
+ require "rainbow/ext/string"
11
+ require "etc"
12
+
13
+ require "invoker/version"
14
+ require "invoker/logger"
15
+ require "invoker/daemon"
16
+ require "invoker/cli"
17
+ require "invoker/dns_cache"
18
+ require "invoker/ipc"
19
+ require "invoker/power/config"
20
+ require "invoker/power/port_finder"
21
+ require "invoker/power/setup"
22
+ require "invoker/power/setup/linux_setup"
23
+ require "invoker/power/setup/osx_setup"
24
+ require "invoker/power/powerup"
25
+ require "invoker/power/pf_migrate"
26
+ require "invoker/errors"
27
+ require "invoker/parsers/procfile"
28
+ require "invoker/parsers/config"
29
+ require "invoker/commander"
30
+ require "invoker/process_manager"
31
+ require "invoker/command_worker"
32
+ require "invoker/reactor"
33
+ require "invoker/event/manager"
34
+ require "invoker/process_printer"
35
+
36
+ module Invoker
37
+ class << self
38
+ attr_accessor :config, :tail_watchers, :commander
39
+ attr_accessor :dns_cache, :daemonize
40
+
41
+ alias_method :daemonize?, :daemonize
42
+
43
+ def darwin?
44
+ ruby_platform.downcase.include?("darwin")
45
+ end
46
+
47
+ def linux?
48
+ ruby_platform.downcase.include?("linux")
49
+ end
50
+
51
+ def ruby_platform
52
+ RUBY_PLATFORM
53
+ end
54
+
55
+ def load_invoker_config(file, port)
56
+ @config = Invoker::Parsers::Config.new(file, port)
57
+ @dns_cache = Invoker::DNSCache.new(@invoker_config)
58
+ @tail_watchers = Invoker::CLI::TailWatcher.new
59
+ @commander = Invoker::Commander.new
60
+ end
61
+
62
+ def close_socket(socket)
63
+ socket.close
64
+ rescue StandardError => error
65
+ Invoker::Logger.puts "Error removing socket #{error}"
66
+ end
67
+
68
+ def daemon
69
+ @daemon ||= Invoker::Daemon.new
70
+ end
71
+
72
+ def can_run_balancer?(throw_warning = true)
73
+ return true if File.exist?(Invoker::Power::Config.config_file)
74
+
75
+ if throw_warning
76
+ Invoker::Logger.puts("Invoker has detected setup has not been run. Domain feature will not work without running setup command.".color(:red))
77
+ end
78
+ false
79
+ end
80
+
81
+ def setup_config_location
82
+ config_dir = Invoker::Power::Config.config_dir
83
+ return config_dir if Dir.exist?(config_dir)
84
+
85
+ if File.exist?(config_dir)
86
+ old_config = File.read(config_dir)
87
+ FileUtils.rm_f(config_dir)
88
+ end
89
+
90
+ FileUtils.mkdir(config_dir)
91
+
92
+ migrate_old_config(old_config, config_dir) if old_config
93
+ config_dir
94
+ end
95
+
96
+ def run_without_bundler
97
+ if defined?(Bundler)
98
+ Bundler.with_clean_env do
99
+ yield
100
+ end
101
+ else
102
+ yield
103
+ end
104
+ end
105
+
106
+ def notify_user(message)
107
+ if Invoker.darwin?
108
+ run_without_bundler { check_and_notify_with_terminal_notifier(message) }
109
+ elsif Invoker.linux?
110
+ notify_with_libnotify(message)
111
+ end
112
+ end
113
+
114
+ def check_and_notify_with_terminal_notifier(message)
115
+ command_path = `which terminal-notifier`
116
+ if command_path && !command_path.empty?
117
+ system("terminal-notifier -message '#{message}' -title Invoker")
118
+ end
119
+ end
120
+
121
+ def notify_with_libnotify(message)
122
+ begin
123
+ require "libnotify"
124
+ Libnotify.show(body: message, summary: "Invoker", timeout: 2.5)
125
+ rescue LoadError; end
126
+ end
127
+
128
+ def migrate_old_config(old_config, config_location)
129
+ new_config = File.join(config_location, 'config')
130
+ File.open(new_config, 'w') do |file|
131
+ file.write(old_config)
132
+ end
133
+ end
134
+
135
+ # On some platforms `Dir.home` or `ENV['HOME']` does not return home directory of user.
136
+ # this is especially true, after effective and real user id of process
137
+ # has been changed.
138
+ #
139
+ # @return [String] home directory of the user
140
+ def home
141
+ if File.writable?(Dir.home)
142
+ Dir.home
143
+ else
144
+ Etc.getpwuid(Process.uid).dir
145
+ end
146
+ end
147
+
148
+ def default_tld
149
+ 'dev'
150
+ end
151
+ end
152
+ end