runfile 0.11.2 → 0.12.0.pre.rc1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f1e4e930d902a8bb8db9d283e1cf7c33fb26c5e1dfdf77b03d5be0a3acc01609
4
- data.tar.gz: cf2bf1976c2dee358a8bbd2b9465b871bc6c9630c0ca7f091000b2464615370c
3
+ metadata.gz: 4ee58eaa893425817219f8fa94a2e96a7789363dc3082f3f8c520130357199e6
4
+ data.tar.gz: 607dc6702aeb3b9ec09f71c88c32292c98f3a0b7c1c6dfefbfbdb1cec02e5738
5
5
  SHA512:
6
- metadata.gz: 9eaadbedb085b6a8ef13078327b2260c82fc86baebf2292868eb7d37c166206e8b529a82a67e39fbe3a1087271308d5f750ff07bea8c515e9b065d7e413cdf65
7
- data.tar.gz: f837dd093b39741dabc2e67813bcd21f9ff7bdac3b52cb90990fe9b568f90801e5c344e697224ddce095af478fc7e92ace4d5be8867c97827b4627f93dd7535e
6
+ metadata.gz: be7893890fc0075e964c49bf3aea294b6337bf5440f0ccea2d56a223439fa7eaa5128cad2d9e8bff57798d77ec55b5c686f10acc7726f2d7b9de6f74d55ca4b7
7
+ data.tar.gz: b0e1b8aa6a11d96433c8bbcf09d92d3838ff6a7e1959b34542b16286d5248a76d0bf6f83fedb8f6520fe880d60450b65c72a052dcc79e79d4e292972de6b5ba4
data/README.md CHANGED
@@ -1,5 +1,7 @@
1
- Runfile - If Rake and Docopt had a baby
2
- ==================================================
1
+ <div align='center'>
2
+ <img src='logo.svg' width=280>
3
+
4
+ # Runfile - command line for your projects
3
5
 
