freyia 0.5.3 → 0.6.1

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.
@@ -5,8 +5,8 @@ require_relative "line_editor/readline"
5
5
 
6
6
  module Freyia
7
7
  module LineEditor
8
- def self.readline(prompt, options = {})
9
- best_available.new(prompt, options).readline
8
+ def self.readline(prompt, **)
9
+ best_available.new(prompt, **).readline
10
10
  end
11
11
 
12
12
  def self.best_available
@@ -80,14 +80,13 @@ module Freyia
80
80
  #
81
81
  # ask "Where should the file be saved?", path: true
82
82
  #
83
- def ask(statement, *args)
84
- options = args.last.is_a?(Hash) ? args.pop : {}
83
+ def ask(statement, *args, **options)
85
84
  color = args.first
86
85
 
87
86
  if options[:limited_to]
88
- ask_filtered(statement, color, options)
87
+ ask_filtered(statement, color, **options)
89
88
  else
90
- ask_simply(statement, color, options)
89
+ ask_simply(statement, color, **options)
91
90
  end
92
91
  end
93
92
 
@@ -181,8 +180,8 @@ module Freyia
181
180
  # colwidth<Integer>:: Force the first column to colwidth spaces wide.
182
181
  # borders<Boolean>:: Adds ascii borders.
183
182
  #
184
- def print_table(array, options = {})
185
- printer = TablePrinter.new(stdout, options)
183
+ def print_table(array, **)
184
+ printer = TablePrinter.new(stdout, **)
186
185
  printer.print(array)
187
186
  end
188
187
 
@@ -195,8 +194,8 @@ module Freyia
195
194
  # ==== Options
196
195
  # indent<Integer>:: Indent each line of the printed paragraph by indent value.
197
196
  #
198
- def print_wrapped(message, options = {})
199
- printer = WrappedPrinter.new(stdout, options)
197
+ def print_wrapped(message, **)
198
+ printer = WrappedPrinter.new(stdout, **)
200
199
  printer.print(message)
201
200
  end
202
201
 
@@ -260,7 +259,7 @@ module Freyia
260
259
  # Apply color to the given string with optional bold. Disabled in the
261
260
  # Freyia::Shell::Basic class.
262
261
  #
263
- def set_color(string, *) #:nodoc:
262
+ def set_color(string, *)
264
263
  string
265
264
  end
266
265
 
@@ -289,7 +288,7 @@ module Freyia
289
288
  $stderr
290
289
  end
291
290
 
292
- def is?(value) #:nodoc: # rubocop:disable Naming/PredicateMethod
291
+ def is?(value) # rubocop:disable Naming/PredicateMethod
293
292
  value = value.to_s
294
293
 
295
294
  if value.size == 1
@@ -299,7 +298,7 @@ module Freyia
299
298
  end
300
299
  end
301
300
 
302
- def file_collision_help(block_given) #:nodoc:
301
+ def file_collision_help(block_given)
303
302
  help = <<-HELP
304
303
  Y - yes, overwrite
305
304
  n - no, do not overwrite
@@ -316,7 +315,7 @@ module Freyia
316
315
  help
317
316
  end
318
317
 
319
- def show_diff(destination, content) #:nodoc:
318
+ def show_diff(destination, content)
320
319
  require "tempfile"
321
320
  Tempfile.open(File.basename(destination), File.dirname(destination),
322
321
  binmode: true) do |temp|
@@ -326,7 +325,7 @@ module Freyia
326
325
  end
327
326
  end
328
327
 
329
- def quiet? #:nodoc:
328
+ def quiet?
330
329
  mute? || (base && base.options[:quiet])
331
330
  end
332
331
 
@@ -334,11 +333,11 @@ module Freyia
334
333
  Terminal.unix?
335
334
  end
336
335
 
337
- def ask_simply(statement, color, options)
336
+ def ask_simply(statement, color, **options)
338
337
  default = options[:default]
339
338
  message = [statement, ("(#{default})" if default), nil].uniq.join(" ")
340
339
  message = prepare_message(message, *color)
341
- result = Freyia::LineEditor.readline(message, options)
340
+ result = Freyia::LineEditor.readline(message, **options)
342
341
 
343
342
  return unless result
344
343
 
@@ -351,13 +350,13 @@ module Freyia
351
350
  end
352
351
  end
353
352
 
354
- def ask_filtered(statement, color, options)
353
+ def ask_filtered(statement, color, **options)
355
354
  answer_set = options[:limited_to]
356
355
  case_insensitive = options.fetch(:case_insensitive, false)
357
356
  correct_answer = nil
358
357
  until correct_answer
359
358
  answers = answer_set.join(", ")
360
- answer = ask_simply("#{statement} [#{answers}]", color, options)
359
+ answer = ask_simply("#{statement} [#{answers}]", color, **options)
361
360
  correct_answer = answer_match(answer_set, answer, case_insensitive)
362
361
  say("Your response must be one of: [#{answers}]. Please try again.") unless correct_answer
363
362
  end
@@ -372,7 +371,7 @@ module Freyia
372
371
  end
