runfile 0.12.0.pre.rc1 → 1.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +112 -28
  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 +96 -21
  40. data/bin/run +0 -10
  41. data/bin/run! +0 -16
  42. data/lib/runfile/docopt_helper.rb +0 -128
  43. data/lib/runfile/dsl.rb +0 -90
  44. data/lib/runfile/refinements.rb +0 -22
  45. data/lib/runfile/runfile_helper.rb +0 -165
  46. data/lib/runfile/settings.rb +0 -34
  47. data/lib/runfile/setup.rb +0 -19
  48. data/lib/runfile/templates/Runfile +0 -16
  49. data/lib/runfile/terminal.rb +0 -32
@@ -0,0 +1,111 @@
1
+ require 'shellwords'
2
+
3
+ module Runfile
4
+ # Represents a single runfile.
5
+ class Userfile
6
+ include Renderable
7
+ include Inspectable
8
+ include DSL
9
+
10
+ attr_reader :code, :name, :path
11
+ attr_writer :context
12
+ alias action_prefix name
13
+
14
+ class << self
15
+ def load_file(path)
16
+ if masterfile? path
17
+ name = nil
18
+ else
19
+ name = File.basename path, '.runfile'
20
+ path = "#{path}.runfile" unless path.end_with? '.runfile'
21
+ end
22
+
23
+ code = File.read path
24
+ new code, name: name, path: path
25
+ end
26
+
27
+ def masterfile?(path)
28
+ Meta::MASTERFILE_NAMES.include? path
29
+ end
30
+ end
31
+
32
+ def initialize(code = nil, name: nil, path: nil)
33
+ @code = code
34
+ @name = name
35
+ @path = path
36
+
37
+ return unless @code
38
+
39
+ if path
40
+ instance_eval @code, @path
41
+ else
42
+ instance_eval @code
43
+ end
44
+ end
45
+
46
+ def inspectable
47
+ { name: name, path: path }
48
+ end
49
+
50
+ def run(argv = [])
51
+ found_delegate = delegate argv[0]
52
+ if found_delegate
53
+ found_delegate.run argv
54
+ else
55
+ run_local argv
56
+ end
57
+ end
58
+
59
+ def context
60
+ @context ||= {}
61
+ end
62
+
63
+ def implicit_title
64
+ title || name
65
+ end
66
+
67
+ # Returns an array of actions that have help defined
68
+ def commands
69
+ actions.values.select(&:help)
70
+ end
71
+
72
+ def delegates
73
+ @delegates ||= (name ? {} : meta.external_files)
74
+ end
75
+
76
+ private
77
+
78
+ def find_action(args)
79
+ acts = actions.values
80
+ acts.find { |a| args[a.name] } ||
81
+ acts.find { |a| args[a.shortcut] } ||
82
+ acts.find { |a| args[a.prefix] } ||
83
+ actions[:default]
84
+ end
85
+
86
+ def run_local(argv)
87
+ Runner.run docopt, argv: argv, version: version do |args|
88
+ action = find_action(args)
89
+ raise ActionNotFound, 'Cannot find action. Is it properly defined?' unless action
90
+
91
+ action.run args
92
+ end
93
+ end
94
+
95
+ def delegate(name)
96
+ return nil unless delegates.has_key? name
97
+
98
+ result = delegates[name]
99
+ result.context = contexts[name]
100
+ result
101
+ end
102
+
103
+ def meta
104
+ @meta ||= Meta.new
105
+ end
106
+
107
+ def docopt
108
+ @docopt ||= render 'userfile', context: self
109
+ end
110
+ end
111
+ end
@@ -1,3 +1,3 @@
1
1
  module Runfile
