kleiber 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: e88d5b1af92965f42cc027de4a82e66d2d8907d5
4
+ data.tar.gz: 2056b863efcd692deea2a52ce582e1f045a973da
5
+ SHA512:
6
+ metadata.gz: a905e1ec600fa5369ed7fd45fea65d612e4d61a2c207d8e3467b0989dc10a98902ecd82d009381b4c490954c3bee216bc25458b58ddcc210650ab4f0165398f0
7
+ data.tar.gz: c835bcc55c8c516075db4200752a97a8562ecbd7d5c9c5b5af8254c303903ff5eb61f64ac13ed5bfef7612e86ae4704185de56b60d16dd8893111868aff708e0
data/.gitignore ADDED
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ .vagrant/
11
+ .byebug_history
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --require spec_helper
2
+ --format documentation
3
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,5 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - 2.3.0
5
+ before_install: gem install bundler -v 1.12.5
@@ -0,0 +1,49 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, and in the interest of
4
+ fostering an open and welcoming community, we pledge to respect all people who
5
+ contribute through reporting issues, posting feature requests, updating
6
+ documentation, submitting pull requests or patches, and other activities.
7
+
8
+ We are committed to making participation in this project a harassment-free
9
+ experience for everyone, regardless of level of experience, gender, gender
10
+ identity and expression, sexual orientation, disability, personal appearance,
11
+ body size, race, ethnicity, age, religion, or nationality.
12
+
13
+ Examples of unacceptable behavior by participants include:
14
+
15
+ * The use of sexualized language or imagery
16
+ * Personal attacks
17
+ * Trolling or insulting/derogatory comments
18
+ * Public or private harassment
19
+ * Publishing other's private information, such as physical or electronic
20
+ addresses, without explicit permission
21
+ * Other unethical or unprofessional conduct
22
+
23
+ Project maintainers have the right and responsibility to remove, edit, or
24
+ reject comments, commits, code, wiki edits, issues, and other contributions
25
+ that are not aligned to this Code of Conduct, or to ban temporarily or
26
+ permanently any contributor for other behaviors that they deem inappropriate,
27
+ threatening, offensive, or harmful.
28
+
29
+ By adopting this Code of Conduct, project maintainers commit themselves to
30
+ fairly and consistently applying these principles to every aspect of managing
31
+ this project. Project maintainers who do not follow or enforce the Code of
32
+ Conduct may be permanently removed from the project team.
33
+
34
+ This code of conduct applies both within project spaces and in public spaces
35
+ when an individual is representing the project or its community.
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
38
+ reported by contacting a project maintainer at qelphybox@gmail.com. All
39
+ complaints will be reviewed and investigated and will result in a response that
40
+ is deemed necessary and appropriate to the circumstances. Maintainers are
41
+ obligated to maintain confidentiality with regard to the reporter of an
42
+ incident.
43
+
44
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
45
+ version 1.3.0, available at
46
+ [http://contributor-covenant.org/version/1/3/0/][version]
47
+
48
+ [homepage]: http://contributor-covenant.org
49
+ [version]: http://contributor-covenant.org/version/1/3/0/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in kleiber.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016 kirill_bobykin
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/Makefile ADDED
@@ -0,0 +1,9 @@
1
+ test:
2
+ bundle exec rspec
3
+
4
+ build:
5
+ gem build kleiber.gemspec
6
+
7
+ publish:
8
+ gem push *.gem
9
+ rm *.gem
data/README.md ADDED
@@ -0,0 +1,130 @@
1
+ # Kleiber
2
+ Manage your development enviroments faster!
3
+ Project is REDESIGNING NOW!
4
+
5
+ ![Carlos Kleiber](http://glasove.com/images/crops/32544_IAiSTZMEfO1QnQHfvwvghswY229lKS-560x315-trim%280,0,950,533%29.jpg)
6
+
7
+ [Carlos Kleiber](https://en.wikipedia.org/wiki/Carlos_Kleiber) (3 July 1930 – 13 July 2004) was a German-born Austrian conductor who is widely regarded as being among the greatest conductors of the 20th century.
8
+
9
+ ## Description
10
+
11
+ Kleiber provides an interface for control multiple vagrant machines. In case when you have distributed system of applications, each application have its vagrant machine and you need to manage system locally in development order Kleiber may be useful.
12
+
13
+ Kleiber combines *projects* into groups called *symphonies* which can be used over centralized control. Using projects combined in symphonies provides general environment for all used projects. Also vagrant provides *tasks* interface for control applications in vagrant.
14
+
15
+ ## Requirements
16
+ On your HOST machine:
17
+
18
+ - ruby >= 2.0
19
+ - vagrant
20
+
21
+ ## Installation
22
+ Install it manually
23
+ ```
24
+ gem install kleiber
25
+ ```
26
+
27
+ ## Usage
28
+ Kleiber provides simple CLI.
29
+ ```bash
30
+ kleiber <vagrant command> <symphony name> [projects] [-t tasks:chain:colon:separated ]
31
+ ```
32
+ Examples:
33
+ ```bash
34
+ kleiber up symphony1 # calls vagrant up for symphonies
35
+ kleiber up symphony1 -t setup:run # calls vagrant up && vagrant ssh -c 'setupcommand... && runcommand...'
36
+ kleiber halt symphony1 project1 # calls vagrant ssh for project1 in symphony1
37
+ ```
38
+
39
+ ## Configuration
40
+ Before start to use kleiber you need to make config like this:
41
+ ```yaml
42
+ ---
43
+ # List of projects which kleiber can use in its symphonies
44
+ :projects:
45
+ - :name: project1
46
+ :prefix: PROJ1
47
+ :path: /path/to/project/dir
48
+ :guest_port: 8000
49
+ :host_port: 8000
50
+ :host: 125.12.123.42
51
+ :tasks:
52
+ setup: 'npm i'
53
+ run: 'node start'
54
+ :env:
55
+ ANOTHERONE_HOST: 192.168.33.33
56
+
57
+ - :name: project2
58
+ :prefix: PROJ2
59
+ :path: /path/to/project/dir
60
+ :guest_port: 8000
61
+ :host_port: 8000
62
+ :host: 125.12.123.42
63
+
64
+ # Dictionary of tasks with the lowest priority for all projects and symphonies
65
+ # Actually, we can call it like 'list of default task values'
66
+ :tasks:
67
+ setup: 'bundle install --jobs 4'
68
+ run: 'bundle exec rails s -p %{port}'
69
+ console: 'bundle exec rails c'
70
+
71
+ # Dictionary of symphonies which kleiber can perform
72
+ :symphonies:
73
+ symphony1:
74
+ :projects: ['project1', 'project2']
75
+ :tasks:
76
+ setup: 'bundle'
77
+ run: 'rails c'
78
+ :env:
79
+ OTHER_HOST: 127.0.0.1
80
+
81
+ # Working terminal settings
82
+ :terminal:
83
+ :exec: 'gnome-terminal'
84
+ :new_tab: '--tab'
85
+ :exec_command: '-e'
86
+ ```
87
+ ### Project parameters
88
+ | Key | Type | Description |
89
+ |--------------|-----------|----------------------------------------------|
90
+ | name * | string | Project identificator |
91
+ | prefix * | string | Prefix for HOST and PORT env variables |
92
+ | path * | string | Absolute path to project directory |
93
+ | guest_port * | number | Vagrant guest port |
94
+ | host_port * | number | Vagrant host port |
95
+ | host * | string | Vagrant host ip address |
96
+ | tasks | key/value | List of task definitions for project |
97
+ | env | key/value | List of env variables definition for project |
98
+
99
+ \* - required parameters
100
+
101
+ `tasks` defined values have the highest priority. That means if one defined, it will be used when task required to execute for project in symphony.
102
+
103
+ ### Symphony parameters
104
+ | Key | Type | Description |
105
+ |------------|-----------|-----------------------------------------------|
106
+ | projects * | list | List of projects uses in one symphony |
107
+ | tasks | key/value | List of task definitions for symphony |
108
+ | env | key/value | List of env variables definition for symphony |
109
+
110
+ \* - required parameters
111
+
112
+ `tasks` defined values have lower priority than project task values. That means, it will be used if project value isn't defined.
113
+
114
+
115
+
116
+ ## Development
117
+ Recommended to install [Vagrant](https://www.vagrantup.com/).
118
+ `vagrant up && vagrant ssh` - switch on and get access to development vagrant machine.
119
+ `bin/setup` - install dependecies and setup app.
120
+ `bundle exec rspec` - to run tests.
121
+ `bundle exec rake install` - install gem on your local machine.
122
+
123
+ ## Contributing
124
+
125
+ Bug reports and pull requests are welcome on GitHub at https://github.com/qelphybox/kleiber. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
126
+
127
+
128
+ ## License
129
+
130
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/Vagrantfile ADDED
@@ -0,0 +1,11 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ Vagrant.require_version '>= 1.8.3'
5
+
6
+ Vagrant.configure(2) do |config|
7
+ config.vm.box = 'ubuntu/trusty64'
8
+ config.vm.provision :ansible_local do |ansible|
9
+ ansible.playbook = '/vagrant/cm/vagrant.yml'
10
+ end
11
+ end
data/bin/console ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'kleiber'
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require 'irb'
14
+ require 'irb/completion'
15
+ IRB.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
data/cm/vagrant.yml ADDED
@@ -0,0 +1,34 @@
1
+ ---
2
+ - hosts: all
3
+ become: yes
4
+
5
+ tasks:
6
+ - name: Add ruby apt repo
7
+ apt_repository:
8
+ repo: 'ppa:brightbox/ruby-ng'
9
+
10
+ - name: Install apt packages
11
+ apt:
12
+ name: '{{ item }}'
13
+ update_cache: yes
14
+ with_items:
15
+ - git
16
+ - vim
17
+ - mc
18
+ - ruby2.3
19
+ - ruby2.3-dev
20
+ - build-essential
21
+ - zlib1g-dev
22
+ - software-properties-common
23
+
24
+ - name: Install bundler
25
+ gem:
26
+ name: bundler
27
+ state: latest
28
+ user_install: no
29
+
30
+ - name: Add autofollow
31
+ lineinfile:
32
+ dest: "/home/vagrant/.bashrc"
33
+ regexp: "^cd /vagrant"
34
+ line: "cd /vagrant"
data/exe/kleiber ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bundler/setup'
4
+ require 'kleiber'
5
+ require 'kleiber/cli'
6
+
7
+ Kleiber::CLI.start(ARGV)
data/kleiber.gemspec ADDED
@@ -0,0 +1,33 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'kleiber/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'kleiber'
8
+ spec.version = Kleiber::VERSION
9
+ spec.authors = ['Kirill Bobykin']
10
+ spec.email = ['qelphybox@gmail.com']
11
+
12
+ spec.summary = 'Manage your development enviroments faster!'
13
+ spec.description = 'If you need to develop more than one application and they actively communicate each other.'
14
+ spec.homepage = 'https://github.com/qelphybox/kleiber'
15
+ spec.license = 'MIT'
16
+
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
18
+ spec.bindir = 'exe'
19
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
+ spec.require_paths = ['lib']
21
+ spec.metadata['yard.run'] = 'yri'
22
+
23
+ spec.add_development_dependency 'bundler', '~> 1.12'
24
+ spec.add_development_dependency 'rake', '~> 10.0'
25
+ spec.add_development_dependency 'rspec', '~> 3.0'
26
+ spec.add_development_dependency 'fakefs', '~> 0.8.1'
27
+ spec.add_development_dependency 'yard'
28
+ spec.add_development_dependency 'factory_girl'
29
+ spec.add_development_dependency 'byebug'
30
+
31
+ spec.add_dependency 'thor'
32
+ spec.add_dependency 'cocaine'
33
+ end
data/lib/kleiber.rb ADDED
@@ -0,0 +1,60 @@
1
+ # encoding: utf-8
2
+
3
+ module Kleiber
4
+ ROOT = File.absolute_path("#{__dir__}/..")
5
+ DEFAULT_SETTINGS_PATH = File.expand_path('.projects.yml', ENV['HOME'])
6
+
7
+ autoload :Settings, 'kleiber/settings'
8
+ autoload :Symphony, 'kleiber/symphony'
9
+ autoload :Project, 'kleiber/project'
10
+ autoload :Terminal, 'kleiber/terminal'
11
+ autoload :Commands, 'kleiber/commands'
12
+ autoload :Performer, 'kleiber/performer'
13
+ autoload :CLI, 'kleiber/cli'
14
+
15
+ class << self
16
+ # Returns performer with defined options
17
+ # @param [String] symphony_name name of symphony to perform
18
+ # @param [Array] projects list of projects names to run only
19
+ # @param [Hash] options options of perfomance
20
+ # @return [Performer] return performer object
21
+ def perform(symphony_name, projects, options)
22
+ Performer.new(symphonies[symphony_name], projects, options)
23
+ end
24
+
25
+ # Returns projects which kleiber can operate
26
+ # @return [Array] projects
27
+ def projects
28
+ settings.projects.map do |project_settings|
29
+ Project.new(project_settings)
30
+ end
31
+ end
32
+
33
+ # Returns symphonies which kleiber can control
34
+ # @return [Hash] symphonies
35
+ def symphonies
36
+ settings.symphonies.each_with_object({}) do |(symphony_name, symphony_settings), result|
37
+ symp_projects = projects.select { |p| symphony_settings[:projects].include?(p.name) }
38
+ result[symphony_name] = Symphony.new(symphony_name, symp_projects, symphony_settings)
39
+ end
40
+ end
41
+
42
+ # Provides blockparam settings for configure
43
+ # @yieldparam [Settings] settings
44
+ def configure
45
+ yield settings
46
+ end
47
+
48
+ # Returns settings if library
49
+ # @return [Settings] settings
50
+ def settings
51
+ @settings ||= Settings.new(DEFAULT_SETTINGS_PATH)
52
+ end
53
+
54
+ # Returns current terminal object
55
+ # @return [Terminal] current terminal
56
+ def terminal
57
+ @terminal ||= Terminal.new(settings.terminal)
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,32 @@
1
+ # encoding: utf-8
2
+
3
+ require 'thor'
4
+
5
+ module Kleiber
6
+ # Class CLI provides command line interface for kleiber
7
+ # @author Кирилл Бобыкин <qelphybox@gmail.com>
8
+ class CLI < Thor
9
+ desc 'up SYMPHONY_NAME [PROJECTS]', 'runs vagrant up for projects'
10
+ method_option :tasks, type: :string, aliases: '-t'
11
+ def up(symphony_name, *projects)
12
+ Kleiber.perform(symphony_name, projects, options).up
13
+ end
14
+
15
+ desc 'ssh SYMPHONY_NAME [PROJECTS]', 'runs vagrant ssh for projects'
16
+ method_option :tasks, type: :string, aliases: '-t'
17
+ def ssh(symphony_name, *projects)
18
+ Kleiber.perform(symphony_name, projects, options).ssh
19
+ end
20
+
21
+ desc 'reload SYMPHONY_NAME [PROJECTS]', 'runs vagrant reload for projects'
22
+ method_option :tasks, type: :string, aliases: '-t'
23
+ def reload(symphony_name, *projects)
24
+ Kleiber.perform(symphony_name, projects, options).reload
25
+ end
26
+
27
+ desc 'halt SYMPHONY_NAME [PROJECTS]', 'runs vagrant halt for projects'
28
+ def halt(symphony_name, *projects)
29
+ Kleiber.perform(symphony_name, projects, options).halt
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,159 @@
1
+ # encoding: utf-8
2
+
3
+ require 'cocaine'
4
+
5
+ module Kleiber
6
+ module Commands
7
+ def vagrant
8
+ Cocaine::CommandLine.new('/usr/bin/vagrant')
9
+ end
10
+
11
+ # Returns vagrant up command line
12
+ # @return [Cocaine::CommandLine] vagrant up command
13
+ def vagrant_up
14
+ Cocaine::CommandLine.new(vagrant.command, 'up')
15
+ end
16
+
17
+ # Returns vagrant ssh command line
18
+ # @return [Cocaine::CommandLine] vagrant ssh command
19
+ def vagrant_ssh
20
+ Cocaine::CommandLine.new(vagrant.command, 'ssh')
21
+ end
22
+
23
+ # Returns vagrant reload command line
24
+ # @return [Cocaine::CommandLine] vagrant reload command
25
+ def vagrant_reload
26
+ Cocaine::CommandLine.new(vagrant.command, 'reload')
27
+ end
28
+
29
+ # Returns vagrant halt command line
30
+ # @return [Cocaine::CommandLine] vagrant halt command
31
+ def vagrant_halt
32
+ Cocaine::CommandLine.new(vagrant.command, 'halt')
33
+ end
34
+
35
+ # Returns vagrant destroy command line
36
+ # @return [Cocaine::CommandLine] vagrant destroy command
37
+ def vagrant_destroy
38
+ Cocaine::CommandLine.new(vagrant.command, 'destroy')
39
+ end
40
+
41
+ # Returns vagrant provision command line
42
+ # @return [Cocaine::CommandLine] vagrant provision command
43
+ def vagrant_provision
44
+ Cocaine::CommandLine.new(vagrant.command, 'provision')
45
+ end
46
+
47
+ # Executes command in new tab
48
+ # @param [String] command command line to run
49
+ def terminal_execute(command)
50
+ with_tmpfile_script(command) do |file|
51
+ Kleiber.terminal.execute(file)
52
+ end
53
+ end
54
+
55
+ # Provides command to execute within temporary bashscript file
56
+ # @param [String] command to execute
57
+ # @yieldparam [File] file bashcript to use in terminal instance
58
+ def with_tmpfile_script(command)
59
+ Tempfile.create([name, '.sh'], '/tmp') do |file|
60
+ file.chmod(0_755)
61
+ file.write(scriptify(command))
62
+ file.close
63
+ yield file
64
+ end
65
+ end
66
+
67
+ # Returns text of bashscript file with command
68
+ # @param [String] command command line to execute
69
+ # @return [String] scriptlike string
70
+ def scriptify(command)
71
+ ['#!/bin/bash', 'unset RUBYLIB', command].join("\n")
72
+ end
73
+
74
+ # Returns command line for `vagrant up` command.
75
+ # Evaluates tasks executions line by taken parameters
76
+ # @param [Hash] params params hash with values to execute with
77
+ # @return [String] line for vagrant up execution
78
+ def handle_up(params)
79
+ line = [vagrant_(:up)]
80
+ line << handle_ssh(params) unless params[:tasks].empty?
81
+ line.join(' && ')
82
+ end
83
+
84
+ # Returns command line for `vagrant ssh` command.
85
+ # Evaluates tasks executions line by taken parameters
86
+ # @param [Hash] params params hash with values to execute with
87
+ # @return [String] line for vagrant ssh execution
88
+ def handle_ssh(params)
89
+ line = [vagrant_(:ssh)]
90
+ line << ssh_exec_line(params) unless params[:tasks].empty?
91
+ line.join(' ')
92
+ end
93
+
94
+ # Returns command line for `vagrant reload` command.
95
+ # Evaluates tasks executions line by taken parameters
96
+ # @param [Hash] params params hash with values to execute with
97
+ # @return [String] line for vagrant reload execution
98
+ def handle_reload(params)
99
+ line = [vagrant_(:reload)]
100
+ line << handle_ssh(params) unless params[:tasks].empty?
101
+ line.join(' && ')
102
+ end
103
+
104
+ # Returns command line for `vagrant halt` command.
105
+ # @param [Hash] _params this handler doesn't use params
106
+ # @return [String] line for vagrant halt execution
107
+ def handle_halt(_params)
108
+ vagrant_(:halt)
109
+ end
110
+
111
+ # Returns option which executes tasks in vagrant
112
+ # @example
113
+ # "-c 'FIRST_HOST=192.168.22.20 cd /vagrant && bundle exec rails server'"
114
+ # @param [Hash] params params hash with values to execute with
115
+ # @return [String] option
116
+ def ssh_exec_line(params)
117
+ Cocaine::CommandLine.new('', '-c :in_machine').command(in_machine: in_machine(params))
118
+ end
119
+
120
+ # Returns commandline need to execute in vagrant machine.
121
+ # Actually, it's an environment settings and chain of tasks
122
+ # @example
123
+ # 'FIRST_HOST=192.168.22.20 cd /vagrant && bundle exec rails server'
124
+ # @param [Hash] params params hash with values to execute with
125
+ # @return [String]
126
+ def in_machine(params)
127
+ [apply_env_line(params[:env]), tasks_line(params[:tasks])].join(' ')
128
+ end
129
+
130
+ # Returns tasks chain command line
131
+ # @param [Hash] tasks_to_run final defined tasks hash
132
+ # @example
133
+ # 'cd /vagrant && bundle install --binstubs && bundle exec rackup'
134
+ # @return [String] tasks commandline
135
+ def tasks_line(tasks_to_run)
136
+ line = ['cd /vagrant']
137
+ line += tasks_to_run.reduce({}) do |result, (key, value)|
138
+ result.merge(key => tasks[key] || value)
139
+ end.values
140
+ line.join(' && ')
141
+ end
142
+
143
+ # Returns string of environment variable definitions
144
+ # @param [Hash] env_to_app final defined environment variables list
145
+ # @example
146
+ # 'FIRST_HOST=192.168.22.20 FIRST_PORT=3030 SECOND_HOST=192.168.22.21 SECOND_PORT=3030'
147
+ # @return [String] environment definition string
148
+ def apply_env_line(env_to_app)
149
+ env_to_app.map { |e| e.join('=') }.join(' ')
150
+ end
151
+
152
+ # Returns vagrant command
153
+ # @param [Symbol, String] command vagrant command
154
+ # @return [String] command line
155
+ def vagrant_(command)
156
+ send("vagrant_#{command}".to_sym).command
157
+ end
158
+ end
159
+ end
@@ -0,0 +1,38 @@
1
+ # encoding: utf-8
2
+
3
+ module Kleiber
4
+ # Provides api for symphony perphomance
5
+ # @author Кирилл Бобыкин <qelphybox@gmail.com>
6
+ class Performer
7
+ attr_reader :symphony, :projects
8
+ def initialize(symphony, projects, options)
9
+ @symphony = symphony
10
+ @projects = projects
11
+ @tasks = options[:tasks]
12
+ end
13
+
14
+ # Generates vagrant api methods
15
+ # @example
16
+ # def up
17
+ # symphony.up(projects, task_names)
18
+ # end
19
+ %i(up ssh halt reload).each do |sym|
20
+ define_method sym do
21
+ symphony.send(sym, projects, tasks)
22
+ end
23
+ end
24
+
25
+ # Returns array of task names
26
+ # @return [Array] task names
27
+ def task_names
28
+ @tasks ? @tasks.split(':') : []
29
+ end
30
+
31
+ # Returns tasks to run with command
32
+ # @return [Hash] tasks to run
33
+ def tasks
34
+ all_tasks = Kleiber.settings.tasks
35
+ task_names.each_with_object({}) { |t, hash| hash[t] = all_tasks[t] if all_tasks.key?(t) }
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,54 @@
1
+ # encoding: utf-8
2
+
3
+ module Kleiber
4
+ # Provides api to control such project
5
+ # @author Кирилл Бобыкин <qelphybox@gmail.com>
6
+ class Project
7
+ include Commands
8
+ attr_reader :name, :prefix, :path, :guest_port, :host_port, :host
9
+ def initialize(settings)
10
+ @name = settings[:name]
11
+ @prefix = settings[:prefix]
12
+ @path = settings[:path]
13
+ @guest_port = settings[:guest_port]
14
+ @host_port = settings[:host_port]
15
+ @host = settings[:host]
16
+ @tasks = settings[:tasks]
17
+ @env = settings[:env]
18
+ end
19
+
20
+ VARS = {
21
+ host: 'HOST',
22
+ guest_port: 'PORT'
23
+ }
24
+
25
+ def env
26
+ @env || {}
27
+ end
28
+
29
+ def tasks
30
+ @tasks || {}
31
+ end
32
+
33
+ # Return env variables of this project
34
+ # @return [Hash]
35
+ def environment
36
+ @env_vars ||= VARS.reduce({}) do |hash, (key, value)|
37
+ hash.merge("#{prefix}_#{value}" => send(key))
38
+ end.merge(env)
39
+ end
40
+
41
+ %i(up ssh halt reload).each do |sym|
42
+ define_method sym do |params|
43
+ terminal_execute(command_with(__method__, params))
44
+ end
45
+ end
46
+
47
+ # Returns command with option to run
48
+ # @param [Hash] params params need run with
49
+ # @return [String] command line
50
+ def command_with(command, params)
51
+ ["cd #{path}", send("handle_#{command}", params)].join(' && ')
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,41 @@
1
+ #!/bin/bash
2
+
3
+ export GEMS_RKIS_DIR_PATH=${1}
4
+ case ${2} in
5
+ 'up' )
6
+ vagrant up
7
+ ;;
8
+ 'ups' )
9
+ vagrant up && vagrant ssh -c "cd /vagrant && bundle install && ${*: 4} bundle exec rails s -p ${3}"
10
+ ;;
11
+ 'upc' )
12
+ vagrant up && vagrant ssh -c "cd /vagrant && bundle install && ${*: 4} bundle exec rails c -p ${3}"
13
+ ;;
14
+ 'ssh' )
15
+ vagrant ssh
16
+ ;;
17
+ 'sshs' )
18
+ vagrant ssh -c "cd /vagrant && bundle install && ${*: 4} bundle exec rails s -p ${3}"
19
+ ;;
20
+ 'sshc' )
21
+ vagrant ssh -c "cd /vagrant && bundle install && ${*: 4} bundle exec rails c"
22
+ ;;
23
+ 'halt' )
24
+ vagrant halt
25
+ ;;
26
+ 'reload' )
27
+ vagrant reload
28
+ ;;
29
+ 'reloads' )
30
+ vagrant reload && vagrant ssh -c "cd /vagrant && bundle install && ${*: 4} bundle exec rails s -p ${3}"
31
+ ;;
32
+ 'reloadc' )
33
+ vagrant reload && vagrant ssh -c "cd /vagrant && bundle install && ${*: 4} bundle exec rails c -p ${3}"
34
+ ;;
35
+ 'destroy' )
36
+ vagrant destroy --force
37
+ ;;
38
+ 'provision' )
39
+ vagrant provision
40
+ ;;
41
+ esac
@@ -0,0 +1,70 @@
1
+ # encoding: utf-8
2
+
3
+ require 'fileutils'
4
+ require 'yaml'
5
+
6
+ module Kleiber
7
+ # Provides access to settings of library
8
+ # @author Кирилл Бобыкин <qelphybox@gmail.com>
9
+ class Settings
10
+ # backporting for old ruby versions
11
+ REQUIRED_KEYS = %w(name prefix path guest_port host_port host).map(&:to_sym)
12
+
13
+ attr_accessor :path
14
+
15
+ def initialize(path)
16
+ @path = path
17
+ end
18
+
19
+ # Returns projects settings hash
20
+ # @return [Array] projects hash
21
+ def projects
22
+ config[:projects]
23
+ end
24
+
25
+ # Returns tasks settings hash
26
+ # @return [Hash] tasks hash
27
+ def tasks
28
+ config[:tasks]
29
+ end
30
+
31
+ # Returns terminal settings
32
+ # @return [Hash]
33
+ def terminal
34
+ config[:terminal]
35
+ end
36
+
37
+ # Returns symphonies settings
38
+ # @return [Hash]
39
+ def symphonies
40
+ config[:symphonies]
41
+ end
42
+
43
+ # Validates settings
44
+ # @return [Boolean] validation result
45
+ def valid?
46
+ private_methods.map do |m|
47
+ send(m) if m.to_s.start_with?('validate_')
48
+ end.compact.all?
49
+ end
50
+
51
+ private
52
+
53
+ def validate_symphonies
54
+ symphonies && symphonies.is_a?(Hash) &&
55
+ symphonies.values.all? do |symp|
56
+ symp.key?(:projects) && symp[:projects].is_a?(Array) &&
57
+ symp[:projects].all? { |p| projects.map { |e| e[:name] }.include?(p) }
58
+ end
59
+ end
60
+
61
+ def validate_projects
62
+ projects && projects.is_a?(Array) &&
63
+ projects.all? { |p| (REQUIRED_KEYS - p.keys).empty? }
64
+ end
65
+
66
+ def config
67
+ YAML.load_file(@path)
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,64 @@
1
+ # encoding: utf-8
2
+
3
+ module Kleiber
4
+ # Model describes session of performances your vagrants.
5
+ # Provides api for control your symphony.
6
+ # @author Bobykin Kirill <qelphybox@gmail.com>
7
+ class Symphony
8
+ attr_reader :projects, :name
9
+
10
+ def initialize(name, projects, options)
11
+ @name = name
12
+ @projects = projects
13
+ @tasks = options[:tasks]
14
+ @env = options[:env]
15
+ end
16
+
17
+ def tasks
18
+ @tasks || {}
19
+ end
20
+
21
+ def env
22
+ @env || {}
23
+ end
24
+
25
+ # Generates vagrant api methods
26
+ # @param [Array] only only this project names
27
+ # @param [Array] tasks
28
+ # @example
29
+ # def up(only, tasks)
30
+ # select_projects(only).each { |p| p.up(args) }
31
+ # end
32
+ %i(up ssh halt reload).each do |sym|
33
+ define_method sym do |only, tasks_to_run|
34
+ select_projects(only).each do |p|
35
+ p.send(sym, tasks: task_list(tasks_to_run), env: environment)
36
+ end
37
+ end
38
+ end
39
+
40
+ # Selects project from projects
41
+ # @param only [Array] projects for filter
42
+ # @return [Array] result array
43
+ def select_projects(only)
44
+ only.empty? ? projects : projects.select { |p| only.include?(p.name) }
45
+ end
46
+
47
+ # Defines symphony task values and environment varaibles, if it exists
48
+ # @param [Hash] list list of tasks to run
49
+ # @return [Hash] task list with symphony values
50
+ def task_list(list)
51
+ list.each_with_object({}) do |(name, task), hash|
52
+ hash[name] = tasks[name] || task
53
+ end
54
+ end
55
+
56
+ # Returns hash with definition all env variables of this symphony
57
+ # @return [Hash] env variables hash
58
+ def environment
59
+ projects.reduce(env) do |result, project|
60
+ result.merge(project.environment)
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,40 @@
1
+ # encoding: utf-8
2
+
3
+ module Kleiber
4
+ # Class Terminal provides api for current terminal
5
+ # @author Кирилл Бобыкин <qelphybox@gmail.com>
6
+ class Terminal
7
+ attr_reader :exec, :new_tab, :title, :exec_command
8
+ def initialize(settings)
9
+ @exec = settings[:exec]
10
+ @new_tab = settings[:new_tab]
11
+ @title = settings[:title]
12
+ @exec_command = settings[:exec_command]
13
+ end
14
+
15
+ # Runs command line in new tab
16
+ # @param [String] line line to execute
17
+ def execute(scriptfile)
18
+ puts command_line.command(script: scriptfile.path)
19
+ command_line.run(script: scriptfile.path)
20
+ end
21
+
22
+ private
23
+
24
+ # Returns CommandLine for execution
25
+ # @param [File] scriptfile file with script to execute in machine
26
+ # @return [Cocaine::CommandLine] new command line to execute
27
+ def command_line
28
+ Cocaine::CommandLine.new(exec, options)
29
+ end
30
+
31
+ # Return options line
32
+ # @return [String] terminal options line
33
+ def options
34
+ options_line = ['-e :script']
35
+ options_line.unshift(title) if title
36
+ options_line.unshift(new_tab) if new_tab
37
+ options_line.join(' ')
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,3 @@
1
+ module Kleiber
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,39 @@
1
+ ---
2
+ :projects:
3
+ - :name: project1
4
+ :prefix: PROJ1
5
+ :path: /path/to/project/dir
6
+ :guest_port: 8000
7
+ :host_port: 8000
8
+ :host: 125.12.123.42
9
+ :tasks:
10
+ setup: 'npm i'
11
+ run: 'node start'
12
+ :env:
13
+ ANOTHERONE_HOST: 192.168.33.33
14
+
15
+ - :name: project2
16
+ :prefix: PROJ2
17
+ :path: /path/to/project/dir
18
+ :guest_port: 8000
19
+ :host_port: 8000
20
+ :host: 125.12.123.42
21
+
22
+ :tasks:
23
+ setup: 'bundle install --jobs 4'
24
+ run: 'bundle exec rails s -p %{port}'
25
+ console: 'bundle exec rails c'
26
+
27
+ :symphonies:
28
+ symphony1:
29
+ :projects: ['project1', 'project2']
30
+ :tasks:
31
+ setup: 'bundle'
32
+ run: 'rails c'
33
+ :env:
34
+ OTHER_HOST: 127.0.0.1
35
+
36
+ :terminal:
37
+ :exec: 'gnome-terminal'
38
+ :new_tab: '--tab'
39
+ :exec_command: '-e'
metadata ADDED
@@ -0,0 +1,199 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: kleiber
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Kirill Bobykin
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2016-12-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.12'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.12'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: fakefs
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.8.1
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.8.1
69
+ - !ruby/object:Gem::Dependency
70
+ name: yard
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: factory_girl
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: byebug
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: thor
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: cocaine
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :runtime
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
139
+ description: If you need to develop more than one application and they actively communicate
140
+ each other.
141
+ email:
142
+ - qelphybox@gmail.com
143
+ executables:
144
+ - kleiber
145
+ extensions: []
146
+ extra_rdoc_files: []
147
+ files:
148
+ - ".gitignore"
149
+ - ".rspec"
150
+ - ".travis.yml"
151
+ - CODE_OF_CONDUCT.md
152
+ - Gemfile
153
+ - LICENSE.txt
154
+ - Makefile
155
+ - README.md
156
+ - Rakefile
157
+ - Vagrantfile
158
+ - bin/console
159
+ - bin/setup
160
+ - cm/vagrant.yml
161
+ - exe/kleiber
162
+ - kleiber.gemspec
163
+ - lib/kleiber.rb
164
+ - lib/kleiber/cli.rb
165
+ - lib/kleiber/commands.rb
166
+ - lib/kleiber/performer.rb
167
+ - lib/kleiber/project.rb
168
+ - lib/kleiber/scripts/vag.sh
169
+ - lib/kleiber/settings.rb
170
+ - lib/kleiber/symphony.rb
171
+ - lib/kleiber/terminal.rb
172
+ - lib/kleiber/version.rb
173
+ - projects-example.yml
174
+ homepage: https://github.com/qelphybox/kleiber
175
+ licenses:
176
+ - MIT
177
+ metadata:
178
+ yard.run: yri
179
+ post_install_message:
180
+ rdoc_options: []
181
+ require_paths:
182
+ - lib
183
+ required_ruby_version: !ruby/object:Gem::Requirement
184
+ requirements:
185
+ - - ">="
186
+ - !ruby/object:Gem::Version
187
+ version: '0'
188
+ required_rubygems_version: !ruby/object:Gem::Requirement
189
+ requirements:
190
+ - - ">="
191
+ - !ruby/object:Gem::Version
192
+ version: '0'
193
+ requirements: []
194
+ rubyforge_project:
195
+ rubygems_version: 2.5.1
196
+ signing_key:
197
+ specification_version: 4
198
+ summary: Manage your development enviroments faster!
199
+ test_files: []