373
372
  end
374
373
 
375
- def merge(destination, content) #:nodoc:
374
+ def merge(destination, content)
376
375
  require "tempfile"
377
376
  Tempfile.open([File.basename(destination), File.extname(destination)],
378
377
  File.dirname(destination)) do |temp|
@@ -382,14 +381,14 @@ module Freyia
382
381
  end
383
382
  end
384
383
 
385
- def merge_tool #:nodoc:
384
+ def merge_tool
386
385
  @merge_tool ||= begin
387
386
  require "shellwords"
388
387
  Shellwords.split(ENV["FREYIA_MERGE"] || "git difftool --no-index")
389
388
  end
390
389
  end
391
390
 
392
- def diff_tool #:nodoc:
391
+ def diff_tool
393
392
  @diff_cmd ||= begin
394
393
  require "shellwords"
395
394
  Shellwords.split(ENV["FREYIA_DIFF"] || ENV["RAILS_DIFF"] || "diff -u")
@@ -11,6 +11,12 @@ module Freyia
11
11
  class Color < Basic
12
12
  include LCSDiff
13
13
 
14
+ ANSI_ESCAPE = format("%c", 27)
15
+
16
+ # NOTE: the following is tweaked from Bridgetown Foundation's regex because we need to
17
+ # be able to count the number within the escape sequence
18
+ ANSI_MATCH = %r!#{ANSI_ESCAPE}\[([0-9;]*)(j|k|m|s|u|A|B|G)|\e\(B\e\[m!ix
19
+
14
20
  # Embed in a String to clear all previous ANSI sequences.
15
21
  CLEAR = "\e[0m"
16
22
  # The start of an ANSI bold sequence.
@@ -99,6 +105,11 @@ module Freyia
99
105
  end
100
106
  end
101
107
 
108
+ # Strip ANSI from the current string. It also strips cursor stuff,
109
+ # well some of it, and it also strips some other stuff that a lot of
110
+ # the other ANSI strippers don't.
111
+ def self.strip_ansi(str) = str.gsub(ANSI_MATCH, "")
112
+
102
113
  protected
103
114
 
104
115
  def can_display_colors?
@@ -7,7 +7,7 @@ module Freyia
7
7
  class ColumnPrinter
8
8
  attr_reader :stdout, :options
9
9
 
10
- def initialize(stdout, options = {})
10
+ def initialize(stdout, **options)
11
11
  @stdout = stdout
12
12
  @options = options
13
13
  @indent = options[:indent].to_i
@@ -5,7 +5,7 @@ module LCSDiff
5
5
 
6
6
  # Overwrite show_diff to show diff with colors if Diff::LCS is
7
7
  # available.
8
- def show_diff(destination, content) #:nodoc:
8
+ def show_diff(destination, content)
9
9
  if diff_lcs_loaded? && ENV["FREYIA_DIFF"].nil? && ENV["RAILS_DIFF"].nil?
10
10
  actual = File.binread(destination).to_s.split("\n")
11
11
  content = content.to_s.split("\n")
@@ -20,7 +20,7 @@ module LCSDiff
20
20
 
21
21
  private
22
22
 
23
- def output_diff_line(diff) #:nodoc:
23
+ def output_diff_line(diff)
24
24
  case diff.action
25
25
  when "-"
26
26
  say "- #{diff.old_element.chomp}", :red, true
@@ -36,7 +36,7 @@ module LCSDiff
36
36
 
37
37
  # Check if Diff::LCS is loaded. If it is, use it to create pretty output
38
38
  # for diff.
39
- def diff_lcs_loaded? #:nodoc:
39
+ def diff_lcs_loaded?
40
40
  return true if defined?(Diff::LCS)
41
41
  return @diff_lcs_loaded unless @diff_lcs_loaded.nil?
42
42
 
@@ -5,15 +5,23 @@ require_relative "terminal"
5
5
 
6
6
  module Freyia
7
7
  module Shell
8
- class TablePrinter < ColumnPrinter
8
+ class TablePrinter
9
9
  BORDER_SEPARATOR = :separator
10
10
 
11
- def initialize(stdout, options = {})
12
- super
11
+ # @return [IO]
12
+ attr_reader :stdout
13
+
14
+ # @return [Boolean]
15
+ attr_reader :borders
16
+
17
+ def initialize(stdout, indent: 0, colwidth: nil, truncate: false, borders: false) # rubocop:disable Metrics/ParameterLists
18
+ @stdout = stdout
19
+ @indent = indent.to_i
13
20
  @formats = []
14
21
  @maximas = []
15
- @colwidth = options[:colwidth]
16
- @truncate = options[:truncate] == true ? Terminal.terminal_width : options[:truncate]
22
+ @colwidth = colwidth
23
+ @truncate = truncate == true ? Terminal.terminal_width : truncate
24
+ @borders = borders
17
25
  @padding = 1
18
26
  end
19
27
 
@@ -22,10 +30,10 @@ module Freyia
22
30
 
23
31
  prepare(array)
24
32
 
