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.
- checksums.yaml +4 -4
- data/README.md +108 -37
- data/bin/runn +5 -0
- data/examples/default-action/runfile +9 -0
- data/examples/default-action-2/runfile +11 -0
- data/examples/default-action-2/server.runfile +6 -0
- data/examples/different-name/runfile.rb +8 -0
- data/examples/example/runfile +10 -0
- data/examples/example-multiline/runfile +16 -0
- data/examples/execute/runfile +14 -0
- data/examples/execute/server.runfile +11 -0
- data/examples/full/runfile +24 -0
- data/examples/import/more_tasks/spec.runfile +7 -0
- data/examples/import/runfile +10 -0
- data/examples/import/tasks/server.runfile +13 -0
- data/examples/minimal/runfile +4 -0
- data/examples/multiple-runfiles/runfile +11 -0
- data/examples/multiple-runfiles/server.runfile +13 -0
- data/examples/named-only/deploy.runfile +7 -0
- data/examples/named-only/server.runfile +11 -0
- data/examples/naval-fate/runfile +47 -0
- data/examples/shortcut/runfile +31 -0
- data/lib/runfile/action.rb +40 -14
- data/lib/runfile/concerns/dsl.rb +132 -0
- data/lib/runfile/concerns/inspectable.rb +13 -0
- data/lib/runfile/concerns/renderable.rb +16 -0
- data/lib/runfile/entrypoint.rb +50 -0
- data/lib/runfile/exceptions.rb +13 -0
- data/lib/runfile/gem_finder.rb +29 -0
- data/lib/runfile/initiator.rb +87 -0
- data/lib/runfile/meta.rb +65 -0
- data/lib/runfile/runner.rb +10 -173
- data/lib/runfile/templates/runfile +13 -0
- data/lib/runfile/userfile.rb +111 -0
- data/lib/runfile/version.rb +2 -2
- data/lib/runfile/views/initiator.gtx +28 -0
- data/lib/runfile/views/userfile.gtx +93 -0
- data/lib/runfile.rb +13 -10
- metadata +98 -24
- data/bin/run +0 -10
- data/bin/run! +0 -16
- data/lib/runfile/compatibility.rb +0 -84
- data/lib/runfile/docopt_helper.rb +0 -128
- data/lib/runfile/dsl.rb +0 -90
- data/lib/runfile/refinements.rb +0 -22
- data/lib/runfile/runfile_helper.rb +0 -165
- data/lib/runfile/settings.rb +0 -34
- data/lib/runfile/setup.rb +0 -19
- data/lib/runfile/templates/Runfile +0 -16
- 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
|
data/lib/runfile/refinements.rb
DELETED
@@ -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
|
data/lib/runfile/settings.rb
DELETED
@@ -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
|
data/lib/runfile/terminal.rb
DELETED
@@ -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
|