runfile 0.12.0 → 1.0.0.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.
Files changed (50) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +108 -37
  3. data/bin/runn +5 -0
  4. data/examples/default-action/runfile +9 -0
  5. data/examples/default-action-2/runfile +11 -0
  6. data/examples/default-action-2/server.runfile +6 -0
  7. data/examples/different-name/runfile.rb +8 -0
  8. data/examples/example/runfile +10 -0
  9. data/examples/example-multiline/runfile +16 -0
  10. data/examples/execute/runfile +14 -0
  11. data/examples/execute/server.runfile +11 -0
  12. data/examples/full/runfile +24 -0
  13. data/examples/import/more_tasks/spec.runfile +7 -0
  14. data/examples/import/runfile +10 -0
  15. data/examples/import/tasks/server.runfile +13 -0
  16. data/examples/minimal/runfile +4 -0
  17. data/examples/multiple-runfiles/runfile +11 -0
  18. data/examples/multiple-runfiles/server.runfile +13 -0
  19. data/examples/named-only/deploy.runfile +7 -0
  20. data/examples/named-only/server.runfile +11 -0
  21. data/examples/naval-fate/runfile +47 -0
  22. data/examples/shortcut/runfile +31 -0
  23. data/lib/runfile/action.rb +40 -14
  24. data/lib/runfile/concerns/dsl.rb +132 -0
  25. data/lib/runfile/concerns/inspectable.rb +13 -0
  26. data/lib/runfile/concerns/renderable.rb +16 -0
  27. data/lib/runfile/entrypoint.rb +50 -0
  28. data/lib/runfile/exceptions.rb +13 -0
  29. data/lib/runfile/gem_finder.rb +29 -0
  30. data/lib/runfile/initiator.rb +87 -0
  31. data/lib/runfile/meta.rb +65 -0
  32. data/lib/runfile/runner.rb +10 -173
  33. data/lib/runfile/templates/runfile +13 -0
  34. data/lib/runfile/userfile.rb +111 -0
  35. data/lib/runfile/version.rb +2 -2
  36. data/lib/runfile/views/initiator.gtx +28 -0
  37. data/lib/runfile/views/userfile.gtx +93 -0
  38. data/lib/runfile.rb +13 -10
  39. metadata +98 -24
  40. data/bin/run +0 -10
  41. data/bin/run! +0 -16
  42. data/lib/runfile/compatibility.rb +0 -84
  43. data/lib/runfile/docopt_helper.rb +0 -128
  44. data/lib/runfile/dsl.rb +0 -90
  45. data/lib/runfile/refinements.rb +0 -22
  46. data/lib/runfile/runfile_helper.rb +0 -165
  47. data/lib/runfile/settings.rb +0 -34
  48. data/lib/runfile/setup.rb +0 -19
  49. data/lib/runfile/templates/Runfile +0 -16
  50. data/lib/runfile/terminal.rb +0 -32
