[DRE-commits] [ruby-shellany] 01/02: Import Upstream version 0.0.1
Daisuke Higuchi
dai at moszumanska.debian.org
Wed Nov 15 09:30:31 UTC 2017
This is an automated email from the git hooks/post-receive script.
dai pushed a commit to branch master
in repository ruby-shellany.
commit 15930bdd92353e44dcd9a09c4ae4675e6dcd0cf3
Author: HIGUCHI Daisuke (VDR dai) <dai at debian.org>
Date: Wed Nov 15 18:30:06 2017 +0900
Import Upstream version 0.0.1
---
.gitignore | 14 ++++
.rspec | 2 +
.travis.yml | 13 ++++
Gemfile | 11 +++
LICENSE.txt | 22 ++++++
README.md | 72 +++++++++++++++++++
Rakefile | 13 ++++
lib/shellany.rb | 5 ++
lib/shellany/sheller.rb | 144 ++++++++++++++++++++++++++++++++++++++
lib/shellany/version.rb | 3 +
shellany.gemspec | 22 ++++++
spec/lib/shellany/sheller_spec.rb | 141 +++++++++++++++++++++++++++++++++++++
spec/shellany_spec.rb | 5 ++
spec/spec_helper.rb | 24 +++++++
14 files changed, 491 insertions(+)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..ae3fdc2
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,14 @@
+/.bundle/
+/.yardoc
+/Gemfile.lock
+/_yardoc/
+/coverage/
+/doc/
+/pkg/
+/spec/reports/
+/tmp/
+*.bundle
+*.so
+*.o
+*.a
+mkmf.log
diff --git a/.rspec b/.rspec
new file mode 100644
index 0000000..83e16f8
--- /dev/null
+++ b/.rspec
@@ -0,0 +1,2 @@
+--color
+--require spec_helper
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..ae8f286
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,13 @@
+language: ruby
+bundler_args: --without development
+rvm:
+ - 1.9.3
+ - 2.0.0
+ - 2.1.5
+ - ruby-head
+ - jruby
+ - rbx-2
+matrix:
+ allow_failures:
+ - rvm: rbx
+ - rvm: jruby
diff --git a/Gemfile b/Gemfile
new file mode 100644
index 0000000..50cdb5e
--- /dev/null
+++ b/Gemfile
@@ -0,0 +1,11 @@
+source 'https://rubygems.org'
+
+# Specify your gem's dependencies in shellany.gemspec
+gemspec development_group: :gem_build_tools
+
+gem "rake", "~> 10.0"
+gem 'nenv', "~> 0.1"
+
+group :test do
+ gem "rspec", "~> 3.1"
+end
diff --git a/LICENSE.txt b/LICENSE.txt
new file mode 100644
index 0000000..48d99fc
--- /dev/null
+++ b/LICENSE.txt
@@ -0,0 +1,22 @@
+Copyright (c) 2014 Cezary Baginski
+
+MIT License
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..72a2a84
--- /dev/null
+++ b/README.md
@@ -0,0 +1,72 @@
+# Shellany
+
+Shellany captures command output.
+
+## Features:
+
+- portability (should work on recent JRuby versions)
+- capturing stdout, stderr in a convenient way
+- returning the result in a convenient way
+- detecting if a shell is needed (though incomplete/primitive implementation)
+- prevents running the same command multiple times
+
+## Installation
+
+Add this line to your application's Gemfile:
+
+```ruby
+gem 'shellany'
+```
+
+And then execute:
+
+ $ bundle
+
+Or install it yourself as:
+
+ $ gem install shellany
+
+## Usage
+
+Basic usage:
+
+```ruby
+require 'shellany/sheller'
+
+Shellany::Sheller.stdout("echo abc") # => "abc"
+Shellany::Sheller.stderr("touch /foo") # => "touch: cannot touch ‘/aef’: Permission denied
+Shellany::Sheller.run("false") # => false
+Shellany::Sheller.system("clear") # => clears screen (no capture done)
+```
+
+Using Sheller object:
+
+```ruby
+require 'shellany/sheller'
+
+sh = Shellany::Sheller.new('grep /etc/passed|tail -n 1') # does nothing
+
+sh.stdout # shows output (runs the command since it wasn't run)
+sh.stderr # shows stderr (does not run the command)
+sh.ok? # returns true if exit code was zero (does not run the command)
+```
+
+## Project status
+
+Only developed enough for Guard to run, though pull requests are more than welcome.
+
+Especially for:
+
+- better API
+- better shell detection code
+- better support for various system() arguments
+- better support for redireciton handling
+- better support for shell detection (e.g. Windows)
+
+## Contributing
+
+1. Fork it ( https://github.com/[my-github-username]/shellany/fork )
+2. Create your feature branch (`git checkout -b my-new-feature`)
+3. Commit your changes (`git commit -am 'Add some feature'`)
+4. Push to the branch (`git push origin my-new-feature`)
+5. Create a new Pull Request
diff --git a/Rakefile b/Rakefile
new file mode 100644
index 0000000..a259cc7
--- /dev/null
+++ b/Rakefile
@@ -0,0 +1,13 @@
+require "bundler/gem_tasks"
+
+require 'nenv'
+
+default_tasks = []
+
+require 'rspec/core/rake_task'
+default_tasks << RSpec::Core::RakeTask.new(:spec) do |t|
+ t.verbose = Nenv.ci?
+end
+
+task default: default_tasks.map(&:name)
+
diff --git a/lib/shellany.rb b/lib/shellany.rb
new file mode 100644
index 0000000..869e96d
--- /dev/null
+++ b/lib/shellany.rb
@@ -0,0 +1,5 @@
+require "shellany/version"
+
+module Shellany
+ # Your code goes here...
+end
diff --git a/lib/shellany/sheller.rb b/lib/shellany/sheller.rb
new file mode 100644
index 0000000..8c5a205
--- /dev/null
+++ b/lib/shellany/sheller.rb
@@ -0,0 +1,144 @@
+require "open3"
+
+module Shellany
+ # The Guard sheller abstract the actual subshell
+ # calls and allow easier stubbing.
+ #
+ class Sheller
+ attr_reader :status
+
+ # Creates a new Guard::Sheller object.
+ #
+ # @param [String] args a command to run in a subshell
+ # @param [Array<String>] args an array of command parts to run in a subshell
+ # @param [*String] args a list of command parts to run in a subshell
+ #
+ def initialize(*args)
+ fail ArgumentError, "no command given" if args.empty?
+ @command = args
+ @ran = false
+ end
+
+ # Shortcut for new(command).run
+ #
+ def self.run(*args)
+ new(*args).run
+ end
+
+ # Shortcut for new(command).run.stdout
+ #
+ def self.stdout(*args)
+ new(*args).stdout
+ end
+
+ # Shortcut for new(command).run.stderr
+ #
+ def self.stderr(*args)
+ new(*args).stderr
+ end
+
+ # Runs the command.
+ #
+ # @return [Boolean] whether or not the command succeeded.
+ #
+ def run
+ unless ran?
+ status, output, errors = self.class._system_with_capture(*@command)
+ @ran = true
+ @stdout = output
+ @stderr = errors
+ @status = status
+ end
+
+ ok?
+ end
+
+ # Returns true if the command has already been run, false otherwise.
+ #
+ # @return [Boolean] whether or not the command has already been run
+ #
+ def ran?
+ @ran
+ end
+
+ # Returns true if the command succeeded, false otherwise.
+ #
+ # @return [Boolean] whether or not the command succeeded
+ #
+ def ok?
+ run unless ran?
+
+ @status && @status.success?
+ end
+
+ # Returns the command's output.
+ #
+ # @return [String] the command output
+ #
+ def stdout
+ run unless ran?
+
+ @stdout
+ end
+
+ # Returns the command's error output.
+ #
+ # @return [String] the command output
+ #
+ def stderr
+ run unless ran?
+
+ @stderr
+ end
+
+ # No output capturing
+ #
+ # NOTE: `$stdout.puts system('cls')` on Windows won't work like
+ # it does for on systems with ansi terminals, so we need to be
+ # able to call Kernel.system directly.
+ def self.system(*args)
+ _system_with_no_capture(*args)
+ end
+
+ def self._system_with_no_capture(*args)
+ Kernel.system(*args)
+ result = $?
+ errors = (result == 0) || "Guard failed to run: #{args.inspect}"
+ [result, nil, errors]
+ end
+
+ def self._system_with_capture(*args)
+ # We use popen3, because it started working on recent versions
+ # of JRuby, while JRuby doesn't handle options to Kernel.system
+ args = _shellize_if_needed(args)
+
+ stdout, stderr, status = nil
+ Open3.popen3(*args) do |_stdin, _stdout, _stderr, _thr|
+ stdout = _stdout.read
+ stderr = _stderr.read
+ status = _thr.value
+ end
+
+ [status, stdout, stderr]
+ rescue Errno::ENOENT, IOError => e
+ [nil, nil, "Guard::Sheller failed (#{e.inspect})"]
+ end
+
+ # Only needed on JRUBY, because MRI properly detects ';' and metachars
+ def self._shellize_if_needed(args)
+ return args unless RUBY_PLATFORM == "java"
+ return args unless args.size == 1
+ return args unless /[;<>]/ =~ args.first
+
+ # NOTE: Sheller was originally meant for Guard (which basically only uses
+ # UNIX commands anyway) and JRuby doesn't support options to
+ # Kernel.system (and doesn't automatically shell when there's a
+ # metacharacter in the command).
+ #
+ # So ... I'm assuming /bin/sh exists - if not, PRs are welcome,
+ # because I have no clue what to do if /bin/sh doesn't exist.
+ # (use ENV["RUBYSHELL"] ? Detect cmd.exe ?)
+ ["/bin/sh", "-c", args.first]
+ end
+ end
+end
diff --git a/lib/shellany/version.rb b/lib/shellany/version.rb
new file mode 100644
index 0000000..163a063
--- /dev/null
+++ b/lib/shellany/version.rb
@@ -0,0 +1,3 @@
+module Shellany
+ VERSION = "0.0.1"
+end
diff --git a/shellany.gemspec b/shellany.gemspec
new file mode 100644
index 0000000..981df75
--- /dev/null
+++ b/shellany.gemspec
@@ -0,0 +1,22 @@
+# coding: utf-8
+lib = File.expand_path('../lib', __FILE__)
+$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
+require 'shellany/version'
+
+Gem::Specification.new do |spec|
+ spec.name = "shellany"
+ spec.version = Shellany::VERSION
+ spec.authors = ["Cezary Baginski"]
+ spec.email = ["cezary at chronomantic.net"]
+ spec.summary = %q{Simple, somewhat portable command capturing}
+ spec.description = %q{MRI+JRuby compatible command output capturing}
+ spec.homepage = ""
+ spec.license = "MIT"
+
+ spec.files = `git ls-files -z`.split("\x0")
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
+ spec.require_paths = ["lib"]
+
+ spec.add_development_dependency "bundler", "~> 1.7"
+end
diff --git a/spec/lib/shellany/sheller_spec.rb b/spec/lib/shellany/sheller_spec.rb
new file mode 100644
index 0000000..ba8ef32
--- /dev/null
+++ b/spec/lib/shellany/sheller_spec.rb
@@ -0,0 +1,141 @@
+require "shellany/sheller"
+
+RSpec.describe Shellany::Sheller, :sheller_specs do
+ before do
+ allow(Kernel).to receive(:system) do |args|
+ fail "Stub called with: #{args.inspect}"
+ end
+ end
+
+ subject { described_class }
+
+ context "without a command" do
+ [:new, :run, :stdout, :stderr].each do |meth|
+ describe ".#{meth}" do
+ specify do
+ expect { subject.send(meth) }.
+ to raise_error ArgumentError, "no command given"
+ end
+ end
+ end
+ end
+
+ context "with shell (string) cmd returning success" do
+ let(:cmd) { "ls -l" }
+ let(:output) { "foo.rb\n" }
+ let(:errors) { "" }
+ let(:result) do
+ [instance_double(Process::Status, success?: true), output, errors]
+ end
+
+ context "when constructed with a cmd" do
+ subject { described_class.new(cmd) }
+
+ describe "#run" do
+ it "runs the command given to constructor" do
+ expect(described_class).to receive(:_system_with_capture).
+ with(cmd).and_return(result)
+ subject.run
+ end
+ end
+ end
+ end
+
+ context "with array cmd returning success" do
+ let(:cmd) { %w(ls -l) }
+ let(:output) { "foo.rb\n" }
+ let(:errors) { "" }
+ let(:result) do
+ [instance_double(Process::Status, success?: true), output, errors]
+ end
+
+ describe "when used as class" do
+ describe ".run" do
+ it "runs the given command" do
+ expect(described_class).to receive(:_system_with_capture).
+ with(*cmd) { result }
+ subject.run(*cmd)
+ end
+ end
+
+ describe ".new" do
+ it "does not run anything" do
+ expect(described_class).to_not receive(:_system_with_capture)
+ subject
+ end
+ end
+
+ describe ".stdout" do
+ before do
+ allow(described_class).to receive(:_system_with_capture).
+ with(*cmd) { result }
+ end
+
+ it "runs command and returns output" do
+ expect(subject.stdout(*cmd)).to eq "foo.rb\n"
+ end
+ end
+
+ describe ".stderr" do
+ before do
+ allow(described_class).to receive(:_system_with_capture).
+ with(*cmd) { result }
+ end
+
+ it "runs command and returns errors" do
+ expect(subject.stderr(*cmd)).to eq ""
+ end
+ end
+ end
+
+ context "when constructed with a cmd" do
+ subject { described_class.new(*cmd) }
+
+ it "does not run anything" do
+ expect(described_class).to_not receive(:_system_with_capture)
+ subject
+ end
+
+ describe "#run" do
+ it "runs the command given to constructor" do
+ expect(described_class).to receive(:_system_with_capture).
+ with(*cmd) { result }
+ subject.run
+ end
+ end
+
+ describe "#stdout" do
+ before do
+ allow(described_class).to receive(:_system_with_capture).
+ with(*cmd) { result }
+ end
+
+ it "runs command and returns output" do
+ expect(subject.stdout).to eq "foo.rb\n"
+ end
+ end
+
+ describe "#stderr" do
+ before do
+ allow(described_class).to receive(:_system_with_capture).
+ with(*cmd) { result }
+ end
+
+ it "runs command and returns output" do
+ expect(subject.stderr).to eq ""
+ end
+ end
+
+ describe "#ok?" do
+ before do
+ allow(described_class).to receive(:_system_with_capture).
+ with(*cmd) { result }
+ end
+
+ it "runs command and returns output" do
+ expect(subject).to be_ok
+ end
+ end
+ end
+ end
+end
diff --git a/spec/shellany_spec.rb b/spec/shellany_spec.rb
new file mode 100644
index 0000000..c44d70e
--- /dev/null
+++ b/spec/shellany_spec.rb
@@ -0,0 +1,5 @@
+RSpec.describe Shellany do
+ it 'has a version number' do
+ expect(Shellany::VERSION).not_to be nil
+ end
+end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
new file mode 100644
index 0000000..a79cd38
--- /dev/null
+++ b/spec/spec_helper.rb
@@ -0,0 +1,24 @@
+RSpec.configure do |config|
+ config.expect_with :rspec do |expectations|
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
+ end
+
+ config.mock_with :rspec do |mocks|
+ mocks.verify_partial_doubles = true
+ end
+
+ config.filter_run :focus
+ config.run_all_when_everything_filtered = true
+
+ config.disable_monkey_patching!
+
+ config.warnings = true
+
+ config.default_formatter = 'doc' if config.files_to_run.one?
+
+ # config.profile_examples = 10
+
+ config.order = :random
+
+ Kernel.srand config.seed
+end
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-ruby-extras/ruby-shellany.git
More information about the Pkg-ruby-extras-commits
mailing list