bindep 0.0.1

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
+ !binary "U0hBMQ==":
3
+ metadata.gz: 158a70fba74e7159c2f9f1a2fec4ffacb7ce5ae9
4
+ data.tar.gz: 4742cd55e48e01349f82fe97f2ac570b04b94bbb
5
+ SHA512:
6
+ metadata.gz: 6427680d083cf0373284f787e936120b8a6a4ed2d4525201f632434215258236dc197f1de43950f1c8ade05b834adcba7455c0b6e0c98e7cee2d9599d3d9462f
7
+ data.tar.gz: d5364eb79015a159342798713c3f723e2559f3eadfba392cbf326ad443ad2615d8356072a8edba6af15a23b3f2b15657f337f3308381efb4d961aa08c86a948f
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ *.gem
2
+ .bundle
3
+ Bindepfile
4
+ Gemfile.lock
5
+ coverage
6
+ test.rb
7
+ .DS_Store
8
+ tmp
data/.travis.yml ADDED
@@ -0,0 +1,10 @@
1
+ ---
2
+ language: ruby
3
+
4
+ rvm:
5
+ - 1.9.3
6
+ - 2.0.0
7
+ - 2.1.0
8
+ - ruby-head
9
+
10
+ script: bundle exec rspec
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "https://rubygems.org"
2
+
3
+ # Specify your gem"s dependencies in bindep.gemspec
4
+ gemspec
data/Guardfile ADDED
@@ -0,0 +1,3 @@
1
+ guard :rspec, cmd: "bundle exec rspec --color" do
2
+ watch(%r{(.+)\.rb$}){ "spec" }
3
+ end
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Niko Dziemba, niko@dziemba.com
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,139 @@
1
+ # Bindep
2
+
3
+ A simple way to manage binary dependencies for multiple platforms.
4
+
5
+ [![Build Status](https://travis-ci.org/dziemba/bindep.svg?branch=master)](https://travis-ci.org/dziemba/bindep) [![Code Climate](https://codeclimate.com/github/dziemba/bindep.png)](https://codeclimate.com/github/dziemba/bindep)
6
+
7
+ ## Example
8
+
9
+ To install git and complile some less code:
10
+ ``` ruby
11
+
12
+ require 'bindep'
13
+ require 'bindep/library'
14
+
15
+ # prompt user to install git if it is not available, do nothing otherwise
16
+ Bindep.check 'git'
17
+
18
+ # prompt to install less compiler if it is not available,
19
+ # then run it with given parameters
20
+ css_code, stderr = Bindep.run :less, '-x -', less_code
21
+ ```
22
+
23
+ ## Installation
24
+
25
+ Install the gem:
26
+
27
+ ``` shell
28
+ gem install bindep
29
+ ```
30
+
31
+ ## Usage
32
+
33
+ Load the gem:
34
+ ``` ruby
35
+ require "bindep" # core module
36
+ require "bindep/library" # predefined packages (optional)
37
+ ```
38
+
39
+ Check if a package is available and prompt the user to install it otherwise:
40
+ ``` ruby
41
+ Bindep.check 'git'
42
+ ```
43
+
44
+ Run commands (`run` calls `check` automatically):
45
+ ``` ruby
46
+ # syntax
47
+ stdout, stderr, exitcode = Bindep.run :package, stdin, raise_on_error
48
+
49
+ # no exception on failure
50
+ css_code, stderr, exitcode = Bindep.run :less, '-x -', less_code, false
51
+ css_code = '' unless exitcode.zero?
52
+
53
+ # raise on failure
54
+ begin
55
+ output, stderr = Bindep.run :git, 'status'
56
+ puts output
57
+ rescue RuntimeError
58
+ puts 'Git failed!'
59
+ end
60
+
61
+ ```
62
+
63
+ Define new packages and check/install them:
64
+ ``` ruby
65
+ Bindep.define(:npm) do |i|
66
+ i.command = "npm"
67
+ i.apt = [ "nodejs", "npm" ]
68
+ i.brew = "node"
69
+ end
70
+
71
+ Bindep.define(:lessc) do |i|
72
+ i.command = "lessc"
73
+ i.npm = "lessc"
74
+ i.depends = [ :npm ]
75
+ end
76
+
77
+ Bindep.check :lessc
78
+ ```
79
+
80
+ Combine `define` and `check`:
81
+ ``` ruby
82
+
83
+ Bindep.check(:git) do |i|
84
+ i.command = "npm"
85
+ i.apt = "git-core"
86
+ i.brew = "git"
87
+ i.yum = "git-core"
88
+ end
89
+ ```
90
+
91
+ ## Command Line Usage
92
+
93
+ Create a `Bindepfile` in your project root using the same syntax:
94
+ ``` ruby
95
+ check 'less'
96
+
97
+ check(:git) do |i|
98
+ i.command = "npm"
99
+ i.apt = "git-core"
100
+ i.brew = "git"
101
+ i.yum = "git-core"
102
+ end
103
+ ```
104
+
105
+ and execute it by running `bindep` in your shell.
106
+
107
+
108
+ ## Configuration
109
+ Add any of the following lines to your code before running any bindep commands.
110
+
111
+ ``` ruby
112
+ # Abort if command is not found, do not try to install.
113
+ Bindep.no_install = true
114
+
115
+ # Do not ask user for confirmation before installing.
116
+ Bindep.no_confirm_before_install = true
117
+
118
+ # Do not output error messages and exit process but raise exceptions instead.
119
+ Bindep.silent_exceptions = true
120
+ ```
121
+
122
+ You can also set these in your `Bindepfile` by adding any of the following before the commands:
123
+ ``` ruby
124
+ @no_install = true
125
+ @no_confirm_before_install = true
126
+ @silent_exceptions = true
127
+ ```
128
+
129
+ ## Contributing
130
+
131
+ I really appreciate any input, either code or new library entries, so please:
132
+
133
+ 1. Fork it ( https://github.com/dziemba/bindep/fork )
134
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
135
+ 3. Commit your changes (`git commit -am "Add some feature"`)
136
+ 4. Push to the branch (`git push origin my-new-feature`)
137
+ 5. Create a new Pull Request
138
+
139
+
data/bin/bindep ADDED
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'bindep'
4
+ require 'bindep/library'
5
+
6
+ if $1 == "--help"
7
+ puts "Usage: $0 [Bindepfile]"
8
+ exit 0
9
+ end
10
+
11
+ Bindep.load_file($1 || 'Bindepfile')
data/bindep.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path("../lib", __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require "bindep/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "bindep"
8
+ spec.version = Bindep::VERSION
9
+ spec.authors = ["Niko Dziemba"]
10
+ spec.email = ["niko@dziemba.com"]
11
+ spec.summary = "A simple way to manage binary dependencies for multiple platforms."
12
+ spec.description = spec.summary
13
+ spec.homepage = "https://github.com/dziemba/bindep"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
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"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec"
24
+ spec.add_development_dependency "guard-rspec"
25
+ spec.add_development_dependency "simplecov"
26
+ end
data/lib/bindep.rb ADDED
@@ -0,0 +1,10 @@
1
+ require "open3"
2
+
3
+ require "bindep/version"
4
+ require "bindep/error"
5
+ require "bindep/helpers"
6
+ require "bindep/os"
7
+ require "bindep/core"
8
+ require "bindep/item"
9
+ require "bindep/context"
10
+
@@ -0,0 +1,91 @@
1
+ module Bindep
2
+ class Context
3
+ attr_accessor :no_install, :no_confirm_before_install, :silent_exceptions
4
+
5
+ # Create a new Bindep context with its own options and item registry.
6
+ def initialize
7
+ @registry = {}
8
+
9
+ @no_install = false
10
+ @no_confirm_before_install = false
11
+ @silent_exceptions = false
12
+
13
+ unless Helpers.which_test
14
+ error "Command detection does not work on your system. Bindep cannot run on your system!"
15
+ end
16
+ end
17
+
18
+ # Define a new item.
19
+ def define(id, &block)
20
+ item = Item.new(id)
21
+ yield item
22
+
23
+ @registry[item.id] = item
24
+ end
25
+
26
+ # Check if a given item is installed, can also define item beforehand if block is given.
27
+ def check(id, force_install = false, &block)
28
+ item = block_given? ? define(id, &block) : get_item(id)
29
+
30
+ [ item.depends ].flatten.compact.each { |dep| check dep }
31
+
32
+ install item if force_install || (item.local_command.nil? && !no_install)
33
+ end
34
+
35
+ # Runs the specified command with the given arguments.
36
+ def run(id, args = [], stdin = nil, raise_on_failure = true)
37
+ check id
38
+
39
+ cmd_string = "#{get_item(id).local_command} #{[ args ].flatten.join(" ")}".strip
40
+ Helpers.cmd cmd_string, stdin, raise_on_failure
41
+ end
42
+
43
+ # Gets an item from the registry.
44
+ def get_item(id)
45
+ @registry[id.to_sym] || raise(Error, "Cannot find item '#{id.to_sym}' in context!")
46
+ end
47
+
48
+ private
49
+ def pre_install(item)
50
+ if no_install
51
+ error "Cannot find command for '#{item.id}' and installation is deactivated. "\
52
+ "Please install manually."
53
+ end
54
+
55
+ if item.install_command.nil?
56
+ error "Cannot find installation instructions for '#{item.id}'. "\
57
+ "Please install manually."
58
+ end
59
+
60
+ unless no_confirm_before_install
61
+ puts "[Bindep] Command '#{item.id}' is not installed. "\
62
+ "Do you want to run the following command? (y/n)"
63
+ end
64
+
65
+ puts "[Bindep] $ #{item.install_command}\n"
66
+
67
+ unless no_confirm_before_install
68
+ error "Aborting." unless gets.downcase.strip == 'y'
69
+ end
70
+ end
71
+
72
+ def install(item)
73
+ pre_install item
74
+
75
+ Helpers.cmd_interactive item.install_command
76
+
77
+ unless item.local_command true
78
+ error "Installation for '#{item.id}' failed. Please install manually."
79
+ end
80
+ end
81
+
82
+ def error(message = nil)
83
+ exception = Error.new message
84
+
85
+ raise exception if silent_exceptions
86
+
87
+ puts exception.to_s
88
+ exit 1
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,16 @@
1
+ module Bindep
2
+ # Get the global context instance, create a new one on first call.
3
+ def self.context
4
+ @context ||= Context.new
5
+ end
6
+
7
+ # Evaluate a Bindepfile in the global context.
8
+ def self.load_file(filename = 'Bindepfile')
9
+ context.instance_eval File.read(filename)
10
+ end
11
+
12
+ # Redirect all other method calls to the global context instance.
13
+ def self.method_missing(method, *args, &block)
14
+ context.send method, *args, &block
15
+ end
16
+ end
@@ -0,0 +1,7 @@
1
+ module Bindep
2
+ class Error < RuntimeError
3
+ def to_s
4
+ "[Bindep] #{super.to_s}"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,36 @@
1
+ module Bindep
2
+ module Helpers
3
+ # Run a command, supply stdin and capture stdout and stderr.
4
+ def self.cmd(command, stdin = nil, raise_on_error = true)
5
+ stdout, stderr, status = Open3.capture3 command, stdin_data: stdin, binmode: true
6
+
7
+ if raise_on_error && (status.exitstatus != 0 || stderr =~ /error/i)
8
+ raise RuntimeError, "Command '#{command}' returned status #{status.exitstatus}"
9
+ end
10
+
11
+ [ stdout, stderr, status.exitstatus ]
12
+ end
13
+
14
+ # Run a command interactively, return exit status
15
+ def self.cmd_interactive(command, raise_on_error = true)
16
+ system command
17
+
18
+ if raise_on_error && !$?.exitstatus.zero?
19
+ raise RuntimeError, "Command '#{command}' returned status #{$?.exitstatus}"
20
+ end
21
+
22
+ $?.exitstatus
23
+ end
24
+
25
+ # Check if a shell command exists (using "which").
26
+ def self.command_exists?(cmd)
27
+ _, _, status = Helpers.cmd "which #{cmd.strip}", nil, false
28
+ status.zero?
29
+ end
30
+
31
+ # Check if "which" command is available and works correctly.
32
+ def self.which_test
33
+ command_exists?("which") && !command_exists?("foo_bar_command_does_not_exist")
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,35 @@
1
+ module Bindep
2
+ class Item
3
+ attr_reader :id
4
+ attr_accessor :command, :apt, :yum, :brew, :npm, :rubygem, :install_command, :depends
5
+
6
+ def initialize(id)
7
+ @id = id.to_sym
8
+ end
9
+
10
+ # Get the command for the current system. Return nil if command is not available.
11
+ def local_command(reset = false)
12
+ @local_command = nil if reset
13
+
14
+ @local_command ||= [ command ].flatten.compact.find do |cmd|
15
+ Helpers.command_exists? cmd
16
+ end
17
+ end
18
+
19
+ # Get the installation commands for the current system as a single string.
20
+ # Return nil if there is no command that fits the current system.
21
+ def install_command
22
+ list = []
23
+
24
+ list << OS.apt_install(apt) if apt && OS.apt?
25
+ list << OS.yum_install(yum) if yum && OS.yum?
26
+ list << OS.brew_install(brew) if brew && OS.brew?
27
+ list << OS.npm_install(npm) if npm && OS.npm?
28
+ list << OS.rubygem_install(rubygem) if rubygem && OS.rubygem?
29
+ list << @install_command if @install_command
30
+
31
+ list.empty? ? nil : list.join("; ")
32
+ end
33
+ end
34
+ end
35
+
@@ -0,0 +1,53 @@
1
+ module Bindep
2
+
3
+ # Example, for testing.
4
+ define(:does_not_exist) do |i|
5
+ i.command = 'does_not_exist'
6
+ # i.install_command = 'echo "This should install the command"'
7
+ end
8
+
9
+ define(:nmap) do |i|
10
+ i.command = 'nmap'
11
+ i.apt = 'nmap'
12
+ i.yum = 'nmap'
13
+ i.brew = 'nmap'
14
+ end
15
+
16
+ define(:git) do |i|
17
+ i.command = 'git'
18
+ i.apt = 'git-core'
19
+ i.yum = 'git-core'
20
+ i.brew = 'git'
21
+ end
22
+
23
+ define(:nodejs) do |i|
24
+ i.command = %w(nodejs node)
25
+ i.apt = %w(nodejs npm)
26
+ i.yum = %w(nodejs npm)
27
+ i.brew = 'node'
28
+ end
29
+
30
+ define(:npm) do |i|
31
+ i.command = 'npm'
32
+ i.depends = 'nodejs'
33
+ end
34
+
35
+ define(:less) do |i|
36
+ i.command = 'lessc'
37
+ i.npm = 'less'
38
+ i.depends = 'npm'
39
+ end
40
+
41
+ define(:uglifyjs) do |i|
42
+ i.command = 'uglifyjs'
43
+ i.npm = 'uglify-js'
44
+ i.depends = 'npm'
45
+ end
46
+
47
+ define(:jshint) do |i|
48
+ i.command = 'jshint'
49
+ i.npm = 'jshint'
50
+ i.depends = 'npm'
51
+ end
52
+
53
+ end
data/lib/bindep/os.rb ADDED
@@ -0,0 +1,35 @@
1
+ module Bindep
2
+ module OS
3
+ LIST = {
4
+ :brew => "brew install",
5
+ :apt => "apt-get install -y",
6
+ :yum => "yum install -y",
7
+ :npm => "npm install -g",
8
+ :rubygem => "gem install",
9
+ }
10
+ @command_exists_cache = {}
11
+
12
+ class << self
13
+ LIST.each_pair do |method, install_cmd|
14
+ check_cmd = install_cmd.split(" ").first
15
+
16
+ # Create a "handler?" method which checks if the specified package handler is available.
17
+ define_method("#{method}?") do
18
+ return @command_exists_cache[method] unless @command_exists_cache[method].nil?
19
+ @command_exists_cache[method] = Helpers.command_exists? check_cmd
20
+ end
21
+
22
+ # Create a "handler_install" method which returns the install string for the given handler.
23
+ define_method("#{method}_install") do |package|
24
+ "#{sudo} #{install_cmd} #{package}".strip
25
+ end
26
+ end
27
+ end
28
+
29
+ private
30
+ def self.sudo
31
+ # homebrew does not need sudo for itself and other package managers
32
+ brew? ? "" : "sudo"
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,3 @@
1
+ module Bindep
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,195 @@
1
+ require "spec_helper"
2
+
3
+ describe Bindep::Context do
4
+ let (:context) { Bindep::Context.new }
5
+ let (:item) { context.define(:testitem) { } }
6
+
7
+ it "fails on init if which tests fails" do
8
+ expect(Bindep::Helpers).to receive(:which_test).once.and_return(false)
9
+
10
+ expect_any_instance_of(Bindep::Context).to receive(:error)
11
+ Bindep::Context.new
12
+ end
13
+
14
+ it "fails on getting invalid item" do
15
+ expect do
16
+ context.get_item(:invalid)
17
+ end.to raise_error Bindep::Error, "[Bindep] Cannot find item 'invalid' in context!"
18
+ end
19
+
20
+ it "can define and get a new item" do
21
+ item = context.define(:testid) do |i|
22
+ i.command = "cmd"
23
+ end
24
+
25
+ expect(item).to be_a Bindep::Item
26
+ expect(item.id).to eq :testid
27
+ expect(item.command).to eq "cmd"
28
+
29
+ expect(context.get_item(:testid)).to eq item
30
+ end
31
+
32
+ context "checking" do
33
+ it "fails for an non-existing item and no block" do
34
+ expect do
35
+ context.check :testid
36
+ end.to raise_error Bindep::Error
37
+ end
38
+
39
+ it "work for an non-existing item and a defining block" do
40
+ expect(context).to receive(:install).once
41
+
42
+ context.check(:testid) do |i|
43
+ i.command = "testcmd"
44
+ end
45
+
46
+ expect(context.get_item(:testid).command).to eq "testcmd"
47
+ end
48
+
49
+ it "works for an existing installed item" do
50
+ context.define(:testid) { |i| i.command = "grep" }
51
+
52
+ context.check :testid
53
+ end
54
+
55
+ [ false, true ].each do |no_install|
56
+ context "with no_install #{no_install}" do
57
+ before :each do
58
+ context.no_install = no_install
59
+ end
60
+
61
+ it "works for an existing installed item with force install" do
62
+ item = context.define(:testid) { |i| i.command = "grep" }
63
+
64
+ expect(context).to receive(:install).with(item).once
65
+ context.check :testid, true
66
+ end
67
+
68
+ it "works for an existing but not installed item" do
69
+ item = context.define(:testid) { |i| i.command = "foo_bar_not_existing" }
70
+
71
+ expect(context).to receive(:install).with(item).exactly(no_install ? 0:1).times
72
+ context.check :testid
73
+ end
74
+ end
75
+ end
76
+
77
+ it "works with dependencies" do
78
+ dep1 = context.define(:dep1) {}
79
+ dep2 = context.define(:dep2) {}
80
+ dep3 = context.define(:dep3) { |i| i.depends = "dep2" }
81
+ item = context.define(:item) { |i| i.depends = [ "dep3", "dep1" ] }
82
+
83
+ [ dep2, dep3, dep1, item ].each do |i|
84
+ expect(context).to receive(:install).with(i).once
85
+ end
86
+
87
+ context.check :item
88
+ end
89
+ end
90
+
91
+ context "pre_install" do
92
+ it "aborts if no_install is set" do
93
+ context.no_install = true
94
+
95
+ expect(context).to receive(:error).with(/deactivated/).and_raise(Bindep::Error)
96
+
97
+ expect do
98
+ context.send :pre_install, item
99
+ end.to raise_error Bindep::Error
100
+ end
101
+
102
+ it "aborts if no install command is found" do
103
+ str = /Cannot find installation instructions/
104
+ expect(context).to receive(:error).with(str).and_raise(Bindep::Error)
105
+
106
+ expect do
107
+ context.send :pre_install, item
108
+ end.to raise_error Bindep::Error
109
+ end
110
+
111
+ it "outputs command and does nothing else if no_confirm_before_install is set" do
112
+ context.no_confirm_before_install = true
113
+
114
+ item.install_command = "my_install -b"
115
+
116
+ expect(context).to receive(:puts).with("[Bindep] $ my_install -b\n")
117
+
118
+ context.send :pre_install, item
119
+ end
120
+
121
+ it "asks for confirmation" do
122
+ item.install_command = "my_install -b"
123
+
124
+ expect(context).to receive(:puts).with(/'testitem' is not installed/)
125
+ expect(context).to receive(:puts).with("[Bindep] $ my_install -b\n")
126
+ expect(context).to receive(:gets).once.and_return("y\n")
127
+
128
+ context.send :pre_install, item
129
+ end
130
+
131
+ it "asks for confirmation and aborts if user wants" do
132
+ item.install_command = "my_install -b"
133
+
134
+ expect(context).to receive(:puts).twice
135
+ expect(context).to receive(:gets).once.and_return("bla\n")
136
+ expect(context).to receive(:error).with(/Aborting/)
137
+
138
+ context.send :pre_install, item
139
+ end
140
+ end
141
+
142
+ context "install" do
143
+ it "runs installation command (success)" do
144
+ item.install_command = "echo 1"
145
+ item.command = "cat"
146
+
147
+ expect(context).to receive(:pre_install).with(item)
148
+ expect(Bindep::Helpers).to receive(:system).with("echo 1")
149
+
150
+ context.send :install, item
151
+ end
152
+
153
+ it "runs installation command (fail)" do
154
+ item.install_command = "echo 1"
155
+
156
+ expect(context).to receive(:pre_install).with(item)
157
+ expect(Bindep::Helpers).to receive(:system).with("echo 1")
158
+ expect(context).to receive(:error).with(/Installation for 'testitem' failed/)
159
+
160
+ context.send :install, item
161
+ end
162
+ end
163
+
164
+ it "runs a command" do
165
+ item.command = "mycmd"
166
+
167
+ expect(item).to receive(:local_command).at_least(:once).and_return("mycmd")
168
+ expect(Bindep::Helpers).to receive(:cmd).with("mycmd --myparam mydoc", 'stdin', false)
169
+ expect(Bindep::Helpers).to receive(:cmd).with("mycmd", nil, true)
170
+ expect(Bindep::Helpers).to receive(:cmd).with("mycmd --myparam mydoc", nil, false)
171
+
172
+ context.run :testitem, [ "--myparam", "mydoc" ], 'stdin', false
173
+ context.run :testitem, "", nil, true
174
+ context.run :testitem, "--myparam mydoc", nil, false
175
+ end
176
+
177
+ context "error handler" do
178
+ it 'prints exception and exits' do
179
+ expect(context).to receive(:puts).with("[Bindep] My message").once
180
+
181
+ expect do
182
+ context.send :error, "My message"
183
+ end.to raise_error SystemExit
184
+ end
185
+
186
+ it 'prints raises exception if silent_exceptions is true' do
187
+ context.silent_exceptions = true
188
+
189
+ expect do
190
+ context.send :error, "My message"
191
+ end.to raise_error Bindep::Error, "[Bindep] My message"
192
+ end
193
+ end
194
+ end
195
+
@@ -0,0 +1,36 @@
1
+ require "spec_helper"
2
+
3
+ describe Bindep do
4
+ it "exposes a singleton context instance" do
5
+ context = Bindep.context
6
+
7
+ expect(context).to be_a Bindep::Context
8
+ expect(Bindep.context).to eq context
9
+ end
10
+
11
+ it "evaluates a Bindepfile" do
12
+ file = Tempfile.new('Bindep')
13
+ file.write "check 'test1'\ncheck 'test2'"
14
+ file.close
15
+
16
+ context = Bindep.context
17
+
18
+ expect(context).to receive(:check).with("test1")
19
+ expect(context).to receive(:check).with("test2")
20
+
21
+ Bindep.load_file file.path
22
+
23
+ file.unlink
24
+ end
25
+
26
+ it "sends all method calls to the singleton context instance" do
27
+ context = Bindep.context
28
+
29
+ expect(context).to receive(:define) do |arg, &blk|
30
+ expect(blk.call).to eq :blocktest
31
+ expect(arg).to eq :test1
32
+ end
33
+
34
+ Bindep.define(:test1) { :blocktest }
35
+ end
36
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ describe Bindep::Helpers do
4
+ context '.cmd_interactive' do
5
+ it 'works on success' do
6
+ expect(Bindep::Helpers.cmd_interactive 'true').to eq 0
7
+ end
8
+
9
+ it 'works on failure' do
10
+ expect(Bindep::Helpers.cmd_interactive 'false', false).to eq 1
11
+ end
12
+
13
+ it 'raises on failure' do
14
+ expect do
15
+ Bindep::Helpers.cmd_interactive 'false'
16
+ end.to raise_error RuntimeError, "Command 'false' returned status 1"
17
+ end
18
+ end
19
+
20
+ context '.cmd' do
21
+ it 'works on success' do
22
+ stdout, stderr, status = Bindep::Helpers.cmd 'cat', 'test'
23
+
24
+ expect(stdout).to eq 'test'
25
+ expect(stderr).to eq ''
26
+ expect(status).to eq 0
27
+ end
28
+
29
+ it 'works on failure' do
30
+ stdout, stderr, status = Bindep::Helpers.cmd 'false', nil, false
31
+ expect(status).to eq 1
32
+ end
33
+
34
+ it 'fails on failure' do
35
+ expect do
36
+ Bindep::Helpers.cmd 'false'
37
+ end.to raise_error RuntimeError, "Command 'false' returned status 1"
38
+ end
39
+ end
40
+
41
+ it 'has .command_exists?' do
42
+ expect(Bindep::Helpers.command_exists? 'cat').to eq true
43
+ expect(Bindep::Helpers.command_exists? 'does_not_exists').to eq false
44
+ end
45
+
46
+ it 'has working which_test' do
47
+ expect(Bindep::Helpers.which_test).to eq true
48
+ end
49
+ end
50
+
@@ -0,0 +1,151 @@
1
+ require "spec_helper"
2
+
3
+ describe Bindep::Item do
4
+ let (:item) { Bindep::Item.new :testid }
5
+
6
+ it "can create a valid item and has read and writable properties" do
7
+ item.command = "command"
8
+ item.apt = "apt"
9
+ item.brew = "brew"
10
+ item.depends = [ :dep1, :dep2 ]
11
+
12
+ expect(item.id).to eq :testid
13
+ expect(item.command).to eq "command"
14
+ expect(item.apt).to eq "apt"
15
+ expect(item.brew).to eq "brew"
16
+ expect(item.depends).to eq [ :dep1, :dep2 ]
17
+ end
18
+
19
+ it "can converts it to symbol" do
20
+ item = Bindep::Item.new "testid"
21
+
22
+ expect(item.id).to eq :testid
23
+ end
24
+
25
+ # tests in this context rely on sensible defaults (e.g. grep, cat are available, foo_bar_not_here is not)
26
+ context "command selection" do
27
+ it "works for empty command" do
28
+ item.command = nil
29
+
30
+ expect(item.local_command).to be_nil
31
+ end
32
+
33
+ it "does not change @command" do
34
+ item.command = [ "not_here", "cat" ]
35
+
36
+ item.local_command
37
+
38
+ expect(item.command).to eq [ "not_here", "cat" ]
39
+ end
40
+
41
+ it "works with a single correct command" do
42
+ item.command = "grep"
43
+
44
+ expect(item.local_command).to eq "grep"
45
+ end
46
+
47
+ it "works with a single wrong command" do
48
+ item.command = "foo_bar_not_here"
49
+
50
+ expect(item.local_command).to eq nil
51
+ end
52
+
53
+ it "works with a two correct commands" do
54
+ item.command = [ "grep", "cat" ]
55
+
56
+ expect(item.local_command).to eq "grep"
57
+ end
58
+
59
+ it "works with a one correct command at first position" do
60
+ item.command = [ "cat", "foo_bar_not_here" ]
61
+
62
+ expect(item.local_command).to eq "cat"
63
+ end
64
+
65
+ it "works with a one correct command at second position" do
66
+ item.command = [ "foo_bar_not_here", "cat", "foo_bar_not_here_two" ]
67
+
68
+ expect(item.local_command).to eq "cat"
69
+ end
70
+
71
+ it "does not run twice" do
72
+ item.command = [ "foo_bar_not_here", "cat" ]
73
+
74
+ expect(item.local_command).to eq "cat"
75
+
76
+ item.command = "foo_bar_not_here"
77
+
78
+ expect(item.local_command).to eq "cat"
79
+ expect(item.command).to eq "foo_bar_not_here"
80
+ end
81
+
82
+ it "runs again if reset parameter is given" do
83
+ item.command = [ "foo_bar_not_here", "cat" ]
84
+
85
+ expect(item.local_command).to eq "cat"
86
+
87
+ item.command = "grep"
88
+
89
+ expect(item.local_command(true)).to eq "grep"
90
+ end
91
+ end
92
+
93
+ # cannot cover all tests (would be 2^n test cases, n = package handler count),
94
+ # so we choose a few general ones and edge cases
95
+ context "install commands" do
96
+ it "works for no packages given" do
97
+ expect(item.install_command).to be_nil
98
+ end
99
+
100
+ it "works for custom command given" do
101
+ cmd = "my_installer -fmgu my_package"
102
+ item.install_command = cmd
103
+
104
+ expect(item.install_command).to eq cmd
105
+ end
106
+
107
+ it "works all commands given and all available" do
108
+ Bindep::OS.instance_variable_set :@command_exists_cache, {
109
+ apt: true, npm: true, brew: true, yum: true, rubygem: true
110
+ }
111
+
112
+ item.apt = "p_apt"
113
+ item.npm = "p_npm"
114
+ item.yum = "p_yum"
115
+ item.brew = "p_brew"
116
+ item.rubygem = "p_gem"
117
+ item.install_command = "my package"
118
+
119
+ results = [
120
+ Bindep::OS.apt_install("p_apt"),
121
+ Bindep::OS.yum_install("p_yum"),
122
+ Bindep::OS.brew_install("p_brew"),
123
+ Bindep::OS.npm_install("p_npm"),
124
+ Bindep::OS.rubygem_install("p_gem"),
125
+ "my package",
126
+ ]
127
+
128
+ expect(item.install_command).to eq results.join("; ")
129
+ end
130
+
131
+ it "works some commands given and some available" do
132
+ Bindep::OS.instance_variable_set :@command_exists_cache, {
133
+ apt: true, npm: true, brew: false, yum: true, rubygem: false
134
+ }
135
+
136
+ item.apt = "p_apt"
137
+ item.npm = nil
138
+ item.yum = "p_yum"
139
+ item.brew = "p_brew"
140
+ item.rubygem = "p_gem"
141
+ item.install_command = nil
142
+
143
+ results = [
144
+ Bindep::OS.apt_install("p_apt"),
145
+ Bindep::OS.yum_install("p_yum"),
146
+ ]
147
+
148
+ expect(item.install_command).to eq results.join("; ")
149
+ end
150
+ end
151
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'Bindep Library' do
4
+ it 'loads the library file successfully' do
5
+ require 'bindep/library'
6
+ end
7
+ end
@@ -0,0 +1,55 @@
1
+ require "spec_helper"
2
+
3
+ describe Bindep::OS do
4
+ HAVE_LIST = {
5
+ "brew?" => "brew",
6
+ "apt?" => "apt-get",
7
+ "yum?" => "yum",
8
+ "npm?" => "npm",
9
+ "rubygem?" => "gem",
10
+ }
11
+
12
+ INSTALL_LIST = {
13
+ "brew_install" => "brew install pkg",
14
+ "apt_install" => "apt-get install -y pkg",
15
+ "yum_install" => "yum install -y pkg",
16
+ "npm_install" => "npm install -g pkg",
17
+ "rubygem_install" => "gem install pkg",
18
+ }
19
+
20
+ before :each do
21
+ Bindep::OS.instance_variable_set(:@command_exists_cache, {})
22
+ end
23
+
24
+ HAVE_LIST.each_pair do |method, command|
25
+ it "has a #{method} method which caches result" do
26
+ expect(Bindep::Helpers).to receive(:command_exists?).with(command).once.and_return(false)
27
+
28
+ 2.times { Bindep::OS.send method.to_sym }
29
+ end
30
+ end
31
+
32
+ [ true, false ].each do |sudo|
33
+ sudo_string = sudo ? "sudo" : ""
34
+
35
+ INSTALL_LIST.each_pair do |method, command|
36
+ it "has a corrent #{method} method with sudo #{sudo}" do
37
+ expect(Bindep::OS).to receive(:sudo).and_return(sudo_string)
38
+
39
+ expect(Bindep::OS.send(method.to_sym, "pkg")).to eq "#{sudo_string} #{command}".strip
40
+ end
41
+ end
42
+ end
43
+
44
+ it "requires sudo if no brew is available (e.g. not on mac os)" do
45
+ expect(Bindep::OS).to receive(:brew?).and_return(false)
46
+
47
+ expect(Bindep::OS.sudo).to eq "sudo"
48
+ end
49
+
50
+ it "requires no sudo if brew is available" do
51
+ expect(Bindep::OS).to receive(:brew?).and_return(true)
52
+
53
+ expect(Bindep::OS.sudo).to eq ""
54
+ end
55
+ end
@@ -0,0 +1,8 @@
1
+ require "simplecov"
2
+
3
+ SimpleCov.coverage_dir "coverage"
4
+ SimpleCov.start
5
+
6
+ require 'tempfile'
7
+
8
+ require "bindep"
metadata ADDED
@@ -0,0 +1,146 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bindep
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Niko Dziemba
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-06-10 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: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ! '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '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: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: guard-rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ! '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: simplecov
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
+ description: A simple way to manage binary dependencies for multiple platforms.
84
+ email:
85
+ - niko@dziemba.com
86
+ executables:
87
+ - bindep
88
+ extensions: []
89
+ extra_rdoc_files: []
90
+ files:
91
+ - .gitignore
92
+ - .travis.yml
93
+ - Gemfile
94
+ - Guardfile
95
+ - LICENSE
96
+ - README.md
97
+ - bin/bindep
98
+ - bindep.gemspec
99
+ - lib/bindep.rb
100
+ - lib/bindep/context.rb
101
+ - lib/bindep/core.rb
102
+ - lib/bindep/error.rb
103
+ - lib/bindep/helpers.rb
104
+ - lib/bindep/item.rb
105
+ - lib/bindep/library.rb
106
+ - lib/bindep/os.rb
107
+ - lib/bindep/version.rb
108
+ - spec/bindep/context_spec.rb
109
+ - spec/bindep/core_spec.rb
110
+ - spec/bindep/helpers_spec.rb
111
+ - spec/bindep/item_spec.rb
112
+ - spec/bindep/library_spec.rb
113
+ - spec/bindep/os_spec.rb
114
+ - spec/spec_helper.rb
115
+ homepage: https://github.com/dziemba/bindep
116
+ licenses:
117
+ - MIT
118
+ metadata: {}
119
+ post_install_message:
120
+ rdoc_options: []
121
+ require_paths:
122
+ - lib
123
+ required_ruby_version: !ruby/object:Gem::Requirement
124
+ requirements:
125
+ - - ! '>='
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
128
+ required_rubygems_version: !ruby/object:Gem::Requirement
129
+ requirements:
130
+ - - ! '>='
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ requirements: []
134
+ rubyforge_project:
135
+ rubygems_version: 2.2.2
136
+ signing_key:
137
+ specification_version: 4
138
+ summary: A simple way to manage binary dependencies for multiple platforms.
139
+ test_files:
140
+ - spec/bindep/context_spec.rb
141
+ - spec/bindep/core_spec.rb
142
+ - spec/bindep/helpers_spec.rb
143
+ - spec/bindep/item_spec.rb
144
+ - spec/bindep/library_spec.rb
145
+ - spec/bindep/os_spec.rb
146
+ - spec/spec_helper.rb