2
- VERSION = "0.12.0-rc1"
3
- end
2
+ VERSION = '1.0.0.rc1'
3
+ end
@@ -0,0 +1,28 @@
1
+ > Runfile
2
+ >
3
+ > Local command line for your projects
4
+ >
5
+ > Usage:
6
+ > run new
7
+ > run example [NAME]
8
+ > run --help | -h
9
+ > run --version
10
+ >
11
+ > Commands:
12
+ > nb`new`
13
+ > Create a new runfile in the current directory
14
+ >
15
+ > nb`example`
16
+ > Copy one of the examples to the current directory
17
+ > Run without arguments to see the list of examples
18
+ >
19
+ > Options:
20
+ > --help, -h
21
+ > Show this message
22
+ >
23
+ > --version
24
+ > Show version number
25
+ >
26
+ > Documentation:
27
+ > bu`https://runfile.dannyb.co`
28
+ >
@@ -0,0 +1,93 @@
1
+ if implicit_title
2
+ = implicit_title
3
+ >
4
+ end
5
+
6
+ if summary
7
+ = implicit_title ? word_wrap(" #{summary}") : word_wrap(summary)
8
+ >
9
+ end
10
+
11
+ > Usage:
12
+ actions.each do |name, action|
13
+ action.implicit_usages.each do |usage|
14
+ = " run #{usage}".rstrip
15
+ end
16
+ end
17
+
18
+ delegates.keys.each do |name|
19
+ = " run #{name}"
20
+ end
21
+
22
+ if delegates.any?
23
+ > run [COMMAND] (--help | -h)
24
+ elsif name
25
+ > run {{ name }} (--help | -h)
26
+ else
27
+ > run (--help | -h)
28
+ end
29
+
30
+ if version
31
+ > run --version
32
+ end
33
+ >
34
+
35
+ if commands.any? || delegates.any?
36
+ > Commands:
37
+ commands.each do |action|
38
+ = " nb`#{action.names.join(', ')}`"
39
+ = word_wrap " #{action.help}"
40
+ >
41
+ end
42
+
43
+ delegates.each do |name, userfile|
44
+ summary = userfile.summary || userfile.title ||
45
+ "Run nu`run #{name} --help` for more information"
46
+
47
+ = " nb`#{name}`"
48
+ = word_wrap " #{summary}"
49
+ >
50
+ end
51
+ end
52
+
53
+ if params.any?
54
+ > Parameters:
55
+ params.each do |name, help|
56
+ = " #{name}"
57
+ = word_wrap " #{help}"
58
+ >
59
+ end
60
+ end
61
+
62
+ > Options:
63
+ options.each do |name, help|
64
+ = " #{name}"
65
+ = word_wrap " #{help}"
66
+ >
67
+ end
68
+ > --help, -h
69
+ > Show this message
70
+ >
71
+ if version
72
+ > --version
73
+ > Show version number
74
+ >
75
+ end
76
+
77
+ if env_vars.any?
78
+ > Environment Variables:
79
+ env_vars.each do |name, help|
80
+ = " #{name}"
81
+ = word_wrap " #{help}"
82
+ end
83
+ >
84
+ end
85
+
86
+
87
+ if examples.any?
88
+ > Examples:
89
+ examples.each do |text|
90
+ = word_wrap " #{text}"
91
+ end
92
+ >
93
+ end
data/lib/runfile.rb CHANGED
@@ -1,10 +1,13 @@
1
- require 'runfile/version'
2
- require 'runfile/terminal'
3
- require 'runfile/refinements'
4
- require 'runfile/settings'
5
- require 'runfile/setup'
6
- require 'runfile/docopt_helper'
7
- require 'runfile/runfile_helper'
8
- require 'runfile/action'
9
- require 'runfile/runner'
10
- require 'runfile/dsl'
1
+ require 'gtx'
2
+ require 'docopt'
3
+ require 'colsole'
4
+ require 'requires'
5
+
6
+ requires 'runfile/exceptions'
7
+ requires 'runfile/concerns'
8
+ requires 'runfile'
9
+
10
+ if ENV['BYEBUG']
11
+ require 'byebug'
12
+ require 'lp'
13
+ end
metadata CHANGED
@@ -1,53 +1,127 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: runfile
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.0.pre.rc1
4
+ version: 1.0.0.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: 2021-09-28 00:00:00.000000000 Z
11
+ date: 2023-01-25 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.8.2
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '2.0'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 0.8.2
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '2.0'
13
33
  - !ruby/object:Gem::Dependency
14
34
  name: docopt
15
35
  requirement: !ruby/object:Gem::Requirement
16
36
  requirements:
17
37
  - - "~>"
18
38
  - !ruby/object:Gem::Version
19
- version: '0.5'
39
+ version: '0.6'
20
40
  type: :runtime
21
41
  prerelease: false
22
42
  version_requirements: !ruby/object:Gem::Requirement
23
43
  requirements:
24
44
  - - "~>"
25
45
  - !ruby/object:Gem::Version
26
- version: '0.5'
27
- description: Build command line applications per project with ease. Rake-inspired,
28
- Docopt inside.
46
+ version: '0.6'
47
+ - !ruby/object:Gem::Dependency
48
+ name: gtx
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '0.1'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '0.1'
61
+ - !ruby/object:Gem::Dependency
62
+ name: requires
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: '0.2'
68
+ - - "<"
69
+ - !ruby/object:Gem::Version
70
+ version: '2.0'
71
+ type: :runtime
72
+ prerelease: false
73
+ version_requirements: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: '0.2'
78
+ - - "<"
79
+ - !ruby/object:Gem::Version
80
+ version: '2.0'
81
+ description: Build expressive command line utilities for your projects.
29
82
  email: db@dannyben.com
