cli-mastermind 0.5.1 → 0.6.0

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: 14bea90e61e0acaf588c50485fc37947c376b5778d9a7e8752b948a540d94f44
4
- data.tar.gz: cdd0b63de45746a2b5df33e72245b20037adcf89665bb98c2c5200f58de2c3c1
3
+ metadata.gz: 9078a8e331150ebe62b1ecf44270422c93855b869510f34d57e983895a3b7fcf
4
+ data.tar.gz: c7bb2f6a630aa6b62319e409f238b88a1a81a4baa3a8e76737b1290e15efd2fc
5
5
  SHA512:
6
- metadata.gz: 29adefa5c6f7a489071af7c726671788b8a3d38b37c4d7af5d53cd24346bc9a2a319fb5fd526734902182d9c06dfa0fae3550d7514cc9e51b534d20b775be03d
7
- data.tar.gz: cafc5940e66d5a756251aa09ec43cc1cb141111eb59be05d145f909db6f3c6a50b391aaf3315abce85ac757ae713ab298e51f47e002bf8c66f3341a4f65460bb
6
+ metadata.gz: 1ec54b9f8e61defa6dd76c40cdd6d46fbba1afb6e173e47f25e0042ed69b7ca4ae32d4dd75ca924af55c22f4a10e2f4f22d2ab907f71abac789e9b08248ed7f9
7
+ data.tar.gz: ef03260db00aa0062ed9514ae5bd6e201274d89778dccafa1f74b94c1bf2566665513e4ae4fd638b1c717e1586990275d3c4786a3952b721d6bd74849c3a4554
@@ -1,4 +1,5 @@
1
1
  # coding: utf-8
2
+ require 'forwardable'
2
3
  require 'cli/ui'
3
4
  require 'cli/mastermind/arg_parse'
4
5
  require 'cli/mastermind/configuration'
@@ -104,34 +105,44 @@ module CLI
104
105
 
105
106
  unless @plans.empty?
106
107
  frame('Plans') do
107
- display_plans
108
+ puts build_display_string
108
109
  end
109
110
  else
110
111
  puts stylize("{{x}} No plans match #{@arguments.pattern.source}")
111
112
  end
112
113
  end
113
114
 
114
- def display_plans(plans=@plans, prefix='')
115
+ def build_display_string(plans=@plans, prefix='')
115
116
  fade_code = CLI::UI::Color.new(90, '').code
117
+ reset = CLI::UI::Color::RESET.code
118
+
119
+ display_string = ''
116
120
 
117
121
  plans.each do |(name, plan)|
118
122
  next unless plan.has_children? or plan.description
119
123
 
120
- print prefix + '• '
121
- puts stylize("{{yellow:#{titleize(name)} #{fade_code}(#{name})#{CLI::UI::Color::RESET.code}")
124
+ display_string += prefix + '• '
125
+ display_string += stylize("{{yellow:#{titleize(name)} #{fade_code}(#{name})#{reset}\n")
122
126
 
123
127
  if plan.aliases.any?
124
- puts prefix + " - #{fade_code}aliases: #{plan.aliases.to_a.join(', ')}#{CLI::UI::Color::RESET.code}"
128
+ display_string += prefix + " - #{fade_code}aliases: #{plan.aliases.to_a.join(', ')}#{reset}\n"
125
129
  end
126
130
 
127
131
  if plan.description
128
- print prefix + ' - '
129
- puts stylize("{{blue:#{plan.description}}}")
132
+ display_string += prefix + ' - '
133
+ display_string += stylize("{{blue:#{plan.description}}}\n")
130
134
  end
131
135
 
132
- display_plans(plan.children, " " + prefix) if plan.has_children?
133
- print "\n"
136
+ if plan.has_children?
137
+ display_string += "\n"
138
+ display_string += build_display_string(plan.children, " " + prefix)
139
+ end
140
+
141
+ display_string += "\n"
134
142
  end
143
+
144
+ # Collapse any run of three or more newlines into just two
145
+ display_string.gsub(/\n{3,}/, "\n\n")
135
146
  end
136
147
 
137
148
  def filter_plans(pattern, plans=@plans)
@@ -15,6 +15,8 @@ module CLI
15
15
  # _last_. You can use this to specify plans you want accessible everywhere
16
16
  # or global configuration that should apply everywhere (unless overridden by
17
17
  # more specific masterplans).
18
+ #
19
+ # @see Configuration::DSL
18
20
  class Configuration
19
21
  # Filename of masterplan files
20
22
  PLANFILE = '.masterplan'
@@ -144,6 +146,10 @@ module CLI
144
146
  end
145
147
  end
146
148
 