4
6
  [![Gem Version](https://badge.fury.io/rb/runfile.svg)](https://badge.fury.io/rb/runfile)
5
7
  [![Build Status](https://github.com/DannyBen/runfile/workflows/Test/badge.svg)](https://github.com/DannyBen/runfile/actions?query=workflow%3ATest)
@@ -7,11 +9,13 @@ Runfile - If Rake and Docopt had a baby
7
9
 
8
10
  ---
9
11
 
10
- A beautiful command line application framework.
11
- Rake-inspired, Docopt inside.
12
+ A beautiful command line application framework
13
+ Rake-inspired - Docopt inside
12
14
 
13
15
  ---
14
16
 
17
+ </div>
18
+
15
19
  **Runfile** lets you create command line applications in a way similar
16
20
  to [Rake](https://github.com/ruby/rake), but with the full power of
17
21
  [Docopt](http://docopt.org/) command line options.
@@ -21,26 +25,7 @@ You create a `Runfile`, and execute commands with
21
25
 
22
26
  ![Runfile Demo](demo.svg "Runfile Demo")
23
27
 
24
- [Learn More in the User Guide](https://runfile.dannyb.co)
25
-
26
- ---
27
-
28
- **Upgrade Notice:**
29
- If you are upgrading to 0.9.x - the `name` command was replaced
30
- with `title`.
31
-
32
- ---
33
-
34
- Install
35
- --------------------------------------------------
36
-
37
- ```shell
38
- $ gem install runfile
39
- ```
40
-
41
-
42
- Quick Start
43
- --------------------------------------------------
28
+ ## Quick Start
44
29
 
45
30
  ```shell
46
31
  $ run new # create a new Runfile
@@ -49,8 +34,7 @@ $ vi Runfile # edit the Runfile
49
34
  ```
50
35
 
51
36
 
52
- Example
53
- --------------------------------------------------
37
+ ## Example
54
38
 
55
39
  The most minimal `Runfile` looks like this:
56
40
 
@@ -63,14 +47,14 @@ end
63
47
 
64
48
  You can then run it by executing this command:
65
49
 
66
- ```
50
+ ```shell
67
51
  $ run greet Luke
68
52
  Hello Luke
69
53
  ```
70
54
 
71
55
  Executing `run` without parameters, will show the usage patterns:
72
56
 
73
- ```
57
+ ```shell
74
58
  $ run
75
59
  Usage:
76
60
  run greet <name>
@@ -79,7 +63,7 @@ Usage:
79
63
 
80
64
  Executing `run --help` will show the full help document (docopt)
81
65
 
82
- ```
66
+ ```shell
83
67
  $ run --help
84
68
  Runfile 0.0.0
85
69
 
@@ -95,30 +79,13 @@ Options:
95
79
  Show version
96
80
  ```
97
81
 
82
+ ## Documentation
98
83
 
99
- Runfile per project or global Runfiles
100
- --------------------------------------------------
101
-
102
- In addition to the per project `Runfile` files, it is also possible to
103
- create global runfiles that are accessible to you only or to anybody on
104
- the system.
105
-
106
- When you execute `run`, we will look for files in this order:
107
-
108
- - `Runfile` in the current directory
109
- - `*.runfile` in the current directory
110
- - `~/runfile/**/*.runfile`
111
- - `/etc/runfile/**/*.runfile`
112
-
113
- When you execute `run!`, we will ignore any local Runfile and only search
114
- for global (named) runfiles.
115
-
116
- Read more on [Runfile Location and Filename](https://runfile.dannyb.co/Runfile-Location-and-Filename)
84
+ - [User Guide](https://runfile.dannyb.co/)
85
+ - [Learn by Example](https://github.com/DannyBen/runfile/tree/master/examples#readme)
117
86
 
87
+ ## Contributing / Support
118
88
 
119
- Documentation
120
- --------------------------------------------------
89
+ If you experience any issue, have a question or a suggestion, or if you wish
90
+ to contribute, feel free to [open an issue](https://github.com/DannyBen/runfile/issues).
121
91
 
122
- - [User Guide](https://runfile.dannyb.co)
123
- - [Learn by Example](https://github.com/DannyBen/runfile/tree/master/examples)
124
- - [Rubydoc](http://www.rubydoc.info/gems/runfile)
data/bin/run CHANGED
@@ -5,7 +5,6 @@ require 'runfile'
5
5
  # for dev
6
6
  # require File.dirname(__FILE__) + "/../lib/runfile"
7
7
 
8
- include Colsole
9
8
  include Runfile::DSL
10
9
 
11
10
  Runfile::Runner.instance.execute ARGV
data/bin/run! CHANGED
@@ -11,7 +11,6 @@ require 'runfile'
11
11
  # for dev
12
12
  # require File.dirname(__FILE__) + "/../lib/runfile"
13
13
 
14
- include Colsole
15
14
  include Runfile::DSL
16
15
 
17
16
  Runfile::Runner.instance.execute ARGV, false
@@ -1,5 +1,4 @@
1
1
  require 'docopt'
2
- require 'colsole'
3
2
 
4
3
  module Runfile
5
4
  # The DocoptHelper class handles the dynamic generation of the
@@ -7,7 +6,7 @@ module Runfile
7
6
  # to call Docopt so it returns the parsed arguments or halts with
8
7
  # usage message).
9
8
  class DocoptHelper
10
- include Colsole
9
+ using Refinements
11
10
 
12
11
  # The constructor expects to an object that responds to all the
13
12
  # textual details needed to generate a docopt document (name, version,
@@ -30,7 +29,7 @@ module Runfile
30
29
  # Generate a document based on all the actions, help messages
31
30
  # and options we have collected from the Runfile DSL.
32
31
  def docopt
33
- width = detect_terminal_size[0]
32
+ width = Terminal.width
34
33
  doc = []
35
34
  doc << (@version ? "#{@name} #{@version}" : "#{@name}")
36
35
  doc << "#{@summary}" if @summary
@@ -67,7 +66,7 @@ module Runfile
67
66
  doc << "Commands:" unless caption_printed
68
67
  caption_printed = true
69
68
  helpline = " #{action.help}"
70
- wrapped = word_wrap helpline, width
69
+ wrapped = helpline.word_wrap width
71
70
  doc << " #{action.usage}\n#{wrapped}\n" unless action.usage == false
72
71
  end
73
72
  doc
@@ -99,7 +98,7 @@ module Runfile
99
98
  base_command = @superspace ? "run #{@superspace}" : "run"
100
99
  @examples.each do |command|
101
100
  helpline = " #{base_command} #{command}"
102
- wrapped = word_wrap helpline, width
101
+ wrapped = helpline.word_wrap width
103
102
  doc << "#{wrapped}"
104
103
  end
105
104
  doc
@@ -113,7 +112,7 @@ module Runfile
113
112
  doc << "#{scope}:"
114
113
  values.each do |label, text|
115
114
  helpline = " #{text}"
116
- wrapped = word_wrap helpline, width
115
+ wrapped = helpline.word_wrap width
117
116
  doc << " #{label}\n#{wrapped}\n"
118
117
  end
119
118
  end
data/lib/runfile/dsl.rb CHANGED
@@ -83,51 +83,6 @@ module Runfile
83
83
  Runner.instance.cross_call command_string
84
84
  end
85
85
 
86
- # Run a command, wait until it is done and continue
87
- # run 'rails server'
88
- def run(cmd)
89
- ExecHandler.instance.run cmd
90
- end
91
-
92
- # Run a command, wait until it is done, then exit
93
- # run! 'rails server'
94
- def run!(cmd)
95
- ExecHandler.instance.run! cmd
96
- end
97
-
98
- # Run a command in the background, optionally log to a log file and save
99
- # the process ID in a pid file
100
- # run_bg 'rails server', pid: 'rails', log: 'tmp/log.log'
101
- def run_bg(cmd, pid: nil, log: '/dev/null')
102
- ExecHandler.instance.run_bg cmd, pid: pid, log: log
103
- end
104
-
105
- # Stop a command started with 'run_bg'. Provide the name of he pid file you
106
- # used in 'run_bg'
107
- # stop_bg 'rails'
108
- def stop_bg(pid)
109
- ExecHandler.instance.stop_bg pid
110
- end
111
-
112
- # Set a block to be called before each run. The block should return
113
- # the command to run, since this is intended to let the block modify
114
- # the command if it needs to.
115
- # before_run do |command|
116
- # puts "BEFORE #{command}"
117
- # command
118
- # end
119
- def before_run(&block)
120
- ExecHandler.instance.before_run(&block)
121
- end
122
-
123
- # Set a block to be called after each run
124
- # before_run do |command|
125
- # puts "AFTER #{command}"
126
- # end
127
- def after_run(&block)
128
- ExecHandler.instance.after_run(&block)
129
- end
130
-
131
86
  # Also allow to use 'endcommand' instead of 'command' to end
132
87
  # a command namespace definition
133
88
  alias_method :endcommand, :command
@@ -0,0 +1,22 @@
1
+ module Runfile
2
+ module Refinements
3
+ refine String do
4
+ def word_wrap(length = nil)
5
+ text = self
6
+
7
+ length ||= Terminal.width
8
+ lead = text[/^\s*/]
9
+ text.strip!
10
+ length -= lead.length
11
+ text.split("\n").collect! do |line|
12
+ if line.length > length
13
+ line.gsub!(/([^\s]{#{length}})([^\s$])/, "\\1 \\2")
14
+ line.gsub(/(.{1,#{length}})(\s+|$)/, "#{lead}\\1\n").rstrip
15
+ else
16
+ "#{lead}#{line}"
17
+ end
18
+ end * "\n"
19
+ end
20
+ end
21
+ end
22
+ end
@@ -8,6 +8,7 @@ module Runfile
8
8
  # 2. Creating new runfiles (`run new`)
9
9
  # 3. Showing a list of found system runfiles in a colorful help
10
10
  class RunfileHelper
11
+ using Refinements
11
12
  include SettingsMixin
12
13
 
13
14
  # Handle the case when `run` is called without a Runfile
@@ -72,14 +73,14 @@ module Runfile
72
73
 
73
74
  # Show some helpful tips, and a list of available runfiles
74
75
  def show_make_help(runfiles, compact=false)
75
- say "!txtpur!Runfile engine v#{Runfile::VERSION}" unless compact
76
+ puts "Runfile engine v#{Runfile::VERSION}" unless compact
76
77
  if runfiles.size < 3 and !compact
77
- say "\nTip: Type '!txtblu!run new!txtrst!' or '!txtblu!run new name!txtrst!' to create a runfile.\nFor global access, place !txtblu!named.runfiles!txtrst! in ~/runfile/ or in /etc/runfile/."
78
+ puts "\nTip: Type 'run new' or 'run new name' to create a runfile.\nFor global access, place named.runfiles in ~/runfile/ or in /etc/runfile/."
78
79
  end
79
80
  if runfiles.empty?
80
- say "\n!txtred!Runfile not found."
81
+ puts "\nRunfile not found."
81
82
  else
82
- say ""
83
+ puts ""
83
84
  compact ? say_runfile_usage(runfiles) : say_runfile_list(runfiles)
84
85
  end
85
86
  end
@@ -110,14 +111,14 @@ module Runfile
110
111
  def say_runfile_list(runfiles)
111
112
  runfile_paths = runfiles.map { |f| File.dirname f }
112
113
  max = runfile_paths.max_by(&:length).size
113
- width = detect_terminal_size[0]
114
+ width = Terminal.width
114
115
  runfiles.each do |f|
115
116
  f[/([^\/]+).runfile$/]
116
117
  command = "run #{$1}"
117
118
  spacer_size = width - max - command.size - 6
118
119
  spacer_size = [1, spacer_size].max
119
120
  spacer = '.' * spacer_size
120
- say " !txtgrn!#{command}!txtrst! #{spacer} #{File.dirname f}"
121
+ puts " #{command} #{spacer} #{File.dirname f}"
121
122
  end
122
123
  end
123
124
 
@@ -125,19 +126,19 @@ module Runfile
125
126
  def say_runfile_usage(runfiles)
126
127
  runfiles_as_columns = get_runfiles_as_columns runfiles
127
128
 
128
- say "#{settings.intro}\n" if settings.intro
129
- say "Usage: run <file>"
130
- say runfiles_as_columns
129
+ puts "#{settings.intro}\n" if settings.intro
130
+ puts "Usage: run <file>"
131
+ puts runfiles_as_columns
131
132
 
132
133
  show_shortcuts if settings.shortcuts
133
134
  end
134
135
 
135
136
  # Prints a friendly output of the shortcut list
136
137
  def show_shortcuts
137
- say "\nShortcuts:"
138
+ puts "\nShortcuts:"
138
139
  max = settings.shortcuts.keys.max_by(&:length).length
139
140
  settings.shortcuts.each_pair do |shortcut, command|
140
- say " #{shortcut.rjust max} : #{command}"
141
+ puts " #{shortcut.rjust max} : #{command}"
141
142
  end
142
143
  end
143
144
 
@@ -145,10 +146,10 @@ module Runfile
145
146
  # current terminal width
146
147
  def get_runfiles_as_columns(runfiles)
147
148
  namelist = runfile_names runfiles
148
- width = detect_terminal_size[0]
149
+ width = Terminal.width
149
150
  max = namelist.max_by(&:length).length
150
151
  message = " " + namelist.map {|f| f.ljust max+1 }.join(' ')
151
- word_wrap message, width
152
+ message.word_wrap width
152
153
  end
153
154
 
154
155
  def runfile_names(runfiles)
@@ -174,7 +174,6 @@ module Runfile
174
174
  if settings.shortcuts and settings.shortcuts[possible_candidate]
175
175
  shortcut_value = settings.shortcuts[argv[0]]
176
176
  expanded = shortcut_value.split ' '
177
- say "!txtblu!# #{possible_candidate} > #{shortcut_value}"
178
177
  argv.shift
179
178
  argv = expanded + argv
180
179
  end
@@ -2,13 +2,15 @@ title "Greeter"
2
2
  summary "A sample Runfile"
3
3
  version "0.1.0"
4
4
 
5
- usage "hello [<name> --color]"
5
+ usage "hello [<name> --shout]"
6
6
  help "Say hello"
7
- option "-c --color", "Greet with color"
7
+ option "-s --shout", "Greet louder"
8
8
  action :hello do |args|
9
- if args['--color']
10
- say "!txtgrn!Hello #{args['<name>']}"
9
+ message = "Hello #{args['<name>']}"
10
+
11
+ if args['--shout']
12
+ puts message.upcase
11
13
  else
12
- say "Hello #{args['<name>']}"
14
+ puts message
13
15
  end
14
16
  end
@@ -0,0 +1,32 @@
1
+ # This file provides some terminal related utilities (extracted from Colsole)
2
+
3
+ module Runfile
4
+ class Terminal
5
+ class << self
6
+ def size(default = [80,30])
7
+ if (ENV['COLUMNS'] =~ /^\d+$/) && (ENV['LINES'] =~ /^\d+$/)
8
+ result = [ENV['COLUMNS'].to_i, ENV['LINES'].to_i]
9
+ elsif (RUBY_PLATFORM =~ /java/ || (!STDIN.tty? && ENV['TERM'])) && command_exist?('tput')
10
+ result = [`tput cols 2>&1`.to_i, `tput lines 2>&1`.to_i]
11
+ elsif STDIN.tty? && command_exist?('stty')
12
+ result = `stty size 2>&1`.scan(/\d+/).map { |s| s.to_i }.reverse
13
+ else
14
+ result = default
15
+ end
16
+ result = default unless result[0].is_a? Integer and result[1].is_a? Integer and result[0] > 0 and result[1] > 0
17
+ result
18
+ end
19
+
20
+ def width
21
+ size[0]
22
+ end
23
+
24
+ def command_exist?(command)
25
+ ENV['PATH'].split(File::PATH_SEPARATOR).any? do |dir|
26
+ File.exist?(File.join dir, command) or File.exist?(File.join dir, "#{command}.exe")
27
+ end
28
+ end
29
+
30
+ end
31
+ end
32
+ end
@@ -1,3 +1,3 @@
1
1
  module Runfile
2
- VERSION = "0.11.2"
2
+ VERSION = "0.12.0-rc1"
3
3
  end
data/lib/runfile.rb CHANGED
@@ -1,4 +1,6 @@
1
1
  require 'runfile/version'
2
+ require 'runfile/terminal'
3
+ require 'runfile/refinements'
2
4
  require 'runfile/settings'
3
5
  require 'runfile/setup'
4
6
  require 'runfile/docopt_helper'
@@ -6,6 +8,3 @@ require 'runfile/runfile_helper'
6
8
  require 'runfile/action'
7
9
  require 'runfile/runner'
8
10
  require 'runfile/dsl'
9
- require 'runfile/exec'
10
-
11
- require 'byebug' if ENV['BYEBUG']
metadata CHANGED
@@ -1,29 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: runfile
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.2
4
+ version: 0.12.0.pre.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Danny Ben Shitrit
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-11-06 00:00:00.000000000 Z
11
+ date: 2021-09-28 00:00:00.000000000 Z
12
12
  dependencies:
13
- - !ruby/object:Gem::Dependency
14
- name: colsole
15
- requirement: !ruby/object:Gem::Requirement
16
- requirements:
17
- - - "~>"
18
- - !ruby/object:Gem::Version
19
- version: '0.5'
20
- type: :runtime
21
- prerelease: false
22
- version_requirements: !ruby/object:Gem::Requirement
23
- requirements:
24
- - - "~>"
25
- - !ruby/object:Gem::Version
26
- version: '0.5'
27
13
  - !ruby/object:Gem::Dependency
28
14
  name: docopt
29
15
  requirement: !ruby/object:Gem::Requirement
@@ -54,12 +40,13 @@ files:
54
40
  - lib/runfile/action.rb
55
41
  - lib/runfile/docopt_helper.rb
56
42
  - lib/runfile/dsl.rb
57
- - lib/runfile/exec.rb
43
+ - lib/runfile/refinements.rb
58
44
  - lib/runfile/runfile_helper.rb
59
45
  - lib/runfile/runner.rb
60
46
  - lib/runfile/settings.rb
61
47
  - lib/runfile/setup.rb
62
48
  - lib/runfile/templates/Runfile
49
+ - lib/runfile/terminal.rb
63
50
  - lib/runfile/version.rb
64
51
  homepage: https://github.com/DannyBen/runfile
65
52
  licenses:
@@ -77,14 +64,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
77
64
  requirements:
78
65
  - - ">="
79
66
  - !ruby/object:Gem::Version
80
- version: 2.0.0
67
+ version: 2.4.0
81
68
  required_rubygems_version: !ruby/object:Gem::Requirement
82
69
  requirements:
83
- - - ">="
70
+ - - ">"
84
71
  - !ruby/object:Gem::Version
85
- version: '0'
72
+ version: 1.3.1
86
73
  requirements: []
87
- rubygems_version: 3.1.4
74
+ rubygems_version: 3.2.25
88
75
  signing_key:
89
76
  specification_version: 4
90
77
  summary: If Rake and Docopt had a baby
data/lib/runfile/exec.rb DELETED
@@ -1,76 +0,0 @@
1
- require 'singleton'
2
-
3
- module Runfile
4
-
5
- # This class provides methods for easily and politely run shell commands
6
- # through a Runfile action.
7
- # It is mainly a convenient wrapper around `system` and `exec` and it also
8
- # adds functions for running background tasks with ease.
9
- class ExecHandler
10
- include Singleton
11
-
12
- # Run a command, wait until it is done and continue
13
- def run(cmd)
14
- cmd = @before_run_block.call(cmd) if @before_run_block
15
- return false unless cmd
16
- say "!txtgrn!> #{cmd}" unless Runfile.quiet
17
- system cmd
18
- @after_run_block.call(cmd) if @after_run_block
19
- end
20
-
21
- # Run a command, wait until it is done, then exit
22
- def run!(cmd)
23
- cmd = @before_run_block.call(cmd) if @before_run_block
24
- return false unless cmd
25
- say "!txtgrn!> #{cmd}" unless Runfile.quiet
26
- exec cmd
27
- end
28
-
29
- # Run a command in the background, optionally log to a log file and save
30
- # the process ID in a pid file
31
- def run_bg(cmd, pid: nil, log: '/dev/null')
32
- cmd = @before_run_block.call(cmd) if @before_run_block
33
- return false unless cmd
34
- full_cmd = "exec #{cmd} >#{log} 2>&1"
35
- say "!txtgrn!> #{full_cmd}" unless Runfile.quiet
36
- process = IO.popen "exec #{cmd} >#{log} 2>&1"
37
- File.write pidfile(pid), process.pid if pid
38
- @after_run_block.call(cmd) if @after_run_block
39
- return process.pid
40
- end
41
-
42
- # Stop a command started with 'run_bg'. Provide the name of he pid file you
43
- # used in 'run_bg'
44
- def stop_bg(pid)
45
- file = pidfile(pid)
46
- if File.exist? file
47
- pid = File.read file
48
- File.delete file
49
- run "kill -s TERM #{pid}"
50
- else
51
- say "!txtred!PID file not found." unless Runfile.quiet
52
- end
53
- end
54
-
55
- # Set a block to be called before each run
56
- def before_run(&block)
57
- @before_run_block = block
58
- end
59
-
60
- # Set a block to be called after each run
61
- def after_run(&block)
62
- @after_run_block = block
63
- end
64
-
65
- private
66
-
67
- def pid_dir
68
- defined?(Runfile.pid_dir) ? Runfile.pid_dir : nil
69
- end
70
-
71
- def pidfile(pid)
72
- pid_dir ? "#{pid_dir}/#{pid}.pid" : "#{pid}.pid"
73
- end
74
-
75
- end
76
- end