yap-shell 0.7.1 → 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +9 -24
  3. data/Gemfile +1 -5
  4. data/LICENSE.txt +17 -18
  5. data/README.md +28 -14
  6. data/Rakefile +4 -1
  7. data/bin/yap +1 -3
  8. data/lib/.gitkeep +0 -0
  9. data/yap-shell.gemspec +12 -11
  10. metadata +19 -184
  11. data/.rspec +0 -2
  12. data/.travis.yml +0 -11
  13. data/DESIGN.md +0 -87
  14. data/Gemfile.travis +0 -8
  15. data/Gemfile.travis.lock +0 -104
  16. data/WISHLIST.md +0 -54
  17. data/bin/yap-dev +0 -45
  18. data/lib/tasks/gem.rake +0 -62
  19. data/lib/yap.rb +0 -52
  20. data/lib/yap/addon.rb +0 -24
  21. data/lib/yap/addon/base.rb +0 -52
  22. data/lib/yap/addon/export_as.rb +0 -12
  23. data/lib/yap/addon/loader.rb +0 -84
  24. data/lib/yap/addon/path.rb +0 -56
  25. data/lib/yap/addon/rc_file.rb +0 -21
  26. data/lib/yap/addon/reference.rb +0 -22
  27. data/lib/yap/cli.rb +0 -4
  28. data/lib/yap/cli/commands.rb +0 -6
  29. data/lib/yap/cli/commands/addon.rb +0 -14
  30. data/lib/yap/cli/commands/addon/disable.rb +0 -35
  31. data/lib/yap/cli/commands/addon/enable.rb +0 -35
  32. data/lib/yap/cli/commands/addon/list.rb +0 -37
  33. data/lib/yap/cli/commands/addon/search.rb +0 -99
  34. data/lib/yap/cli/commands/generate.rb +0 -13
  35. data/lib/yap/cli/commands/generate/addon.rb +0 -258
  36. data/lib/yap/cli/commands/generate/addonrb.template +0 -22
  37. data/lib/yap/cli/commands/generate/gemspec.template +0 -25
  38. data/lib/yap/cli/commands/generate/license.template +0 -21
  39. data/lib/yap/cli/commands/generate/rakefile.template +0 -6
  40. data/lib/yap/cli/commands/generate/readme.template +0 -40
  41. data/lib/yap/cli/options.rb +0 -162
  42. data/lib/yap/cli/options/addon.rb +0 -64
  43. data/lib/yap/cli/options/addon/disable.rb +0 -62
  44. data/lib/yap/cli/options/addon/enable.rb +0 -63
  45. data/lib/yap/cli/options/addon/list.rb +0 -65
  46. data/lib/yap/cli/options/addon/search.rb +0 -76
  47. data/lib/yap/cli/options/generate.rb +0 -59
  48. data/lib/yap/cli/options/generate/addon.rb +0 -63
  49. data/lib/yap/configuration.rb +0 -74
  50. data/lib/yap/gem_helper.rb +0 -195
  51. data/lib/yap/gem_tasks.rb +0 -6
  52. data/lib/yap/shell.rb +0 -116
  53. data/lib/yap/shell/aliases.rb +0 -58
  54. data/lib/yap/shell/builtins.rb +0 -18
  55. data/lib/yap/shell/builtins/alias.rb +0 -42
  56. data/lib/yap/shell/builtins/cd.rb +0 -57
  57. data/lib/yap/shell/builtins/env.rb +0 -11
  58. data/lib/yap/shell/commands.rb +0 -163
  59. data/lib/yap/shell/evaluation.rb +0 -439
  60. data/lib/yap/shell/evaluation/shell_expansions.rb +0 -99
  61. data/lib/yap/shell/event_emitter.rb +0 -18
  62. data/lib/yap/shell/execution.rb +0 -16
  63. data/lib/yap/shell/execution/builtin_command_execution.rb +0 -20
  64. data/lib/yap/shell/execution/command_execution.rb +0 -30
  65. data/lib/yap/shell/execution/context.rb +0 -128
  66. data/lib/yap/shell/execution/file_system_command_execution.rb +0 -137
  67. data/lib/yap/shell/execution/result.rb +0 -18
  68. data/lib/yap/shell/execution/ruby_command_execution.rb +0 -80
  69. data/lib/yap/shell/execution/shell_command_execution.rb +0 -30
  70. data/lib/yap/shell/prompt.rb +0 -21
  71. data/lib/yap/shell/repl.rb +0 -237
  72. data/lib/yap/shell/version.rb +0 -5
  73. data/lib/yap/world.rb +0 -286
  74. data/rcfiles/yaprc +0 -390
  75. data/scripts/4 +0 -8
  76. data/scripts/bg-vim +0 -4
  77. data/scripts/fail +0 -3
  78. data/scripts/letters +0 -8
  79. data/scripts/lots-of-output +0 -6
  80. data/scripts/pass +0 -3
  81. data/scripts/simulate-long-running +0 -4
  82. data/scripts/write-to-stderr.rb +0 -3
  83. data/scripts/write-to-stdout.rb +0 -3
  84. data/spec/features/addons/generating_an_addon_spec.rb +0 -55
  85. data/spec/features/addons/using_an_addon_spec.rb +0 -182
  86. data/spec/features/aliases_spec.rb +0 -78
  87. data/spec/features/environment_variables_spec.rb +0 -69
  88. data/spec/features/filesystem_commands_spec.rb +0 -61
  89. data/spec/features/first_time_spec.rb +0 -45
  90. data/spec/features/grouping_spec.rb +0 -81
  91. data/spec/features/line_editing_spec.rb +0 -174
  92. data/spec/features/range_spec.rb +0 -35
  93. data/spec/features/redirection_spec.rb +0 -234
  94. data/spec/features/repetition_spec.rb +0 -118
  95. data/spec/features/shell_expansions_spec.rb +0 -127
  96. data/spec/spec_helper.rb +0 -172
  97. data/spec/support/matchers/have_not_printed.rb +0 -30
  98. data/spec/support/matchers/have_printed.rb +0 -68
  99. data/spec/support/very_soon.rb +0 -9
  100. data/spec/support/yap_spec_dsl.rb +0 -258
  101. data/test.rb +0 -206
  102. data/update-rawline.sh +0 -6