data/lib/runfile/dsl.rb DELETED
@@ -1,90 +0,0 @@
1
- # This file defines all the commands supported in a Runfile.
2
- # All commands are immediately handed over to the Runner instance
3
- # for handling.
4
-
5
- module Runfile
6
- module DSL
7
- private
8
-
9
- # Set the name of your Runfile program
10
- # title 'My Runfile'
11
- def title(name)
12
- Runner.instance.name = name
13
- end
14
-
15
- # Set the version of your Runfile program
16
- # version '0.1.0'
17
- def version(ver)
18
- Runner.instance.version = ver
19
- end
20
-
21
- # Set the one line summary of your Runfile program
22
- # summary 'Utilities for my server'
23
- def summary(text)
24
- Runner.instance.summary = text
25
- end
26
-
27
- # Set the usage pattern for the next action
28
- # usage 'server [--background]'
29
- def usage(text)
30
- Runner.instance.last_usage = text
31
- end
32
-
33
- # Set the help message for the next action
34
- # help 'Starts the server in the foreground or background'
35
- def help(text)
36
- Runner.instance.last_help = text
37
- end
38
-
39
- # Add an option/flag to the next action (can be called multiple
40
- # times)
41
- # option '-b --background', 'Start in the background'
42
- def option(flag, text, scope=nil)
43
- Runner.instance.add_option flag, text, scope
44
- end
45
-
46
- # Add a parameter (can be called multiple times)
47
- # param 'FOLDER', 'Folder to copy'
48
- def param(name, text, scope=nil)
49
- Runner.instance.add_param name, text, scope
50
- end
51
-
52
- # Set an environment variable (can be called multiple times)
53
- # env_var 'USER', 'Set the user (same as --user)'
54
- def env_var(name, text, scope = nil)
55
- Runner.instance.add_env_var name, text, scope
56
- end
57
-
58
- # Set an example command (can be called multiple times)
59
- # example 'server --background'
60
- def example(text)
61
- Runner.instance.add_example text
62
- end
63
-
64
- # Define the action
65
- # action :server do |args|
66
- # run 'rails server'
67
- # end
68
- def action(name, altname=nil, &block)
69
- Runner.instance.add_action name, altname, &block
70
- end
71
-
72
- # Define a new command namespace
73
- # command 'server'
74
- # # ... define actions here
75
- # endcommand
76
- def command(name=nil)
77
- Runner.instance.namespace = name
78
- end
79
-
80
- # Cross-call another action
81
- # execute 'other_action'
82
- def execute(command_string)
83
- Runner.instance.cross_call command_string
84
- end
85
-
86
- # Also allow to use 'endcommand' instead of 'command' to end
87
- # a command namespace definition
88
- alias_method :endcommand, :command
89
- end
90
- end
@@ -1,22 +0,0 @@
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
@@ -1,165 +0,0 @@
1
- require 'docopt'
2
- require 'pp'
3
-
4
- module Runfile
5
-
6
- # The RunfileHelper class assists in:
7
- # 1. Finding named.runfiles
8
- # 2. Creating new runfiles (`run new`)
9
- # 3. Showing a list of found system runfiles in a colorful help
10
- class RunfileHelper
11
- using Refinements
12
- include SettingsMixin
13
-
14
- # Handle the case when `run` is called without a Runfile
15
- # present. We will let the user know they can type `run new`
16
- # to create a new sample Runfile.
17
- # If the first argument matches the name of a *.runfile name,
18
- # we will return it to the caller. Otherwise, we return false
19
- # to indicate "no further handling is needed".
20
- def handle(argv)
21
- # make a new runfile
22
- if argv[0] == "new" && !settings_present?
23
- make_runfile argv[1]
24
- return false
25
- end
26
-
27
- # get a list of *.runfile path-wide
28
- runfiles = find_runfiles || []
29
-
30
- # if first arg is a valid *.runfile, run it
31
- if argv[0]
32
- runfile = runfiles.select { |f| f[/\/#{argv[0]}.runfile/] }.first
33
- runfile and return runfile
34
- end
35
-
36
- # if we are here, offer some help and advice and show a list
37
- # of possible runfiles to run.
38
- show_make_help runfiles, settings.folder
39
- return false
40
- end
41
-
42
- def purge_settings
43
- @settings = OpenStruct.new
44
- end
45
-
46
- private
47
-
48
- # Create a new runfile in the current directory. We can either
49
- # create a standard 'Runfile' or a 'named.runfile'.
50
- def make_runfile(name=nil)
51
- name = 'Runfile' if name.nil?
52
- template = File.expand_path("../templates/Runfile", __FILE__)
53
- name += ".runfile" unless name == 'Runfile'
54
- dest = "#{Dir.pwd}/#{name}"
55
- begin
56
- File.write(dest, File.read(template))
57
- puts "#{name} created."
58
- rescue => e
59
- abort "Failed creating #{name}\n#{e.message}"
60
- end
61
- end
62
-
63
- # Find all *.runfile files in our search difrectories
64
- def find_runfiles
65
- result = []
66
- dirs = runfile_folders
67
- dirs.each do |d|
68
- found = Dir[File.join(d, '*.runfile')]
69
- result << found unless found.empty?
70
- end
71
- return result.empty? ? false : result.flatten.uniq
72
- end
73
-
74
- # Show some helpful tips, and a list of available runfiles
75
- def show_make_help(runfiles, compact=false)
76
- puts "Runfile engine v#{Runfile::VERSION}" unless compact
77
- if runfiles.size < 3 and !compact
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/."
79
- end
80
- if runfiles.empty?
81
- puts "\nRunfile not found."
82
- else
83
- puts ""
84
- compact ? say_runfile_usage(runfiles) : say_runfile_list(runfiles)
85
- end
86
- end
87
-
88
- # Return array of folders we should search in for runfiles.
89
- def runfile_folders
90
- # This trick allows searching in subfolders recursively, including
91
- # one level of symlinked folder
92
- subdirs = '**{,/*/**}'
93
-
94
- # If there is a '.runfile' settings file with a folder definition
95
- # in it, use it. Otherwise, search globally.
96
- if settings.folder
97
- ["#{settings.folder}/#{subdirs}"]
98
- else
99
- [Dir.pwd, "#{Dir.home}/runfile/#{subdirs}", "/etc/runfile/#{subdirs}"]
100
- end
101
- end
102
-
103
- # [UNUSED] Same as runfile_folders, but including PATH
104
- def runfile_folders_with_path
105
- dirs = path_dirs
106
- dirs.insert 0, Dir.pwd, "#{Dir.home}/runfile", "/etc/runfile"
107
- dirs
108
- end
109
-
110
- # Output the list of available runfiles
111
- def say_runfile_list(runfiles)
112
- runfile_paths = runfiles.map { |f| File.dirname f }
113
- max = runfile_paths.max_by(&:length).size
114
- width = Terminal.width
115
- runfiles.each do |f|
116
- f[/([^\/]+).runfile$/]
117
- command = "run #{$1}"
118
- spacer_size = width - max - command.size - 6
119
- spacer_size = [1, spacer_size].max
120
- spacer = '.' * spacer_size
121
- puts " #{command} #{spacer} #{File.dirname f}"
122
- end
123
- end
124
-
125
- # Output the list of available runfiles without filename
126
- def say_runfile_usage(runfiles)
127
- runfiles_as_columns = get_runfiles_as_columns runfiles
128
-
129
- puts "#{settings.intro}\n" if settings.intro
130
- puts "Usage: run <file>"
131
- puts runfiles_as_columns
132
-
133
- show_shortcuts if settings.shortcuts
134
- end
135
-
136
- # Prints a friendly output of the shortcut list
137
- def show_shortcuts
138
- puts "\nShortcuts:"
139
- max = settings.shortcuts.keys.max_by(&:length).length
140
- settings.shortcuts.each_pair do |shortcut, command|
141
- puts " #{shortcut.rjust max} : #{command}"
142
- end
143
- end
144
-
145
- # Returns the list of runfiles, organized as columns based on the
146
- # current terminal width
147
- def get_runfiles_as_columns(runfiles)
148
- namelist = runfile_names runfiles
149
- width = Terminal.width
150
- max = namelist.max_by(&:length).length
151
- message = " " + namelist.map {|f| f.ljust max+1 }.join(' ')
152
- message.word_wrap width
153
- end
154
-
155
- def runfile_names(runfiles)
156
- runfiles.map {|f| /([^\/]+).runfile$/.match(f)[1] }.sort
157
- end
158
-
159
- # Returns an array of path directories
160
- def path_dirs
161
- ENV['PATH'].split(File::PATH_SEPARATOR)
162
- end
163
-
164
- end
165
- end
@@ -1,34 +0,0 @@
1
- require 'ostruct'
2
- require 'yaml'
3
-
4
- module Runfile
5
-
6
- # The Settings class handles '.runfile' YAML config files.
7
- # If found in the current directory, we will use their content.
8
- class Settings
9
- def as_struct
10
- OpenStruct.new settings
11
- end
12
-
13
- private
14
-
15
- def settings
16
- @settings ||= settings!
17
- end
18
-
19
- def settings!
20
- File.file?('.runfile') ? YAML.load_file('.runfile') : {}
21
- end
22
- end
23
-
24
- module SettingsMixin
25
- def settings
26
- @settings ||= Settings.new.as_struct
27
- end
28
-
29
- def settings_present?
30
- File.file?('.runfile')
31
- end
32
- end
33
-
34
- end
data/lib/runfile/setup.rb DELETED
@@ -1,19 +0,0 @@
1
- module Runfile
2
- class << self
3
- # Set the directory where PID files are stored when using `run_bg`
4
- # Runfile.pid_dir = 'tmp'
5
- attr_accessor :pid_dir
6
-
7
- # Disable echoing of the command when using `run` or `run!`
8
- # Runfile.quiet = true
9
- attr_accessor :quiet
10
-
11
- # You can also configure Runfile by providing a block:
12
- # Runfile.setup do |config|
13
- # config.quiet = true
14
- # end
15
- def setup
16
- yield self
17
- end
18
- end
19
- end
@@ -1,16 +0,0 @@
1
- title "Greeter"
2
- summary "A sample Runfile"
3
- version "0.1.0"
4
-
5
- usage "hello [<name> --shout]"
6
- help "Say hello"
7
- option "-s --shout", "Greet louder"
8
- action :hello do |args|
9
- message = "Hello #{args['<name>']}"
10
-
11
- if args['--shout']
12
- puts message.upcase
13
- else
14
- puts message
15
- end
16
- end
@@ -1,32 +0,0 @@
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