[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