@@ -1,74 +0,0 @@
1
- require 'pathname'
2
-
3
- module Yap
4
- require 'yap/world'
5
-
6
- def self.configuration
7
- @configuration ||= Configuration.new
8
- end
9
-
10
- class Configuration
11
- attr_accessor :addon_paths
12
- attr_accessor :rcfiles
13
- attr_accessor :yap_addons_configuration_path
14
- attr_accessor :yap_binpath
15
-
16
- def self.option(name, type=nil, default: nil)
17
- reader_method = name.to_s
18
- define_method(reader_method) do
19
- return default unless instance_variable_defined?("@#{name}")
20
- value = instance_variable_get("@#{name}")
21
- return !!value if type == :boolean
22
- value
23
- end
24
-
25
- writer_method = "#{reader_method}="
26
- define_method(writer_method) do |value|
27
- instance_variable_set("@#{name}", value)
28
- end
29
-
30
- if type == :boolean
31
- query_method = "#{reader_method}?"
32
- alias_method query_method, reader_method
33
- end
34
- end
35
-
36
- option :run_shell, :boolean, default: true
37
- option :skip_first_time, :boolean, default: false
38
- option :use_addons, :boolean, default: true
39
- option :use_history, :boolean, default: true
40
- option :use_rcfiles, :boolean, default: true
41
-
42
- def initialize
43
- @yap_addons_configuration_path = yap_path.join('addons.yml')
44
-
45
- @addon_paths = [
46
- # "#{File.dirname(__FILE__)}/../../addons",
47
- # "#{ENV['HOME']}/.yap/addons"
48
- ].concat(Gem.path.map { |gems_path| "#{gems_path}/gems" }).map do |path|
49
- File.expand_path(path)
50
- end
51
-
52
- @rcfiles = [
53
- "#{ENV['HOME']}/.yaprc",
54
- preferred_yaprc_path
55
- ]
56
- end
57
-
58
- def path_for(part)
59
- yap_path.join(part)
60
- end
61
-
62
- def preferred_yaprc_path
63
- yap_path.join("yaprc")
64
- end
65
-
66
- def yaprc_template_path
67
- Pathname.new(File.dirname(__FILE__)).join('../../rcfiles/yaprc')
68
- end
69
-
70
- def yap_path
71
- Pathname.new "#{ENV['HOME']}/.yap"
72
- end
73
- end
74
- end
@@ -1,195 +0,0 @@
1
- require 'bundler'
2
- require 'term/ansicolor'
3
- require 'yap/addon'
4
-
5
- module Yap
6
- class GemHelper
7
- Color = Term::ANSIColor
8
-
9
- include Rake::DSL if defined? Rake::DSL
10
-
11
- class << self
12
- # set when install'd.
13
- attr_accessor :instance
14
-
15
- def install_tasks(opts = {})
16
- new(opts[:dir], opts[:name]).install
17
- end
18
- end
19
-
20
- attr_reader :spec_path, :base, :gemspec
21
-
22
- def initialize(base = nil, name = nil)
23
- @base ||= Dir.pwd
24
- gemspecs = name ? [File.join(@base, "#{name}.gemspec")] : Dir[File.join(@base, "{,*}.gemspec")]
25
- raise "Unable to determine name from existing gemspec. Use :name => 'gemname' in #install_tasks to manually set it." unless gemspecs.size == 1
26
- @spec_path = gemspecs.first
27
- @gemspec = Bundler.load_gemspec(@spec_path)
28
- @export_as = Yap::Addon.export_as_for_gemspec(@gemspec)
29
- end
30
-
31
- def install
32
- built_gem_path = nil
33
-
34
- desc "Build #{Color.yellow(@export_as)} yap addon as gem #{name}-#{version}.gem"
35
- task "build" do
36
- built_gem_path = build_gem
37
- puts "Don't forget to run #{Term::ANSIColor.yellow('rake install && reload!')} to see your changes reflected in yap."
38
- puts Term::ANSIColor.bright_black("P.S. You can skip this step if you always run 'rake install'")
39
- end
40
-
41
- desc "Build and install #{Color.yellow(@export_as)} yap addon as gem #{name}-#{version}.gem into system gems."
42
- task "install" do
43
- built_gem_path = build_gem
44
- install_gem(built_gem_path)
45
- puts "Don't forget to run #{Term::ANSIColor.yellow('reload!')} to see your changes reflected in yap."
46
- end
47
-
48
- desc "Build and install #{Color.yellow(@export_as)} yap addon as #{name}-#{version}.gem into system gems without network access."
49
- task "install:local" => "build" do
50
- install_gem(built_gem_path, :local)
51
- end
52
-
53
- desc "Create tag #{version_tag} and build and push #{Color.yellow(@export_as)} addon #{name}-#{version}.gem to Rubygems\n" \
54
- "To prevent publishing in Rubygems use `gem_push=no rake release`"
55
- task "release", [:remote] => ["build", "release:guard_clean",
56
- "release:source_control_push", "release:rubygem_push"] do
57
- end
58
-
59
- task "release:guard_clean" do
60
- guard_clean
61
- end
62
-
63
- task "release:source_control_push", [:remote] do |_, args|
64
- tag_version { git_push(args[:remote]) } unless already_tagged?
65
- end
66
-
67
- task "release:rubygem_push" do
68
- rubygem_push(built_gem_path) if gem_push?
69
- end
70
-
71
- GemHelper.instance = self
72
- end
73
-
74
- def build_gem
75
- file_name = nil
76
- sh("gem build -V '#{spec_path}'") do
77
- file_name = File.basename(built_gem_path)
78
- FileUtils.mkdir_p(File.join(base, 'pkg'))
79
- FileUtils.mv(built_gem_path, 'pkg')
80
- tell_user_success("#{name} #{version} built to pkg/#{file_name}.")
81
- end
82
- File.join(base, "pkg", file_name)
83
- end
84
-
85
- def install_gem(built_gem_path = nil, local = false)
86
- built_gem_path ||= build_gem
87
- out, _ = sh_with_code("gem install '#{built_gem_path}'#{" --local" if local}")
88
- raise "Couldn't install gem, run `gem install #{built_gem_path}' for more detailed output" unless out[/Successfully installed/]
89
- tell_user_success("#{name} (#{version}) installed.")
90
- end
91
-
92
- protected
93
-
94
- def tell_user_success(msg)
95
- puts Color.green(msg)
96
- end
97
-
98
- def tell_user_error(msg)
99
- puts Color.red(msg)
100
- end
101
-
102
- def rubygem_push(path)
103
- allowed_push_host = nil
104
- gem_command = "gem push '#{path}'"
105
- if @gemspec.respond_to?(:metadata)
106
- allowed_push_host = @gemspec.metadata["allowed_push_host"]
107
- gem_command += " --host #{allowed_push_host}" if allowed_push_host
108
- end
109
- unless allowed_push_host || Pathname.new("~/.gem/credentials").expand_path.file?
110
- raise "Your rubygems.org credentials aren't set. Run `gem push` to set them."
111
- end
112
- sh(gem_command)
113
- tell_user_success "Pushed #{name} #{version} to #{allowed_push_host ? allowed_push_host : "rubygems.org."}"
114
- end
115
-
116
- def built_gem_path
117
- Dir[File.join(base, "#{name}-*.gem")].sort_by {|f| File.mtime(f) }.last
118
- end
119
-
120
- def git_push(remote = "")
121
- perform_git_push remote
122
- perform_git_push "#{remote} --tags"
123
- tell_user_success "Pushed git commits and tags."
124
- end
125
-
126
- def perform_git_push(options = "")
127
- cmd = "git push #{options}"
128
- out, code = sh_with_code(cmd)
129
- raise "Couldn't git push. `#{cmd}' failed with the following output:\n\n#{out}\n" unless code == 0
130
- end
131
-
132
- def already_tagged?
133
- return false unless sh("git tag").split(/\n/).include?(version_tag)
134
- tell_user_success "Tag #{version_tag} has already been created."
135
- true
136
- end
137
-
138
- def guard_clean
139
- clean? && committed? || raise("There are files that need to be committed first.")
140
- end
141
-
142
- def clean?
143
- sh_with_code("git diff --exit-code")[1] == 0
144
- end
145
-
146
- def committed?
147
- sh_with_code("git diff-index --quiet --cached HEAD")[1] == 0
148
- end
149
-
150
- def tag_version
151
- sh "git tag -a -m \"Version #{version}\" #{version_tag}"
152
- tell_user_success "Tagged #{version_tag}."
153
- yield if block_given?
154
- rescue
155
- tell_user_error "Untagging #{version_tag} due to error."
156
- sh_with_code "git tag -d #{version_tag}"
157
- raise
158
- end
159
-
160
- def version
161
- gemspec.version
162
- end
163
-
164
- def version_tag
165
- "v#{version}"
166
- end
167
-
168
- def name
169
- gemspec.name
170
- end
171
-
172
- def sh(cmd, &block)
173
- out, code = sh_with_code(cmd, &block)
174
- unless code.zero?
175
- raise(out.empty? ? "Running `#{cmd}` failed. Run this command directly for more detailed output." : out)
176
- end
177
- out
178
- end
179
-
180
- def sh_with_code(cmd, &block)
181
- cmd += " 2>&1"
182
- outbuf = String.new
183
- Dir.chdir(base) do
184
- outbuf = `#{cmd}`
185
- status = $?.exitstatus
186
- block.call(outbuf) if status.zero? && block
187
- [outbuf, status]
188
- end
189
- end
190
-
191
- def gem_push?
192
- ! %w(n no nil false off 0).include?(ENV["gem_push"].to_s.downcase)
193
- end
194
- end
195
- end
@@ -1,6 +0,0 @@
1
- # frozen_string_literal: true
2
- require "rake/clean"
3
- CLOBBER.include "pkg"
4
-
5
- require "yap/gem_helper"
6
- Yap::GemHelper.install_tasks
@@ -1,116 +0,0 @@
1
- require 'readline'
2
- require 'yaml'
3
- require 'fcntl'
4
-
5
- module Yap
6
- module Shell
7
- require 'yap/shell/version'
8
- require 'yap/shell/builtins'
9
-
10
- autoload :Aliases, "yap/shell/aliases"
11
-
12
- autoload :CommandFactory, "yap/shell/commands"
13
- autoload :CommandError, "yap/shell/commands"
14
- autoload :BuiltinCommand, "yap/shell/commands"
15
- autoload :FileSystemCommand, "yap/shell/commands"
16
- autoload :RubyCommand, "yap/shell/commands"
17
- autoload :ShellCommand, "yap/shell/commands"
18
-
19
- autoload :Execution, "yap/shell/execution"
20
-
21
- autoload :Evaluation, "yap/shell/evaluation"
22
- autoload :Repl, "yap/shell/repl"
23
-
24
- class Impl
25
- def initialize(addons:)
26
- @original_file_descriptor_flags = {
27
- stdin: $stdin.fcntl(Fcntl::F_GETFL, 0),
28
- stdout: $stdout.fcntl(Fcntl::F_GETFL, 0),
29
- stderr: $stderr.fcntl(Fcntl::F_GETFL, 0)
30
- }
31
-
32
- @stdin = $stdin
33
- @stdout = $stdout
34
- @stderr = $stderr
35
-
36
- @stdout.sync = true
37
- @stderr.sync = true
38
-
39
- addons_str = "\n - " + addons.map(&:class).map(&:name).join("\n - ")
40
- Treefell['shell'].puts "Constructing world instance with addons: #{addons_str}"
41
- @world = Yap::World.instance(addons:addons)
42
- end
43
-
44
- # Yields to the passed in block after restoring the file descriptor
45
- # flags that Yap started in. This ensures that any changes Yap has
46
- # made to run the shell don't interfere with child processes.
47
- def with_original_file_descriptor_flags(&block)
48
- current_file_descriptor_flags = {
49
- stdin: $stdin.fcntl(Fcntl::F_GETFL, 0),
50
- stdout: $stdout.fcntl(Fcntl::F_GETFL, 0),
51
- stderr: $stderr.fcntl(Fcntl::F_GETFL, 0)
52
- }
53
-
54
- $stdin.fcntl(Fcntl::F_SETFL, @original_file_descriptor_flags[:stdin])
55
- $stdout.fcntl(Fcntl::F_SETFL, @original_file_descriptor_flags[:stdout])
56
- $stderr.fcntl(Fcntl::F_SETFL, @original_file_descriptor_flags[:stderr])
57
-
58
- yield
59
- ensure
60
- $stdin.fcntl(Fcntl::F_SETFL, current_file_descriptor_flags[:stdin])
61
- $stdout.fcntl(Fcntl::F_SETFL, current_file_descriptor_flags[:stdout])
62
- $stderr.fcntl(Fcntl::F_SETFL, current_file_descriptor_flags[:stderr])
63
- end
64
-
65
- def repl
66
- context = Yap::Shell::Execution::Context.new(
67
- stdin: @stdin,
68
- stdout: @stdout,
69
- stderr: @stderr
70
- )
71
-
72
- @world.repl.on_input do |input|
73
- Treefell['shell'].puts "repl received input: #{input.inspect}"
74
- evaluation = Yap::Shell::Evaluation.new(stdin:@stdin, stdout:@stdout, stderr:@stderr, world:@world)
75
- evaluation.evaluate(input) do |command, stdin, stdout, stderr, wait|
76
- Treefell['shell'].puts <<-DEBUG.gsub(/^\s*\|/, '')
77
- |adding #{command} to run in context of:
78
- | stdin: #{stdin.inspect}
79
- | stdout: #{stdout.inspect}
80
- | stderr: #{stderr.inspect}
81
- | wait for child process to complete? #{wait.inspect}
82
- DEBUG
83
- context.clear_commands
84
- context.add_command_to_run command, stdin:stdin, stdout:stdout, stderr:stderr, wait:wait
85
-
86
- with_original_file_descriptor_flags do
87
- context.execute(world:@world)
88
- end
89
- end
90
- end
91
-
92
- begin
93
- Treefell['shell'].puts "enter interactive mode"
94
- @world.interactive!
95
- # rescue Errno::EIO => ex
96
- # # This happens when yap is no longer the foreground process
97
- # # but it tries to receive input/output from the tty. I believe it
98
- # # is a race condition when launching a child process.
99
- rescue Interrupt
100
- Treefell['shell'].puts "^C"
101
- @world.editor.puts "^C"
102
- retry
103
- rescue Exception => ex
104
- if !ex.is_a?(SystemExit)
105
- if $stdout.isatty
106
- binding.pry
107
- else
108
- $stdout.puts ex.class.name
109
- raise ex
110
- end
111
- end
112
- end
113
- end
114
- end
115
- end
116
- end
@@ -1,58 +0,0 @@
1
- require 'singleton'
2
-
3
- module Yap::Shell
4
- class Aliases
5
- include Singleton
6
-
7
- def initialize
8
- @file = ENV["HOME"] + "/.yapaliases.yml"
9
- @aliases = begin
10
- Treefell['shell'].puts "reading aliases from disk: #{@file}"
11
- YAML.load_file(@file)
12
- rescue
13
- {}
14
- end
15
- end
16
-
17
- def names
18
- @aliases.keys
19
- end
20
-
21
- def fetch_alias(name)
22
- @aliases[name].tap do |contents|
23
- Treefell['shell'].puts "alias fetched name=#{name} contents=#{contents.inspect}"
24
- end
25
- end
26
-
27
- def set_alias(name, contents)
28
- @aliases[name] = contents
29
- Treefell['shell'].puts "alias set name=#{name} to #{contents.inspect}"
30
- write_to_disk
31
- end
32
-
33
- def unset_alias(name)
34
- @aliases.delete(name)
35
- Treefell['shell'].puts "alias unset name=#{name}"
36
- write_to_disk
37
- end
38
-
39
- def has_key?(key)
40
- @aliases.has_key?(key)
41
- end
42
-
43
- def to_h
44
- @aliases.keys.compact.sort.inject(Hash.new) do |h,k|
45
- h[k] = @aliases[k]
46
- h
47
- end
48
- end
49
-
50
- private
51
-
52
- def write_to_disk
53
- File.write(@file, @aliases.to_yaml).tap do
54
- Treefell['shell'].puts "aliases written to disk: #{@file}"
55
- end
56
- end
57
- end
58
- end