30
83
  executables:
31
- - run
32
- - run!
84
+ - runn
33
85
  extensions: []
34
86
  extra_rdoc_files: []
35
87
  files:
36
88
  - README.md
37
- - bin/run
38
- - bin/run!
89
+ - bin/runn
90
+ - examples/default-action-2/runfile
91
+ - examples/default-action-2/server.runfile
92
+ - examples/default-action/runfile
93
+ - examples/different-name/runfile.rb
94
+ - examples/example-multiline/runfile
95
+ - examples/example/runfile
96
+ - examples/execute/runfile
97
+ - examples/execute/server.runfile
98
+ - examples/full/runfile
99
+ - examples/import/more_tasks/spec.runfile
100
+ - examples/import/runfile
101
+ - examples/import/tasks/server.runfile
102
+ - examples/minimal/runfile
103
+ - examples/multiple-runfiles/runfile
104
+ - examples/multiple-runfiles/server.runfile
105
+ - examples/named-only/deploy.runfile
106
+ - examples/named-only/server.runfile
107
+ - examples/naval-fate/runfile
108
+ - examples/shortcut/runfile
39
109
  - lib/runfile.rb
40
110
  - lib/runfile/action.rb
41
- - lib/runfile/docopt_helper.rb
42
- - lib/runfile/dsl.rb
43
- - lib/runfile/refinements.rb
44
- - lib/runfile/runfile_helper.rb
111
+ - lib/runfile/concerns/dsl.rb
112
+ - lib/runfile/concerns/inspectable.rb
113
+ - lib/runfile/concerns/renderable.rb
114
+ - lib/runfile/entrypoint.rb
115
+ - lib/runfile/exceptions.rb
116
+ - lib/runfile/gem_finder.rb
117
+ - lib/runfile/initiator.rb
118
+ - lib/runfile/meta.rb
45
119
  - lib/runfile/runner.rb
46
- - lib/runfile/settings.rb
47
- - lib/runfile/setup.rb
48
- - lib/runfile/templates/Runfile
49
- - lib/runfile/terminal.rb
120
+ - lib/runfile/templates/runfile
121
+ - lib/runfile/userfile.rb
50
122
  - lib/runfile/version.rb
123
+ - lib/runfile/views/initiator.gtx
124
+ - lib/runfile/views/userfile.gtx
51
125
  homepage: https://github.com/DannyBen/runfile
52
126
  licenses:
53
127
  - MIT
@@ -56,6 +130,7 @@ metadata:
56
130
  changelog_uri: https://github.com/DannyBen/runfile/blob/master/CHANGELOG.md
57
131
  source_code_uri: https://github.com/DannyBen/runfile
58
132
  bug_tracker_uri: https://github.com/DannyBen/runfile/issues
133
+ rubygems_mfa_required: 'true'
59
134
  post_install_message:
60
135
  rdoc_options: []
61
136
  require_paths:
@@ -64,15 +139,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
64
139
  requirements:
65
140
  - - ">="
66
141
  - !ruby/object:Gem::Version
67
- version: 2.4.0
142
+ version: '2.7'
68
143
  required_rubygems_version: !ruby/object:Gem::Requirement
69
144
  requirements:
70
145
  - - ">"
71
146
  - !ruby/object:Gem::Version
72
147
  version: 1.3.1
73
148
  requirements: []
74
- rubygems_version: 3.2.25
149
+ rubygems_version: 3.4.5
75
150
  signing_key:
76
151
  specification_version: 4
77
- summary: If Rake and Docopt had a baby
152
+ summary: Local command line for your projects
78
153
  test_files: []