149
+ # Describes the DSL used in masterplan files.
150
+ #
151
+ # See the .masterplan file in the root of this repo for a full example of
152
+ # the available options.
147
153
  class DSL
148
154
  def initialize(config, filename)
149
155
  @config = config
@@ -154,26 +160,48 @@ module CLI
154
160
  # Specifies that another masterplan should also be loaded when loading
155
161
  # this masterplan. NOTE: This _immediately_ loads the other masterplan.
156
162
  def see_also(filename)
157
- @config.load_masterplan(filename)
163
+ @config.load_masterplan(File.expand_path(filename))
158
164
  end
159
165
 
160
- # With no arguments, specifies that the current directory containing this
161
- # masterplan is at the root of your project. Otherwise, specifies the root
162
- # of the project.
163
- def project_root(root = File.dirname(@filename))
166
+ # Specifies the root of the project.
167
+ # +root+ must be a directory.
168
+ def project_root(root)
169
+ unless Dir.exist? root
170
+ raise InvalidDirectoryError.new('Invalid project root', root)
171
+ end
172
+
164
173
  @config.project_root = root
165
174
  end
166
- alias_method :at_project_root, :project_root
167
175
 
168
- # With no arguments, specifies that plans exist in a /plans/ directory
169
- # under the directory the masterplan is in.
170
- def plan_files(directory = File.join(File.dirname(@filename), 'plans'))
171
- @config.add_plans(Dir.glob(File.join(directory, '**', "*{#{supported_extensions}}")))
176
+ # Syntactic sugar on top of `project_root` to specify that the current
177
+ # masterplan resides in the root of the project.
178
+ def at_project_root
179
+ project_root File.dirname(@filename)
180
+ end
181
+
182
+ # Specify that plans exist in the given +directory+.
183
+ # Must be a valid directory
184
+ def plan_files(directory)
185
+ unless Dir.exist? directory
186
+ raise InvalidDirectoryError.new('Invalid plan file directory', directory)
187
+ end
188
+
189
+ planfiles = Dir.glob(File.join(directory, '**', "*{#{supported_extensions}}"))
190
+ planfiles.map! { |file| File.expand_path(file) }
191
+
192
+ @config.add_plans(planfiles)
193
+ end
194
+
195
+ # Syntactic sugar on top of `plan_files` to specify that plans exist in
196
+ # a +plans/+ directory in the current directory.
197
+ def has_plan_files
198
+ plan_files File.join(File.dirname(@filename), 'plans')
172
199
  end
173
- alias_method :has_plan_files, :plan_files
174
200
 
175
201
  # Specifies that a specific plan file exists at the given +filename+.
176
202
  def plan_file(*files)
203
+ files = files.map { |file| File.expand_path file }
204
+
177
205
  @config.add_plans(files)
178
206
  end
179
207
 
@@ -11,5 +11,11 @@ module CLI
11
11
 
12
12
  class InvalidPlanError < Error
13
13
  end
14
+
15
+ class InvalidDirectoryError < Error
16
+ def initialize(message, directory)
17
+ super "#{message}: #{directory} does not exist or is not a directory"
18
+ end
19
+ end
14
20
  end
15
21
  end
@@ -13,6 +13,8 @@ module CLI::Mastermind
13
13
  private
14
14
 
15
15
  class DSL
16
+ extend Forwardable
17
+
16
18
  attr_reader :plans
17
19
 
18
20
  def initialize(filename=nil, &block)
@@ -50,6 +52,12 @@ module CLI::Mastermind
50
52
  def set_alias(alias_to)
51
53
  @plans.last.add_alias(alias_to)
52
54
  end
55
+
56
+ # Delegate configuration to the top-level configuration object
57
+ # Planfile loading happens well after configuration has been loaded. So,
58
+ # we can safely rely on it being setup at this point.
59
+ def_delegator :'CLI::Mastermind', :configuration
60
+ alias_method :config, :configuration
53
61
  end
54
62
  end
55
63
  end
@@ -1,4 +1,3 @@
1
- require 'forwardable'
2
1
  require 'cli/mastermind/plan/interface'
3
2
 
4
3
  module CLI
@@ -7,8 +7,8 @@ module CLI
7
7
 
8
8
  module VERSION
9
9
  RELEASE = 0
10
- MAJOR = 5
11
- MINOR = 1
10
+ MAJOR = 6
11
+ MINOR = 0
12
12
  PATCH = nil
13
13
 
14
14
  STRING = [RELEASE, MAJOR, MINOR, PATCH].compact.join('.').freeze
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cli-mastermind
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chris Hall
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-03-06 00:00:00.000000000 Z
11
+ date: 2019-03-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: cli-ui