25
- print_border_separator if options[:borders]
33
+ print_border_separator if borders
26
34
 
27
35
  array.each do |row|
28
- if options[:borders] && row == BORDER_SEPARATOR
36
+ if borders && row == BORDER_SEPARATOR
29
37
  print_border_separator
30
38
  next
31
39
  end
@@ -37,10 +45,10 @@ module Freyia
37
45
  end
38
46
 
39
47
  sentence = truncate(sentence)
40
- sentence << "|" if options[:borders]
48
+ sentence << "|" if borders
41
49
  stdout.puts indentation + sentence
42
50
  end
43
- print_border_separator if options[:borders]
51
+ print_border_separator if borders
44
52
  end
45
53
 
46
54
  private
@@ -54,10 +62,12 @@ module Freyia
54
62
  colcount = array.max_by(&:size).size
55
63
 
56
64
  start.upto(colcount - 1) do |index|
57
- maxima = array.map { |row| row[index] ? row[index].to_s.size : 0 }.max
65
+ maxima = array.map do |row|
66
+ row[index] ? Shell::Color.strip_ansi(row[index].to_s).size : 0
67
+ end.max
58
68
 
59
69
  @maximas << maxima
60
- @formats << if options[:borders]
70
+ @formats << if borders
61
71
  "%-#{maxima}s"
62
72
  elsif index == colcount - 1
63
73
  # Don't output 2 trailing spaces when printing the last column
@@ -74,7 +84,7 @@ module Freyia
74
84
  maxima = @maximas[index]
75
85
 
76
86
  f = if column.is_a?(Numeric)
77
- if options[:borders]
87
+ if borders
78
88
  # With borders we handle padding separately
79
89
  "%#{maxima}s"
80
90
  elsif index == row_size - 1 # rubocop:disable Lint/DuplicateBranch
@@ -84,13 +94,13 @@ module Freyia
84
94
  "%#{maxima}s "
85
95
  end
86
96
  else
87
- @formats[index]
97
+ adjust_for_ansi_codes @formats[index], column
88
98
  end
89
99
 
90
100
  cell = +""
91
- cell << "|#{" " * @padding}" if options[:borders]
101
+ cell << "|#{" " * @padding}" if borders
92
102
  cell << (f % column.to_s)
93
- cell << (" " * @padding) if options[:borders]
103
+ cell << (" " * @padding) if borders
94
104
  cell
95
105
  end
96
106
 
@@ -115,6 +125,20 @@ module Freyia
115
125
  def indentation
116
126
  " " * @indent
117
127
  end
128
+
129
+ def adjust_for_ansi_codes(format, column)
130
+ column_string = column.to_s
131
+ if column_string =~ Shell::Color::ANSI_MATCH
132
+ codes_count = column_string.scan(Shell::Color::ANSI_MATCH).sum do |match|
133
+ match[0].length + 3
134
+ end
135
+ format.gsub(%r!(\d+)s!) do
136
+ "#{Regexp.last_match[1].to_i + codes_count}s"
137
+ end
138
+ else
139
+ format
140
+ end
141
+ end
118
142
  end
119
143
  end
120
144
  end
data/lib/freyia/shell.rb CHANGED
@@ -13,8 +13,8 @@ module Freyia
13
13
  # Common methods that are delegated to the shell.
14
14
  SHELL_DELEGATED_METHODS.each do |method|
15
15
  module_eval <<-METHOD, __FILE__, __LINE__ + 1 # rubocop:disable Style/DocumentDynamicEvalDefinition
16
- def #{method}(*args,&block)
17
- shell.#{method}(*args,&block)
16
+ def #{method}(*args, **kwargs, &block)
17
+ shell.#{method}(*args, **kwargs, &block)
18
18
  end
19
19
  METHOD
20
20
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Freyia
4
- VERSION = "0.5.3"
4
+ VERSION = "0.6.1"
5
5
  end
data/lib/freyia.rb CHANGED
@@ -4,7 +4,6 @@ require_relative "freyia/version"
4
4
 
5
5
  module Freyia
6
6
  class Error < StandardError; end
7
- # Your code goes here...
8
7
 
9
8
  TEMPLATE_EXTNAME = ".tmpl"
10
9
  end
@@ -30,6 +29,15 @@ module Freyia::Setup
30
29
  Freyia::Shell::Color
31
30
  end
32
31
  end
32
+
33
+ # Set or return the `template` type for the Freyia base. Defaults to `:erb`
34
+ #
35
+ # @param type [Symbol] either `:erb` or `:serbea`
36
+ # @return [Symbol] if called without an argument, returns the template type
37
+ def template_type(type = nil)
38
+ @template_type ||= :erb
39
+ type ? @template_type = type : @template_type
40
+ end
33
41
  end
34
42
 
35
43
  def self.included(klass)
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: freyia
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.3
4
+ version: 0.6.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jared White
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2025-11-21 00:00:00.000000000 Z
10
+ date: 2025-12-18 00:00:00.000000000 Z
11
11
  dependencies: []
12
12
  description: Define and execute automated tasks like the party girl you are.
13
13
  email: