dosh 0.0.1

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.
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,2 @@
1
+ source 'https://rubygems.org'
2
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Jon Williams
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,34 @@
1
+ # Dosh
2
+
3
+ Dev Ops Scripting.
4
+
5
+ ## Installation
6
+
7
+ $ gem install dosh
8
+
9
+ ## Requirements
10
+
11
+ Ruby 1.9.3 or greater.
12
+
13
+ ## Principles
14
+
15
+ 1. Scripts should be standalone.
16
+ 2. DRY, but self-sufficency and explictness are important too.
17
+ 3. Scripts should be re-runnable, with the same outcome. If something changes
18
+ that can't be repeated, check for it and exit early.
19
+
20
+ ## Conventions
21
+
22
+ - "ensure_<state>" checks if a state is true, generating a fault if not.
23
+ - "install_<noun>" installs the given noun, to a completely "ready" state.
24
+ - "meet_<noun>_<state>" takes the noun and attemps to achieve the given state.
25
+
26
+ ## Contributing
27
+
28
+ 1. Fork it
29
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
30
+ 2a. Make sure you have some tests or way of validating the feature.
31
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
32
+ 4. Push to the branch (`git push origin my-new-feature`)
33
+ 5. Create new Pull Request
34
+ 6. ... and thanks!
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/bin/dosh ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+
4
+ dir = File.dirname(File.expand_path(__FILE__))
5
+ require File.join(dir, '..', 'lib', 'dosh.rb')
6
+
7
+ begin
8
+ Dosh::Script.new(true).script(*ARGV)
9
+ rescue Exception => e
10
+ puts e.message
11
+ exit(1)
12
+ end
data/dosh.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'dosh'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "dosh"
8
+ spec.version = Dosh::VERSION
9
+ spec.authors = ["Jon Williams"]
10
+ spec.email = ["jon@jonathannen.com"]
11
+ spec.description = %q{Dev Ops Scripting}
12
+ spec.summary = %q{Dev Ops Scripting}
13
+ spec.homepage = "https://github.com/jonathannen/dosh"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ end
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env dosh -r
2
+ # encoding: utf-8
3
+ # describe: Runs a sample script
4
+
5
+ script "echo A" do
6
+ script "echo B"
7
+ script "echo", "C" do
8
+ script "generic/fail"
9
+ end
10
+ end
data/generic/fail.rb ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+ # describe: Causes the script to fail with an optional message
4
+
5
+ puts "#{ENV['DOSH_INDENT']}#{ARGV.first}" if ARGV.length > 0
6
+ exit(false)
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env dosh -r
2
+ # encoding: utf-8
3
+ # describe: Outputs the version
4
+
5
+ puts "dosh version #{Dosh::VERSION}"
data/lib/dosh.rb ADDED
@@ -0,0 +1,8 @@
1
+ # encoding: utf-8
2
+
3
+ module Dosh
4
+ VERSION = "0.0.1"
5
+ end
6
+
7
+ dir = File.dirname(File.expand_path(__FILE__))
8
+ %w{shelling terminal script platform}.each { |v| require File.join(dir, v) }
data/lib/platform.rb ADDED
@@ -0,0 +1,15 @@
1
+ module Platform
2
+
3
+
4
+ module Ubuntu
5
+
6
+ def platform_prefixes
7
+ # %w{ubuntu/12.04LTS ubuntu debian linux}
8
+ %w{ubuntu generic}
9
+ end
10
+
11
+ end
12
+
13
+ end
14
+
15
+ Dosh::Script.send(:include, Platform::Ubuntu)
data/lib/script.rb ADDED
@@ -0,0 +1,130 @@
1
+ # encoding: utf-8
2
+ require 'benchmark'
3
+
4
+ use_color = !ARGV.include?('--no-color')
5
+
6
+ module Dosh
7
+ EXPLICIT_EXTENSIONS = ['.rb', '.sh']
8
+
9
+ module Injection
10
+
11
+ def script(*args, &block)
12
+ s = Script.new
13
+ s.script(*args, &block)
14
+ end
15
+
16
+ end
17
+
18
+ class Script
19
+ include Shelling
20
+ include Terminal
21
+ @@dosh_dir = File.expand_path(File.join(File.dirname(File.expand_path(__FILE__)), '..'))
22
+
23
+ def initialize(use_require = false)
24
+ @use_require = use_require
25
+ end
26
+
27
+ def candidate_files(filename)
28
+ fn = [filename]
29
+ fn += EXPLICIT_EXTENSIONS.map { |ext| "#{filename}#{ext}"} unless has_explicit_extension?(filename)
30
+ fn += fn.product(platform_prefixes).map { |file, dir| File.join(dir, file) }
31
+ fn.product([@@dosh_dir, Dir.pwd]).map { |file, dir| File.join(dir, file) }.uniq
32
+ end
33
+
34
+ def resolve_file(filename)
35
+ candidate_files(filename).detect { |file| File.exists?(file) }
36
+ end
37
+
38
+ def script(*args, &block)
39
+ if args.first == :meet
40
+ command = args.first
41
+ task = Meet.new
42
+ task.instance_eval(&block)
43
+ else
44
+ filename = nil
45
+ command = args.shift
46
+ if @use_require || !File.exists?(command)
47
+ filename = resolve_file(command)
48
+ end
49
+ task = @use_require ? Require.new(filename, args) : Standard.new(filename, command, args)
50
+ end
51
+
52
+ raise "#{command} failed" unless run_dependency(command, task, &block)
53
+
54
+ rescue Exception => e
55
+ raise e
56
+ end
57
+
58
+ protected
59
+
60
+ def has_explicit_extension?(filename)
61
+ !!EXPLICIT_EXTENSIONS.detect { |ext| filename.end_with?(ext) }
62
+ end
63
+
64
+ def run_dependency(header, task, &block)
65
+ current = ENV['DOSH_INDENT'] || ""
66
+ log_started(header)
67
+ ENV['DOSH_INDENT'] = "#{current} "
68
+ result = task.run(&block)
69
+ ENV['DOSH_INDENT'] = current
70
+
71
+ result ? log_success(header) : log_failure(header)
72
+ result
73
+ rescue Exception => e
74
+ puts e.message
75
+ puts e.backtrace
76
+ ENV['DOSH_INDENT'] = current
77
+ log_failure(header)
78
+ raise e
79
+ end
80
+
81
+ end
82
+
83
+
84
+ class Meet < Script
85
+
86
+ def run
87
+ return true if self.met?
88
+ meet
89
+ self.met?
90
+ end
91
+
92
+ end
93
+
94
+ class Require < Script
95
+
96
+ def initialize(filename, args)
97
+ @filename = filename
98
+ @args = args
99
+ end
100
+
101
+ def run
102
+ raise "File '#{command}' not found" if @filename.nil?
103
+ ARGV.clear
104
+ @args.each { |a| ARGV << a }
105
+ require(@filename)
106
+ end
107
+
108
+ end
109
+
110
+ class Standard < Script
111
+
112
+ def initialize(filename, command, args)
113
+ @filename = filename
114
+ @command = command
115
+ @args = args
116
+ end
117
+
118
+ def run(&block)
119
+ raise "File '#{@filename}' not executable" if !@filename.nil? && !File.executable?(@filename)
120
+ system(@filename || @command, *@args)
121
+ success = $?.success?
122
+ self.instance_eval(&block) if success && block_given?
123
+ success
124
+ end
125
+
126
+ end
127
+
128
+ end
129
+
130
+ Object.send(:include, Dosh::Injection)
data/lib/shelling.rb ADDED
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+ module Dosh
3
+
4
+ module Shelling
5
+
6
+ protected
7
+
8
+ def shell(*args)
9
+ cmd = args * ' '
10
+ `#{cmd}`
11
+ rescue Errno::ENOENT => e
12
+ nil
13
+ end
14
+
15
+ end
16
+
17
+ end
data/lib/terminal.rb ADDED
@@ -0,0 +1,44 @@
1
+ # encoding: utf-8
2
+ module Dosh
3
+
4
+ module Terminal
5
+
6
+ protected
7
+
8
+ COLORS = %w{black red green yellow blue magenta cyan grey}
9
+
10
+ COLORS.each_with_index do |value, i|
11
+ define_method(value.to_sym) { |v| "\e[0;3#{i}m#{v}\e[0m" }
12
+
13
+ if value == 'grey'
14
+ define_method(:gray) { |v| "\e[0;3#{i}m#{v}\e[0m" }
15
+ end
16
+ end
17
+
18
+ def white(v)
19
+ "\e[0m#{v}"
20
+ end
21
+
22
+ def indentation
23
+ ENV['DOSH_INDENT']
24
+ end
25
+
26
+ def log_failure(*args)
27
+ puts "#{indentation}#{red('✘')} #{args * ' '}"
28
+ end
29
+
30
+ def log_general(*args)
31
+ puts "#{indentation}#{args * ' '}"
32
+ end
33
+
34
+ def log_started(*args)
35
+ puts "#{indentation}> #{grey(args * ' ')}"
36
+ end
37
+
38
+ def log_success(*args)
39
+ puts "#{indentation}#{green('✔')} #{args * ' '}"
40
+ end
41
+
42
+ end
43
+
44
+ end
@@ -0,0 +1,3 @@
1
+ #!/bin/sh
2
+
3
+ sudo -n echo 1 > /dev/null
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+ # install_apt_key.rb <recv> [keyserver]
4
+
5
+ recv = ARGV.shift
6
+ keyserver = ARGV.shift || 'hkp://keyserver.ubuntu.com:80'
7
+ puts("The apt-key recv value is required") & exit(1) if recv.nil?
8
+
9
+ def met?(recv)
10
+ `sudo apt-key list | grep #{recv}`.length > 0
11
+ end
12
+
13
+ exit(0) if met?(recv)
14
+ system "sudo apt-key adv --keyserver #{keyserver} --recv #{recv}"
15
+ exit(met?(recv) ? 0 : 1)
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+ # install_apt_source.rb <entry>
4
+
5
+ puts("Entry must be supplied. Something like \"deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen\"") & exit(1) if ARGV.length == 0
6
+ entry = ARGV * ' '
7
+
8
+ def met?(entry)
9
+ `cat /etc/apt/sources.list`.lines.detect { |v| v.strip == entry }
10
+ end
11
+
12
+ exit(0) if met?(entry)
13
+ system "echo '#{entry}' | sudo tee -a /etc/apt/sources.list"
14
+ system "sudo apt-get -y --force-yes update"
15
+ exit(met?(entry) ? 0 : 1)
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env dosh -r
2
+ # encoding: utf-8
3
+ # Installs MongoDB via the 10gen repository.
4
+
5
+ script 'install_apt_key', '7F0CEB10'
6
+ script 'install_apt_source', 'deb http://downloads-distro.mongodb.org/repo/ubuntu-upstart dist 10gen'
7
+ script 'meet_apt_install', 'mongodb-10gen'
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env dosh -r
2
+ # encoding: utf-8
3
+ # install_openjdk [version]
4
+ # version: "7" would install Java7. This is the default.
5
+
6
+ script(:meet) do
7
+ @version = ARGV.shift || "7"
8
+
9
+ def met?
10
+ shell("java -version 2>&1").include?("version \"1.#{@version}.")
11
+ end
12
+
13
+ def meet
14
+ script 'meet_apt_install', "openjdk-#{@version}-jdk"
15
+ end
16
+
17
+ end
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env ruby
2
+ # encoding: utf-8
3
+ # meet_apt_install.rb <package1> [package2..]
4
+
5
+ puts("At least one package is required") & exit(1) if ARGV.length == 0
6
+
7
+ def met?(names)
8
+ !names.detect { |name| `dpkg -s #{name}`; !$?.success? }
9
+ end
10
+
11
+ exit(0) if met?(ARGV)
12
+ system "sudo apt-get -y --force-yes install #{ARGV * ' '}"
13
+ exit(met?(ARGV) ? 0 : 1)
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env dosh -r
2
+ # encoding: utf-8
3
+ # Performs an update and update of aptitude. Will attempt to do so unattended.
4
+
5
+ script 'ensure_passwordless_sudo'
6
+ script "sudo apt-get -y --force-yes update"
7
+ script "sudo apt-get -y --force-yes upgrade"
8
+ script "sudo apt-get -y --force-yes clean"
metadata ADDED
@@ -0,0 +1,101 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: dosh
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jon Williams
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-06-30 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.3'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.3'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: Dev Ops Scripting
47
+ email:
48
+ - jon@jonathannen.com
49
+ executables:
50
+ - dosh
51
+ extensions: []
52
+ extra_rdoc_files: []
53
+ files:
54
+ - .gitignore
55
+ - Gemfile
56
+ - LICENSE.txt
57
+ - README.md
58
+ - Rakefile
59
+ - bin/dosh
60
+ - dosh.gemspec
61
+ - generic/example.rb
62
+ - generic/fail.rb
63
+ - generic/version.rb
64
+ - lib/dosh.rb
65
+ - lib/platform.rb
66
+ - lib/script.rb
67
+ - lib/shelling.rb
68
+ - lib/terminal.rb
69
+ - ubuntu/ensure_passwordless_sudo.sh
70
+ - ubuntu/install_apt_key.rb
71
+ - ubuntu/install_apt_source.rb
72
+ - ubuntu/install_mongodb.rb
73
+ - ubuntu/install_openjdk.rb
74
+ - ubuntu/meet_apt_install.rb
75
+ - ubuntu/meet_apt_updated_and_upgraded.rb
76
+ homepage: https://github.com/jonathannen/dosh
77
+ licenses:
78
+ - MIT
79
+ post_install_message:
80
+ rdoc_options: []
81
+ require_paths:
82
+ - lib
83
+ required_ruby_version: !ruby/object:Gem::Requirement
84
+ none: false
85
+ requirements:
86
+ - - ! '>='
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ required_rubygems_version: !ruby/object:Gem::Requirement
90
+ none: false
91
+ requirements:
92
+ - - ! '>='
93
+ - !ruby/object:Gem::Version
94
+ version: '0'
95
+ requirements: []
96
+ rubyforge_project:
97
+ rubygems_version: 1.8.25
98
+ signing_key:
99
+ specification_version: 3
100
+ summary: Dev Ops Scripting
101
+ test_files: []