make_menu 0.0.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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: fde049dc673ab7e43c9254d5b394b9ed592a9d9799e46046c1d935a1d55e4774
4
+ data.tar.gz: 0b289aa24e021fa1ba4f2add414978de9783827fac12e028d38ebb39adcbf80f
5
+ SHA512:
6
+ metadata.gz: 443c5ad6a9eb87e424e7e693ea3e618ecafdbf1d979c03cdbe4c0c31782b6ca3905648fe01a950901b39b7706d3f7ff9870c3cd854f9d5a99218bcd1688553b8
7
+ data.tar.gz: eaf82c95dc0df11c6422c76ed49d634501bcc7ed9a0894d08ca77cb091887766c1767b6bb525a112e067925f3cb8f73647343bb6ff27858800e3a530a5c38d95
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'http://rubygems.org'
4
+
5
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,17 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ make_menu (0.0.1)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+
10
+ PLATFORMS
11
+ arm64-darwin-21
12
+
13
+ DEPENDENCIES
14
+ make_menu!
15
+
16
+ BUNDLED WITH
17
+ 2.3.26
@@ -0,0 +1,141 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MakeMenu
4
+ # Monkeypatch for `String`, adds methods to change console text colo(u)r
5
+ module ColorString
6
+ COLORS = {
7
+ white: 0,
8
+ normal: 0,
9
+ bold: 1,
10
+ dark: 2,
11
+ underline: 4,
12
+ blink: 5,
13
+ invert: 7,
14
+
15
+ black: 30,
16
+ red: 31,
17
+ green: 32,
18
+ yellow: 33,
19
+ blue: 34,
20
+ magenta: 35,
21
+ cyan: 36,
22
+ grey: 37,
23
+
24
+ black_bg: 40,
25
+ red_bg: 41,
26
+ green_bg: 42,
27
+ yellow_bg: 43,
28
+ blue_bg: 44,
29
+ magenta_bg: 45,
30
+ cyan_bg: 46,
31
+ grey_bg: 47,
32
+
33
+ dark_grey: 90,
34
+ light_red: 91,
35
+ light_green: 92,
36
+ light_yellow: 93,
37
+ light_blue: 94,
38
+ light_magenta: 95,
39
+ light_cyan: 96,
40
+ light_grey: 97,
41
+
42
+ dark_grey_bg: 100,
43
+ light_red_bg: 101,
44
+ light_green_bg: 102,
45
+ light_yellow_bg: 103,
46
+ light_blue_bg: 104,
47
+ light_magenta_bg: 105,
48
+ light_cyan_bg: 106,
49
+ light_grey_bg: 107
50
+ }.freeze
51
+
52
+ COLORS.each do |name, code|
53
+ define_method name do
54
+ color(code)
55
+ end
56
+ end
57
+
58
+ # Apply specified color code to the String
59
+ # @param [Array, Symbol, Integer] color_code Can be a key in the COLORS array,
60
+ # an integer ANSI code for text color, or an array of either to be applied in order
61
+ # @return [String] String enclosed by formatting characters
62
+ def color(color_code)
63
+ case color_code
64
+ when Array
65
+ color_code.inject(self) { |string, code| string.color(code) }
66
+ when Symbol
67
+ color(COLORS[color_code])
68
+ else
69
+ "\e[#{color_code}m#{self}\e[0m"
70
+ end
71
+ end
72
+
73
+ # Changes all occurrences of a specified character to one color,
74
+ # and all other characters to another
75
+ # @param [String] char Character to highlight
76
+ # @param [Symbol] fore_color Key of color to use for highlighted character
77
+ # @param [Symbol] back_color Key of color to use for other characters
78
+ # @return [String] Highlighted text
79
+ # @example "==$$==".highlight('$', :light_yellow, :red)
80
+ # rubocop:disable Metrics/MethodLength
81
+ def highlight(char, fore_color, back_color)
82
+ inside_highlight = false
83
+ output = ''
84
+ buffer = ''
85
+ each_char do |c|
86
+ if c == char
87
+ unless inside_highlight
88
+ output += buffer.color(COLORS[back_color.to_sym])
89
+ buffer = ''
90
+ inside_highlight = true
91
+ end
92
+ elsif inside_highlight
93
+ output += buffer.color(COLORS[fore_color.to_sym]).bold
94
+ buffer = ''
95
+ inside_highlight = false
96
+ end
97
+ buffer += c
98
+ end
99
+
100
+ output += if inside_highlight
101
+ buffer.color(COLORS[fore_color.to_sym]).bold
102
+ else
103
+ buffer.color(COLORS[back_color.to_sym])
104
+ end
105
+
106
+ output
107
+ end
108
+ # rubocop:enable Metrics/MethodLength
109
+
110
+ # Remove color codes from the string
111
+ # @return [String] The modified string
112
+ def decolor
113
+ gsub(/\e\[\d+m/, '')
114
+ end
115
+
116
+ # Align the string, ignoring color code characters which would otherwise mess up String#center, etc.
117
+ # @param [Symbol] alignment :left, :center, or :right
118
+ # @param [Integer] width The number of characters to spread the string over (default to terminal width)
119
+ # @param [String] char The character to use for padding
120
+ # @param [Boolean] pad_right Set true to include trailing spaces when aligning to :center
121
+ # @return [String] The padded string
122
+ # rubocop:disable Metrics/MethodLength
123
+ def align(alignment = :left, width: nil, char: ' ', pad_right: false)
124
+ width = ::TTY::Screen.cols unless width
125
+
126
+ case alignment
127
+ when :left
128
+ right_pad = width - decolor.length
129
+ "#{self}#{char * right_pad}"
130
+ when :center
131
+ left_pad = [(width - decolor.length) / 2, 0].max
132
+ right_pad = width - left_pad - decolor.length
133
+ "#{char * left_pad}#{self}#{pad_right ? char * right_pad : ''}"
134
+ when :right
135
+ left_pad = width - decolor.length
136
+ "#{char * left_pad}#{self}"
137
+ end
138
+ end
139
+ # rubocop:enable Metrics/MethodLength
140
+ end
141
+ end
@@ -0,0 +1,166 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'menu_item_group'
4
+ require_relative 'color_string'
5
+ require_relative 'text_table'
6
+
7
+ module MakeMenu
8
+ # This class builds and displays a number-selection menu from a Makefile
9
+ # then prompts for a number and executes the target.
10
+ class Menu
11
+ # @param [String] makefile Makefile name
12
+ def initialize(makefile)
13
+ @groups = []
14
+ @items = []
15
+ @status_present = false
16
+ build makefile
17
+ end
18
+
19
+ attr_reader :groups, :items
20
+ attr_accessor :status_present
21
+
22
+ # Display menu and prompt for command
23
+ # rubocop:disable Metrics/MethodLength
24
+ def run
25
+ running = true
26
+
27
+ while running
28
+ system 'clear' if clear_screen?
29
+
30
+ display_header
31
+
32
+ puts colorize(TextTable.new(groups).to_s)
33
+ puts
34
+ puts 'Press ENTER to quit'.align(:center).bold
35
+ puts
36
+ print 'Select option: '.align(:center)
37
+
38
+ running = false unless execute_option(gets.strip)
39
+ end
40
+
41
+ puts
42
+
43
+ system 'clear' if clear_screen?
44
+ end
45
+
46
+ # rubocop:enable Metrics/MethodLength
47
+
48
+ # Display the company logo and the status bar (if set)
49
+ def display_header
50
+ puts formatted_logo if logo
51
+ puts `make status` if status_present
52
+ end
53
+
54
+ private
55
+
56
+ # Build a menu from the specified Makefile
57
+ # @param [String] makefile Filename
58
+ # rubocop:disable Metrics/MethodLength
59
+ def build(makefile)
60
+ File.open(makefile, 'r') do |file|
61
+ option_number = 1
62
+ current_group = nil
63
+
64
+ file.each_line do |line|
65
+ if line.start_with? '###'
66
+ # Group header
67
+ group_title = line.gsub(/###\s+/, '').strip
68
+ current_group = MenuItemGroup.new(group_title.color(group_title_color))
69
+ groups << current_group
70
+
71
+ elsif line.match(/^[a-zA-Z_-]+:.*?## .*$$/)
72
+ # Menu item
73
+ target = line.split(':').first.strip
74
+ description = line.split('##').last.strip
75
+
76
+ # Target 'menu' should not appear
77
+ next if target == 'menu'
78
+
79
+ # Target 'status' should not appear, but is run automatically when the menu is rendered
80
+ if target == 'status'
81
+ self.status_present = true
82
+ next
83
+ end
84
+
85
+ unless current_group
86
+ current_group = MenuItemGroup.new
87
+ groups << current_group
88
+ end
89
+
90
+ items << current_group.add_item(
91
+ MenuItem.new(option_number, target, description)
92
+ )
93
+
94
+ option_number += 1
95
+ end
96
+ end
97
+ end
98
+ end
99
+
100
+ # rubocop:enable Metrics/MethodLength
101
+
102
+ # Execute the selected menu item
103
+ # @param [String] selected Value entered by user
104
+ # @return [Boolean] False to signify that menu should exit
105
+ def execute_option(selected)
106
+ return false if selected.empty?
107
+
108
+ selected = selected.to_i
109
+
110
+ items.each do |item|
111
+ next unless item.option_number == selected
112
+
113
+ system 'clear' if clear_screen?
114
+ item.execute
115
+ return true
116
+ end
117
+
118
+ true
119
+ end
120
+
121
+ # Apply word colorings
122
+ # @param [String] string
123
+ # @return [String]
124
+ def colorize(string)
125
+ return string unless Object.const_defined?("#{self.class.name}::HIGHLIGHTS")
126
+
127
+ Object.const_get("#{self.class.name}::HIGHLIGHTS").each do |word, color|
128
+ case color
129
+ when Array
130
+ color.each { |c| string.gsub!(word, word.send(c)) }
131
+ else
132
+ string.gsub!(word, word.send(color))
133
+ end
134
+ end
135
+ string
136
+ end
137
+
138
+ # Center each line of the logo across the screen
139
+ def formatted_logo
140
+ logo.split("\n")
141
+ .map { |line| line.align(:center) }
142
+ .join("\n")
143
+ end
144
+
145
+ # Get the menu logo from the LOGO constant
146
+ def logo
147
+ return "\n#{' make '.black_bg.light_yellow}#{' menu '.light_yellow_bg.black}\n".bold unless Object.const_defined?("#{self.class.name}::LOGO")
148
+
149
+ Object.const_get("#{self.class.name}::LOGO")
150
+ end
151
+
152
+ protected
153
+
154
+ # Override the following methods to customise the menu display
155
+
156
+ # @return [Symbol] Color for group title
157
+ def group_title_color
158
+ :light_green
159
+ end
160
+
161
+ # Clean screen before and after each command
162
+ def clear_screen?
163
+ true
164
+ end
165
+ end
166
+ end
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MakeMenu
4
+ # This class represents an option in the menu which runs a target from the Makefile
5
+ class MenuItem
6
+ INDENT = 6
7
+
8
+ # @param [Integer] option_number Number user enters for this command
9
+ # @param [String] target Name of target defined in Makefile
10
+ # @param [String] description Text to display for this command, taken from Makefile comment
11
+ def initialize(option_number = nil, target = nil, description = nil)
12
+ @option_number = option_number
13
+ @target = target
14
+ @description = description || target
15
+ end
16
+
17
+ attr_reader :option_number, :target, :description
18
+
19
+ # Run the make target
20
+ def execute
21
+ cmd = ['make', target]
22
+ puts "> #{cmd.join(' ').cyan}\n"
23
+ unless system(*cmd)
24
+ # Indicates the command failed, so we pause to allow user to see error message
25
+ puts "\nPress ENTER key to continue....\n"
26
+ gets
27
+ end
28
+ rescue StandardError => _e
29
+ # ignore CTRL+C from within Make target
30
+ end
31
+
32
+ # @return [Integer] Number of characters required to display the item
33
+ def width
34
+ description.size + INDENT + 1
35
+ end
36
+
37
+ # @return [String] Text to display for this item
38
+ def to_s
39
+ "#{option_number.to_s.rjust(INDENT, ' ').bold}. #{description}"
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'menu_item'
4
+
5
+ module MakeMenu
6
+ # This class represents a group of menu items, with a title line
7
+ class MenuItemGroup
8
+ INDENT = 2
9
+
10
+ # @param [String] title The title text to display at the top of the group
11
+ def initialize(title = 'Commands')
12
+ @title = title
13
+ @items = []
14
+ end
15
+
16
+ attr_reader :title, :items
17
+
18
+ # Add a new item to the group
19
+ # @param [MenuItem] item The item to add
20
+ # @return [MenuItem] The added item
21
+ def add_item(item)
22
+ items << item
23
+ item
24
+ end
25
+
26
+ # @return [Integer] Number of characters needed to display the widest item
27
+ def width
28
+ [items.map(&:width).max, title.length + INDENT].max
29
+ end
30
+
31
+ # @return [Integer] Number of rows needed to display the group
32
+ def height
33
+ items.size + 2
34
+ end
35
+
36
+ # @return [String] Text representation of group
37
+ def to_s
38
+ result = "#{' ' * INDENT}#{title}\n"
39
+
40
+ items.each do |item|
41
+ result += "#{item}\n"
42
+ end
43
+
44
+ "#{result} "
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'color_string'
4
+ require 'readline'
5
+
6
+ module MakeMenu
7
+ # A panel above the menu displaying the status of Docker containers.
8
+ # The mapping of TextLabel => ContainerName must be defined in a constant called CONTAINERS
9
+ class StatusPanel
10
+ String.include(ColorString)
11
+
12
+ # Print panel
13
+ def display
14
+ return if containers.empty?
15
+
16
+ puts "\n#{panel}"
17
+ end
18
+
19
+ protected
20
+
21
+ # Return a hash mapping label to container name
22
+ # This is assumed to be provided as a constant called CONTAINERS
23
+ # @return [Hash{String=>String}]
24
+ def containers
25
+ Object.const_get "#{self.class.name}::CONTAINERS"
26
+ rescue NameError
27
+ {}
28
+ end
29
+
30
+ # Override this to change the colors for running / not running
31
+ def colors_if_running
32
+ {
33
+ true => %i[green_bg bold white],
34
+ false => %i[red_bg bold dark]
35
+ }.freeze
36
+ end
37
+
38
+ # Override this to limit each row to a maximum number of labels
39
+ def max_labels_per_line
40
+ containers.size
41
+ end
42
+
43
+ private
44
+
45
+ # @return [String] Text representation of the panel
46
+ # rubocop:disable Metrics/MethodLength
47
+ def panel
48
+ return @panel if @panel
49
+
50
+ @panel = ''
51
+ labels_on_this_line = 0
52
+ line_buffer = ''
53
+
54
+ containers.each do |label, container|
55
+ if (labels_on_this_line + 1) > labels_per_line
56
+ @panel += "#{left_indent(labels_on_this_line)}#{line_buffer}\n\n"
57
+ labels_on_this_line = 0
58
+ line_buffer = ''
59
+ end
60
+
61
+ text = label.align(:center, width: max_label_width, pad_right: true)
62
+ .color(colors_if_running[running?(container)])
63
+
64
+ line_buffer += " #{text} "
65
+
66
+ labels_on_this_line += 1
67
+ end
68
+
69
+ @panel += "#{left_indent(labels_on_this_line)}#{line_buffer}\n\n"
70
+ end
71
+ # rubocop:enable Metrics/MethodLength
72
+
73
+ # @return [String] List of Docker containers and information
74
+ def docker_ps
75
+ @docker_ps ||= `docker compose ps`
76
+ end
77
+
78
+ # @return [Boolean] whether specified container is running
79
+ def running?(container)
80
+ docker_ps.include? container
81
+ end
82
+
83
+ # Return the left indent for this line of labels
84
+ # @param [Integer] number_of_labels Number of labels on this line
85
+ # @return [String]
86
+ def left_indent(number_of_labels)
87
+ spaces = (::TTY::Screen.cols - (number_of_labels * (max_label_width + 2))) / 2
88
+ spaces = [spaces, 0].max
89
+ ' ' * spaces
90
+ end
91
+
92
+ # @return [Integer] Maximum label width, with padding
93
+ def max_label_width
94
+ @max_label_width ||= containers.map do |label, _container|
95
+ label.length
96
+ end.max + 2
97
+ end
98
+
99
+ # @return [Integer] Number of labels that can fit on one line
100
+ def labels_per_line
101
+ @labels_per_line ||= [
102
+ (::TTY::Screen.cols / max_label_width) - 1,
103
+ max_labels_per_line
104
+ ].min
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MakeMenu
4
+ # A column of text with a fixed with
5
+ class TextColumn
6
+ # @param [Integer] width Width of the column, in characters
7
+ def initialize(width)
8
+ @width = width
9
+ @rows = []
10
+ @row_index = 0
11
+ end
12
+
13
+ attr_reader :width
14
+
15
+ attr_accessor :rows, :row_index
16
+
17
+ # Add a block of text to the column. Each row will be padded to the column width
18
+ # @param [String] text The text to add, may be multi-line
19
+ def add(text)
20
+ self.rows += text.split("\n").map do |row|
21
+ row.gsub("\r", '')
22
+ end
23
+ self.row_index += text.lines.size
24
+ end
25
+
26
+ # Return the specified row of text
27
+ # @param [Integer] index The index of the row
28
+ # @return [String] The row at the specified index
29
+ def row(index)
30
+ (rows[index] || '').align(width: width)
31
+ end
32
+
33
+ # @return [Integer] The number of rows in the column
34
+ def height
35
+ row_index
36
+ end
37
+
38
+ # @return [Boolean] True if the column is empty
39
+ def empty?
40
+ row_index.zero?
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'text_column'
4
+
5
+ module MakeMenu
6
+ # This class displays the menu groups in columns across the screen.
7
+ # Each group is kept together in a column, and once a column has exceeded the
8
+ # calculated height a new column is added.
9
+ class TextTable
10
+ MAX_COLUMNS = 4
11
+
12
+ # @param [Array<MenuItemGroup>] groups
13
+ def initialize(groups)
14
+ @groups = groups
15
+ @columns = []
16
+ calculate_table_dimensions
17
+ build_table
18
+ end
19
+
20
+ # @return [String] The entire table, centered on the screen
21
+ def to_s
22
+ buffer = ''
23
+
24
+ max_height.times do |i|
25
+ row = ''
26
+ columns.each do |column|
27
+ row += column.row(i) unless column.empty?
28
+ end
29
+ buffer += "#{row.align(:center)}\n"
30
+ end
31
+
32
+ buffer
33
+ end
34
+
35
+ private
36
+
37
+ attr_reader :groups, :columns, :column_width, :column_height
38
+
39
+ attr_accessor :current_column
40
+
41
+ # Calculate width and minimum height of columns
42
+ def calculate_table_dimensions
43
+ @column_width = groups.map(&:width).max + 5
44
+ total_rows = groups.map(&:height).sum
45
+ column_count = (::TTY::Screen.cols / column_width).clamp(1, MAX_COLUMNS)
46
+ @column_height = total_rows / column_count
47
+ end
48
+
49
+ # Build columns from groups
50
+ def build_table
51
+ column_break
52
+ groups.each do |group|
53
+ add_text_block group.to_s
54
+ end
55
+ end
56
+
57
+ # Add a block of text to the current column. If the column is now larger than
58
+ # the minimum height, a new column is added
59
+ def add_text_block(text)
60
+ current_column.add(text)
61
+ column_break if current_column.height >= column_height
62
+ end
63
+
64
+ # Add a new column to the table
65
+ def column_break
66
+ self.current_column = TextColumn.new(column_width)
67
+ columns << current_column
68
+ end
69
+
70
+ # @return [Integer] Maximum column height (rows)
71
+ def max_height
72
+ columns.map(&:height).max
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,3 @@
1
+ module MakeMenu
2
+ VERSION = '0.0.1'
3
+ end
data/lib/make_menu.rb ADDED
@@ -0,0 +1,32 @@
1
+ require_relative 'make_menu/color_string'
2
+ require_relative 'make_menu/menu'
3
+ require_relative 'make_menu/status_panel'
4
+
5
+ require 'tty-screen'
6
+
7
+ module MakeMenu
8
+ String.include MakeMenu::ColorString
9
+
10
+ def self.run
11
+ # Allows CTRL+C to return to the menu instead of exiting the script
12
+ trap('SIGINT') { throw StandardError }
13
+
14
+ makefile = ENV.fetch('MAKEFILE', './Makefile')
15
+
16
+ if (menu_name = ENV.fetch('MENU', nil))
17
+ require "./#{menu_name.downcase}_menu.rb"
18
+ Object.const_get("#{menu_name.capitalize}Menu").new(makefile).run
19
+ else
20
+ MakeMenu::Menu.new(makefile).run
21
+ end
22
+ end
23
+
24
+ def self.status
25
+ if (menu_name = ENV.fetch('MENU', nil))
26
+ require "./#{menu_name.downcase}_status_panel.rb"
27
+ Object.const_get("#{menu_name.capitalize}StatusPanel").new.display
28
+ else
29
+ MakeMenu::StatusPanel.new.display
30
+ end
31
+ end
32
+ end
data/make_menu.gemspec ADDED
@@ -0,0 +1,59 @@
1
+ require File.expand_path('lib/make_menu/version', __dir__)
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "make_menu"
5
+ s.version = MakeMenu::VERSION
6
+ s.summary = "Generates an interactive menu from a Makefile"
7
+ s.authors = ["Barri Mason"]
8
+ s.email = "loki@amarantha.net"
9
+ s.files = Dir[
10
+ 'lib/**/*.rb',
11
+ 'make_menu.gemspec',
12
+ 'Gemfile',
13
+ 'Gemfile.lock'
14
+ ]
15
+ s.homepage =
16
+ "https://rubygems.org/gems/make_menu"
17
+ s.license = "MIT"
18
+ s.add_dependency 'tty-screen', '~> 0.8.2'
19
+ s.description = %(
20
+ Creates a number-selection menu from a Makefile. The menu will attempt to fill the width of the terminal window.
21
+
22
+ - Any targets in the Makefile with a double-hash comment will be displayed, e.g.:
23
+ serve: ## Start Rails server in background
24
+ This will display a line such as '1. Start Rails server in background' which runs the command `make serve`.
25
+
26
+ - A line that starts with a triple-hash will create a new menu group, e.g.:
27
+ ### Docker Commands
28
+ This will begin a new group with the header 'Docker Commands'
29
+
30
+ - The environment variable MENU can be used to specify a custom menu class, e.g.:
31
+ export MENU=Accounts
32
+ This assumes that a class `AccountsMenu` is defined in the file `accounts_menu.rb`
33
+
34
+ You can define two constants in your custom class:
35
+ LOGO (String) text or ASCII art to display above the menu
36
+ HIGHLIGHTS (Hash{String=>[Symbol,Array<Symbol>]}) Add coloring to specific words or phrases
37
+
38
+ - The environment variable MAKEFILE can specify a Makefile. The default is './Makefile'.
39
+
40
+ The menu will not display any targets called 'menu' or 'status'. The latter, if present, is called each
41
+ time the menu displays.
42
+
43
+ -----------------------------
44
+ Docker Container Status Panel
45
+ -----------------------------
46
+
47
+ Displays a color-coded panel indicating whether or not a Docker container is running.
48
+
49
+ You must define a custom class inheriting from `MakeMenu::StatusPanel` and indicate this using
50
+ the environment variable MENU, e.g.:
51
+ export MENU=Accounts
52
+ This assumes that a class `AccountsStatusPanel` is defined in the file `accounts_status_panel.rb`
53
+
54
+ You can define a constant CONTAINERS {String=>String} in this custom class to map the displayed
55
+ label to the container name, e.g.:
56
+ CONTAINERS = { 'Backend' => 'myapp-backend-1' }
57
+
58
+ )
59
+ end
metadata ADDED
@@ -0,0 +1,108 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: make_menu
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Barri Mason
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-12-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: tty-screen
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 0.8.2
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 0.8.2
27
+ description: |2+
28
+
29
+ Creates a number-selection menu from a Makefile. The menu will attempt to fill the width of the terminal window.
30
+
31
+ - Any targets in the Makefile with a double-hash comment will be displayed, e.g.:
32
+ serve: ## Start Rails server in background
33
+ This will display a line such as '1. Start Rails server in background' which runs the command `make serve`.
34
+
35
+ - A line that starts with a triple-hash will create a new menu group, e.g.:
36
+ ### Docker Commands
37
+ This will begin a new group with the header 'Docker Commands'
38
+
39
+ - The environment variable MENU can be used to specify a custom menu class, e.g.:
40
+ export MENU=Accounts
41
+ This assumes that a class `AccountsMenu` is defined in the file `accounts_menu.rb`
42
+
43
+ You can define two constants in your custom class:
44
+ LOGO (String) text or ASCII art to display above the menu
45
+ HIGHLIGHTS (Hash{String=>[Symbol,Array<Symbol>]}) Add coloring to specific words or phrases
46
+
47
+ - The environment variable MAKEFILE can specify a Makefile. The default is './Makefile'.
48
+
49
+ The menu will not display any targets called 'menu' or 'status'. The latter, if present, is called each
50
+ time the menu displays.
51
+
52
+ -----------------------------
53
+ Docker Container Status Panel
54
+ -----------------------------
55
+
56
+ Displays a color-coded panel indicating whether or not a Docker container is running.
57
+
58
+ You must define a custom class inheriting from `MakeMenu::StatusPanel` and indicate this using
59
+ the environment variable MENU, e.g.:
60
+ export MENU=Accounts
61
+ This assumes that a class `AccountsStatusPanel` is defined in the file `accounts_status_panel.rb`
62
+
63
+ You can define a constant CONTAINERS {String=>String} in this custom class to map the displayed
64
+ label to the container name, e.g.:
65
+ CONTAINERS = { 'Backend' => 'myapp-backend-1' }
66
+
67
+ email: loki@amarantha.net
68
+ executables: []
69
+ extensions: []
70
+ extra_rdoc_files: []
71
+ files:
72
+ - Gemfile
73
+ - Gemfile.lock
74
+ - lib/make_menu.rb
75
+ - lib/make_menu/color_string.rb
76
+ - lib/make_menu/menu.rb
77
+ - lib/make_menu/menu_item.rb
78
+ - lib/make_menu/menu_item_group.rb
79
+ - lib/make_menu/status_panel.rb
80
+ - lib/make_menu/text_column.rb
81
+ - lib/make_menu/text_table.rb
82
+ - lib/make_menu/version.rb
83
+ - make_menu.gemspec
84
+ homepage: https://rubygems.org/gems/make_menu
85
+ licenses:
86
+ - MIT
87
+ metadata: {}
88
+ post_install_message:
89
+ rdoc_options: []
90
+ require_paths:
91
+ - lib
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ required_rubygems_version: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ requirements: []
103
+ rubygems_version: 3.3.26
104
+ signing_key:
105
+ specification_version: 4
106
+ summary: Generates an interactive menu from a Makefile
107
+ test_files: []
108
+ ...