freyia 0.5.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.
@@ -0,0 +1,120 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "column_printer"
4
+ require_relative "terminal"
5
+
6
+ module Freyia
7
+ module Shell
8
+ class TablePrinter < ColumnPrinter
9
+ BORDER_SEPARATOR = :separator
10
+
11
+ def initialize(stdout, options = {})
12
+ super
13
+ @formats = []
14
+ @maximas = []
15
+ @colwidth = options[:colwidth]
16
+ @truncate = options[:truncate] == true ? Terminal.terminal_width : options[:truncate]
17
+ @padding = 1
18
+ end
19
+
20
+ def print(array) # rubocop:todo Metrics
21
+ return if array.empty?
22
+
23
+ prepare(array)
24
+
25
+ print_border_separator if options[:borders]
26
+
27
+ array.each do |row|
28
+ if options[:borders] && row == BORDER_SEPARATOR
29
+ print_border_separator
30
+ next
31
+ end
32
+
33
+ sentence = +""
34
+
35
+ row.each_with_index do |column, index|
36
+ sentence << format_cell(column, row.size, index)
37
+ end
38
+
39
+ sentence = truncate(sentence)
40
+ sentence << "|" if options[:borders]
41
+ stdout.puts indentation + sentence
42
+ end
43
+ print_border_separator if options[:borders]
44
+ end
45
+
46
+ private
47
+
48
+ def prepare(array) # rubocop:todo Metrics
49
+ array = array.reject { |row| row == BORDER_SEPARATOR }
50
+
51
+ @formats << "%-#{@colwidth + 2}s" if @colwidth
52
+ start = @colwidth ? 1 : 0
53
+
54
+ colcount = array.max_by(&:size).size
55
+
56
+ start.upto(colcount - 1) do |index|
57
+ maxima = array.map { |row| row[index] ? row[index].to_s.size : 0 }.max
58
+
59
+ @maximas << maxima
60
+ @formats << if options[:borders]
61
+ "%-#{maxima}s"
62
+ elsif index == colcount - 1
63
+ # Don't output 2 trailing spaces when printing the last column
64
+ +"%-s"
65
+ else
66
+ "%-#{maxima + 2}s"
67
+ end
68
+ end
69
+
70
+ @formats << "%s"
71
+ end
72
+
73
+ def format_cell(column, row_size, index)
74
+ maxima = @maximas[index]
75
+
76
+ f = if column.is_a?(Numeric)
77
+ if options[:borders]
78
+ # With borders we handle padding separately
79
+ "%#{maxima}s"
80
+ elsif index == row_size - 1 # rubocop:disable Lint/DuplicateBranch
81
+ # Don't output 2 trailing spaces when printing the last column
82
+ "%#{maxima}s"
83
+ else
84
+ "%#{maxima}s "
85
+ end
86
+ else
87
+ @formats[index]
88
+ end
89
+
90
+ cell = +""
91
+ cell << "|#{" " * @padding}" if options[:borders]
92
+ cell << (f % column.to_s)
93
+ cell << (" " * @padding) if options[:borders]
94
+ cell
95
+ end
96
+
97
+ def print_border_separator
98
+ separator = @maximas.map do |maxima|
99
+ "+#{"-" * (maxima + (2 * @padding))}"
100
+ end
101
+ stdout.puts "#{indentation}#{separator.join}+"
102
+ end
103
+
104
+ def truncate(string)
105
+ return string unless @truncate
106
+
107
+ chars = string.chars.to_a
108
+ if chars.length <= @truncate
109
+ chars.join
110
+ else
111
+ "#{chars[0, @truncate - 3 - @indent].join}..."
112
+ end
113
+ end
114
+
115
+ def indentation
116
+ " " * @indent
117
+ end
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Freyia
4
+ module Shell
5
+ module Terminal
6
+ DEFAULT_TERMINAL_WIDTH = 80
7
+
8
+ class << self
9
+ # This code was copied from Rake, available under MIT-LICENSE
10
+ # Copyright (c) 2003, 2004 Jim Weirich
11
+ def terminal_width
12
+ result = if ENV["FREYIA_COLUMNS"]
13
+ ENV["FREYIA_COLUMNS"].to_i
14
+ else
15
+ unix? ? dynamic_width : DEFAULT_TERMINAL_WIDTH
16
+ end
17
+ result < 10 ? DEFAULT_TERMINAL_WIDTH : result
18
+ rescue StandardError
19
+ DEFAULT_TERMINAL_WIDTH
20
+ end
21
+
22
+ def unix?
23
+ RUBY_PLATFORM =~ %r{(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris)}i
24
+ end
25
+
26
+ private
27
+
28
+ # Calculate the dynamic width of the terminal
29
+ def dynamic_width
30
+ @dynamic_width ||= dynamic_width_stty.nonzero? || dynamic_width_tput
31
+ end
32
+
33
+ def dynamic_width_stty
34
+ `stty size 2>/dev/null`.split[1].to_i
35
+ end
36
+
37
+ def dynamic_width_tput
38
+ `tput cols 2>/dev/null`.to_i
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "column_printer"
4
+ require_relative "terminal"
5
+
6
+ module Freyia
7
+ module Shell
8
+ class WrappedPrinter < ColumnPrinter
9
+ def print(message) # rubocop:todo Metrics
10
+ width = Terminal.terminal_width - @indent
11
+ paras = message.split("\n\n")
12
+
13
+ paras.map! do |unwrapped|
14
+ words = unwrapped.split
15
+ counter = words.first.length
16
+ words.inject do |memo, word|
17
+ word = word.gsub(%r{\n\005}, "\n").gsub(%r{\005}, "\n")
18
+ counter = 0 if word.include? "\n"
19
+ if (counter + word.length + 1) < width
20
+ memo = "#{memo} #{word}"
21
+ counter += (word.length + 1)
22
+ else
23
+ memo = "#{memo}\n#{word}"
24
+ counter = word.length
25
+ end
26
+ memo
27
+ end
28
+ end.compact!
29
+
30
+ paras.each do |para|
31
+ para.split("\n").each do |line|
32
+ stdout.puts line.insert(0, " " * @indent)
33
+ end
34
+ stdout.puts unless para == paras.last
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rbconfig"
4
+
5
+ module Freyia
6
+ module Shell
7
+ SHELL_DELEGATED_METHODS = [:ask, :error, :set_color, :yes?, :no?, :say, :say_error,
8
+ :say_status, :print_in_columns, :print_table, :print_wrapped,
9
+ :file_collision, :terminal_width,].freeze
10
+
11
+ autoload :Basic, File.expand_path("shell/basic", __dir__)
12
+ autoload :Color, File.expand_path("shell/color", __dir__)
13
+ # Common methods that are delegated to the shell.
14
+ SHELL_DELEGATED_METHODS.each do |method|
15
+ module_eval <<-METHOD, __FILE__, __LINE__ + 1 # rubocop:disable Style/DocumentDynamicEvalDefinition
16
+ def #{method}(*args,&block)
17
+ shell.#{method}(*args,&block)
18
+ end
19
+ METHOD
20
+ end
21
+
22
+ # Yields the given block with padding.
23
+ def with_padding
24
+ shell.padding += 1
25
+ yield
26
+ ensure
27
+ shell.padding -= 1
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Freyia
4
+ VERSION = "0.5.0"
5
+ end
data/lib/freyia.rb ADDED
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "freyia/version"
4
+
5
+ module Freyia
6
+ class Error < StandardError; end
7
+ # Your code goes here...
8
+
9
+ TEMPLATE_EXTNAME = ".tmpl"
10
+ end
11
+
12
+ require_relative "freyia/shell"
13
+ require_relative "freyia/automations"
14
+ require_relative "freyia/line_editor"
15
+
16
+ module Freyia::Setup
17
+ include Freyia::Shell
18
+ include Freyia::Automations
19
+
20
+ module ClassMethods
21
+ # Returns the shell used in all Freyia classes. If you are in a Unix platform
22
+ # it will use a colored log, otherwise it will use a basic one without color.
23
+ #
24
+ def shell
25
+ @shell ||= if ENV["FREYIA_SHELL"] && !ENV["FREYIA_SHELL"].empty?
26
+ Freyia::Shell.const_get(ENV["FREYIA_SHELL"])
27
+ elsif RbConfig::CONFIG["host_os"] =~ %r{mswin|mingw} && !ENV["ANSICON"]
28
+ Freyia::Shell::Basic
29
+ else
30
+ Freyia::Shell::Color
31
+ end
32
+ end
33
+ end
34
+
35
+ def self.included(klass)
36
+ klass.attr_accessor :source_paths
37
+ klass.extend ClassMethods
38
+ end
39
+
40
+ def shell
41
+ @shell ||= self.class.shell.new(base: self)
42
+ end
43
+
44
+ def options
45
+ @options ||= {}
46
+ end
47
+ end
48
+
49
+ class Freyia::Base
50
+ include Freyia::Setup
51
+
52
+ def initialize(source:, dest:)
53
+ self.source_paths = Array(source).map { File.expand_path(_1, Dir.pwd) }
54
+ self.destination_root = File.expand_path(dest, Dir.pwd)
55
+ end
56
+ end
metadata ADDED
@@ -0,0 +1,68 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: freyia
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.0
5
+ platform: ruby
6
+ authors:
7
+ - Jared White
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 2025-11-18 00:00:00.000000000 Z
11
+ dependencies: []
12
+ description: Define and execute automated tasks like the party girl you are.
13
+ email:
14
+ - jared@whitefusion.studio
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - CHANGELOG.md
20
+ - CODE_OF_CONDUCT.md
21
+ - LICENSE.txt
22
+ - README.md
23
+ - Rakefile
24
+ - lib/freyia.rb
25
+ - lib/freyia/automations.rb
26
+ - lib/freyia/automations/create_file.rb
27
+ - lib/freyia/automations/create_link.rb
28
+ - lib/freyia/automations/directory.rb
29
+ - lib/freyia/automations/empty_directory.rb
30
+ - lib/freyia/automations/file_manipulation.rb
31
+ - lib/freyia/automations/inject_into_file.rb
32
+ - lib/freyia/line_editor.rb
33
+ - lib/freyia/line_editor/basic.rb
34
+ - lib/freyia/line_editor/readline.rb
35
+ - lib/freyia/shell.rb
36
+ - lib/freyia/shell/basic.rb
37
+ - lib/freyia/shell/color.rb
38
+ - lib/freyia/shell/column_printer.rb
39
+ - lib/freyia/shell/lcs_diff.rb
40
+ - lib/freyia/shell/table_printer.rb
41
+ - lib/freyia/shell/terminal.rb
42
+ - lib/freyia/shell/wrapped_printer.rb
43
+ - lib/freyia/version.rb
44
+ homepage: https://codeberg.org/jaredwhite/freyia
45
+ licenses:
46
+ - MIT
47
+ metadata:
48
+ homepage_uri: https://codeberg.org/jaredwhite/freyia
49
+ source_code_uri: https://codeberg.org/jaredwhite/freyia
50
+ rubygems_mfa_required: 'true'
51
+ rdoc_options: []
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: 3.2.0
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ requirements: []
65
+ rubygems_version: 3.6.2
66
+ specification_version: 4
67
+ summary: Define and execute automated tasks like the party girl you are.
68
+ test_files: []