data/bin/run DELETED
@@ -1,10 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require 'runfile'
4
-
5
- # for dev
6
- # require File.dirname(__FILE__) + "/../lib/runfile"
7
-
8
- include Runfile::DSL
9
-
10
- Runfile::Runner.instance.execute ARGV
data/bin/run! DELETED
@@ -1,16 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- # This is needed in cases when you are running "run!" from a folder
4
- # that contains a Gemfile on a machine with RVM.
5
- # It will disable attempting to run in the current context
6
- # Source: https://rvm.io/integration/bundler
7
- ENV['NOEXEC_DISABLE'] = '1'
8
-
9
- require 'runfile'
10
-
11
- # for dev
12
- # require File.dirname(__FILE__) + "/../lib/runfile"
13
-
14
- include Runfile::DSL
15
-
16
- Runfile::Runner.instance.execute ARGV, false
@@ -1,128 +0,0 @@
1
- require 'docopt'
2
-
3
- module Runfile
4
- # The DocoptHelper class handles the dynamic generation of the
5
- # docopt document and the docopt part of the execution (meaning,
6
- # to call Docopt so it returns the parsed arguments or halts with
7
- # usage message).
8
- class DocoptHelper
9
- using Refinements
10
-
11
- # The constructor expects to an object that responds to all the
12
- # textual details needed to generate a docopt document (name, version,
13
- # summary, options) and an array of Action objects.
14
- # The superspace argument will be the name of runfile, in case we
15
- # are running a named.runfile. It is only needed to generate the
16
- # proper `run superspace (-h|--help|--version)` line
17
- def initialize(options)
18
- @superspace = options.superspace
19
- @name = options.name
20
- @version = options.version
21
- @summary = options.summary
22
- @actions = options.actions
23
- @options = options.options
24
- @params = options.params
25
- @env_vars = options.env_vars
26
- @examples = options.examples
27
- end
28
-
29
- # Generate a document based on all the actions, help messages
30
- # and options we have collected from the Runfile DSL.
31
- def docopt
32
- width = Terminal.width
33
- doc = []
34
- doc << (@version ? "#{@name} #{@version}" : "#{@name}")
35
- doc << "#{@summary}" if @summary
36
- doc += docopt_usage
37
- doc += docopt_commands width
38
- doc += docopt_options width
39
- doc += docopt_params width
40
- doc += docopt_env_vars width
41
- doc += docopt_examples width
42
- doc.join "\n"
43
- end
44
-
45
- # Return all docopt lines for the 'Usage' section
46
- def docopt_usage
47
- doc = ["\nUsage:"];
48
- @actions.each do |_name, action|
49
- doc << " run #{action.usage}" unless action.usage == false
50
- end
51
- basic_flags = @version ? "(-h|--help|--version)" : "(-h|--help)"
52
- if @superspace
53
- doc << " run #{@superspace} #{basic_flags}\n"
54
- else
55
- doc << " run #{basic_flags}\n"
56
- end
57
- doc
58
- end
59
-
60
- # Return all docopt lines for the 'Commands' section
61
- def docopt_commands(width)
62
- doc = []
63
- caption_printed = false
64
- @actions.each do |_name, action|
65
- action.help or next
66
- doc << "Commands:" unless caption_printed
67
- caption_printed = true
68
- helpline = " #{action.help}"
69
- wrapped = helpline.word_wrap width
70
- doc << " #{action.usage}\n#{wrapped}\n" unless action.usage == false
71
- end
72
- doc
73
- end
74
-
75
- # Return all docopt lines for the various 'Options' sections
76
- def docopt_options(width)
77
- @options['Options'] = {} unless @options['Options']
78
- @options['Options']['-h --help'] = 'Show this screen'
79
- @options['Options']['--version'] = 'Show version number' if @version
80
- section_block @options, width
81
- end
82
-
83
- # Return all docopt params for 'Params' section
84
- def docopt_params(width)
85
- section_block @params, width
86
- end
87
-
88
- # Return all docopt params for 'Environment Variables' section
89
- def docopt_env_vars(width)
90
- section_block @env_vars, width
91
- end
92
-
93
- # Return all docopt lines for the 'Examples' section
94
- def docopt_examples(width)
95
- return [] if @examples.empty?
96
-
97
- doc = ["Examples:"]
98
- base_command = @superspace ? "run #{@superspace}" : "run"
99
- @examples.each do |command|
100
- helpline = " #{base_command} #{command}"
101
- wrapped = helpline.word_wrap width
102
- doc << "#{wrapped}"
103
- end
104
- doc
105
- end
106
-
107
- # Return a generic block containing scope section (e.g. "Options"),
108
- # followed by key value paragraphs.
109
- def section_block(definitions, width)
110
- doc = []
111
- definitions.each do |scope, values|
112
- doc << "#{scope}:"
113
- values.each do |label, text|
114
- helpline = " #{text}"
115
- wrapped = helpline.word_wrap width
116
- doc << " #{label}\n#{wrapped}\n"
117
- end
118
- end
119
- doc
120
- end
121
-
122
- # Call the docopt handler, which will either return a parsed
123
- # arguments list, or halt execution and show usage.
124
- def args(argv)
125
- Docopt.docopt(docopt, version: @version, argv:argv)
126
- end
127
- end
128
- end
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