runfile 0.12.0 → 1.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
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