rubyshell 1.0.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 90f9ebf7c21774ab58cacb92b34525a94884e2ca087a3cb2307a6f3cf45dde7e
4
+ data.tar.gz: 9a75183f34a96c7755c3b1e2a8057d75b4e113a9c9f860905807090336456850
5
+ SHA512:
6
+ metadata.gz: a86a05dc7ebd4a5eacba2c90a61a03033fe6367e2ace6bef2638a7a606be62c7630b1fada06cf3981c18772cc40680cda953408af8e7c8776155a4dd4644f83b
7
+ data.tar.gz: 9869197ad8eaff074eb74f5eea166bffa2f1ff70f0b28e5f8530230bc74279e186a3d5238df595881b3a1962f10f6db8ce0e98a12c0643d3da9afb901af08fb7
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ ## [Unreleased]
2
+
3
+ ## [0.1.0] - 2025-09-10
4
+
5
+ - Initial release
data/README.md ADDED
@@ -0,0 +1,39 @@
1
+ # Rubysh
2
+
3
+ TODO: Delete this and the text below, and describe your gem
4
+
5
+ Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/rubysh`. To experiment with that code, run `bin/console` for an interactive prompt.
6
+
7
+ ## Installation
8
+
9
+ TODO: Replace `UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG` with your gem name right after releasing it to RubyGems.org. Please do not do it earlier due to security reasons. Alternatively, replace this section with instructions to install your gem from git if you don't plan to release to RubyGems.org.
10
+
11
+ Install the gem and add to the application's Gemfile by executing:
12
+
13
+ $ bundle add UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
14
+
15
+ If bundler is not being used to manage dependencies, install the gem by executing:
16
+
17
+ $ gem install UPDATE_WITH_YOUR_GEM_NAME_IMMEDIATELY_AFTER_RELEASE_TO_RUBYGEMS_ORG
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Development
24
+
25
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
26
+
27
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
28
+
29
+ ## Contributing
30
+
31
+ Bug reports and pull requests are welcome on GitHub at https://github.com/albertalef/rubysh. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/[USERNAME]/rubysh/blob/master/CODE_OF_CONDUCT.md).
32
+
33
+ ## License
34
+
35
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
36
+
37
+ ## Code of Conduct
38
+
39
+ Everyone interacting in the Rubysh project's codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/[USERNAME]/rubysh/blob/master/CODE_OF_CONDUCT.md).
data/Rakefile ADDED
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "bundler/gem_tasks"
4
+ require "rspec/core/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ require "rubocop/rake_task"
9
+
10
+ RuboCop::RakeTask.new
11
+
12
+ task default: %i[spec rubocop]
@@ -0,0 +1,12 @@
1
+
2
+ module RubyShell
3
+ class ChainContext
4
+ def self.method_missing(method_name, *args, &)
5
+ RubyShell::Chainer.new(RubyShell::Command.new(method_name, *(args << {_manual: true}), &))
6
+ end
7
+
8
+ def self.respond_to_missing?(name, _include_private)
9
+ false
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,44 @@
1
+
2
+ module RubyShell
3
+ class Chainer
4
+ def initialize(command)
5
+ @parts = [command]
6
+ end
7
+
8
+ def handle_chain(operator, chainer)
9
+ @parts = [*@parts, operator.to_s, *chainer.parts]
10
+
11
+ self
12
+ end
13
+
14
+ def method_missing(method_name, *args, &)
15
+ if method_name.start_with?(/[^A-Za-z0-9]/)
16
+ handle_chain(method_name, args.first)
17
+ else
18
+ super
19
+ end
20
+ end
21
+
22
+ def respond_to_missing?(name, _include_private)
23
+ false
24
+ end
25
+
26
+ def exec_commands
27
+ %x{#{to_shell}}.chomp
28
+ end
29
+
30
+ def parts
31
+ @parts
32
+ end
33
+
34
+ def to_shell
35
+ parts.map do |part|
36
+ if part.is_a?(RubyShell::Command)
37
+ part.to_shell
38
+ else
39
+ part
40
+ end
41
+ end.join(" ")
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,42 @@
1
+ module RubyShell
2
+ class Command
3
+ def initialize(command_name, *args, &block)
4
+ @command_name = command_name
5
+ @args = args
6
+ @block = block
7
+ end
8
+
9
+ def to_shell
10
+ [@command_name.to_s.gsub("!", ""), *parsed_args].join(" ")
11
+ end
12
+
13
+ def exec_command
14
+ result = `#{to_shell}`.chomp
15
+
16
+ raise "Command Failed" unless $?.success?
17
+
18
+ result
19
+ end
20
+
21
+ def parsed_args
22
+ @args.map do |arg|
23
+ case arg
24
+ when Hash
25
+ arg.map do |k, v|
26
+ next if k.start_with?("_")
27
+
28
+ key = if k.length == 1
29
+ "-#{k}"
30
+ else
31
+ "--#{k}"
32
+ end
33
+
34
+ [key, v.is_a?(TrueClass) ? nil : v].compact.join(" ")
35
+ end.compact
36
+ else
37
+ arg.to_s
38
+ end
39
+ end.flatten
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,12 @@
1
+
2
+ module RubyShell
3
+ class Executor
4
+ def self.method_missing(method_name, *args, &)
5
+ RubyShell::Command.new(method_name, *args, &).exec_command
6
+ end
7
+
8
+ def self.respond_to_missing?(name, _include_private)
9
+ false
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RubyShell
4
+ VERSION = "1.0.0"
5
+ end
data/lib/rubyshell.rb ADDED
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "rubyshell/version"
4
+ require_relative "rubyshell/command"
5
+ require_relative "rubyshell/chainer"
6
+ require_relative "rubyshell/chain_context"
7
+ require_relative "rubyshell/executor"
8
+
9
+ module Kernel
10
+ def sh(&block)
11
+ if !block.nil?
12
+ RubyShell::Executor.class_eval(&block)
13
+ else
14
+ RubyShell::Executor
15
+ end
16
+ end
17
+
18
+ def sh_unsafe_mode(value)
19
+ @sh_unsafe_mode = value
20
+ end
21
+
22
+ def cd(path, &)
23
+ Dir.chdir(path, &)
24
+ end
25
+
26
+ def method_missing(method_name, *args, &)
27
+ if @sh_unsafe_mode
28
+ RubyShell::Executor.send(method_name.to_s.gsub('!', ''), *args, &)
29
+ else
30
+ super
31
+ end
32
+ end
33
+
34
+ def chain(&)
35
+ RubyShell::ChainContext.class_eval(&).exec_commands
36
+ end
37
+ end
metadata ADDED
@@ -0,0 +1,53 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rubyshell
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - albertalef
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies: []
12
+ description: A long description, short for now
13
+ email:
14
+ - albertalef@protonmail.com
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - CHANGELOG.md
20
+ - README.md
21
+ - Rakefile
22
+ - lib/rubyshell.rb
23
+ - lib/rubyshell/chain_context.rb
24
+ - lib/rubyshell/chainer.rb
25
+ - lib/rubyshell/command.rb
26
+ - lib/rubyshell/executor.rb
27
+ - lib/rubyshell/version.rb
28
+ homepage: https://github.com/albertalef/rubyshell
29
+ licenses:
30
+ - MIT
31
+ metadata:
32
+ allowed_push_host: https://rubygems.org
33
+ homepage_uri: https://github.com/albertalef/rubyshell
34
+ source_code_uri: https://github.com/albertalef/rubyshell
35
+ changelog_uri: https://github.com/albertalef/rubyshell
36
+ rdoc_options: []
37
+ require_paths:
38
+ - lib
39
+ required_ruby_version: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ version: 2.6.0
44
+ required_rubygems_version: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ requirements: []
50
+ rubygems_version: 3.7.2
51
+ specification_version: 4
52
+ summary: A rubist way to run shell commands
53
+ test_files: []