# frozen_string_literal: true # # Copyright (c) 2006-2023 Hal Brodigan (postmodern.mod3 at gmail.com) # # Ronin is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # Ronin is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with Ronin. If not, see . # require 'ronin/cli/command' module Ronin class CLI module Commands # # Prints a random tip on how to use `ronin`. # # ## Usage # # ronin tips [options] # # ## Options # # --list-categories Prints all category names # -c, --category STR Print a random tip from the category # -s, --search TEXT Searches all tip files for the text # -h, --help Print help information # class Tips < Command # Path to the `data/tips/` directory. TIPS_DIR = File.join(__dir__,'..','..','..','..','data','tips') option :list_categories, desc: 'Prints all category names' option :category, value: true, short: '-c', desc: 'Print a random tip from the category' option :search, value: { type: String, usage: 'TEXT' }, short: '-s', desc: 'Searches all tip files for the text' description 'Prints a random tip on how to use ronin' man_page 'ronin-tips.1' # # Runs the tip command. # def run if options[:list_categories] puts tip_category_names else category = options[:category] if category && !tip_category_names.include?(category) print_error "unknown category name: #{category}." print_error "please see `ronin tips --list-categories` for all category names." exit(1) end if options[:search] print_matching_tips(options[:search], category: category) else print_random_tip(category) end end end # # All of the paths to the tip category directories. # # @return [Array] # def tip_category_paths Dir[File.join(TIPS_DIR,'*/')] end # # All of the tip category names. # # @return [Array] # def tip_category_names tip_category_paths.map { |path| File.basename(path) } end # # Gets the paths to all of the tip files. # # @param [String, nil] category # The optional tips category to select the tip files from. # # @return [Array] # The paths to all files in `data/tips/`. # def tip_paths(category=nil) glob_pattern = if category then File.join(TIPS_DIR,category,'*.txt') else File.join(TIPS_DIR,'{*/}*.txt') end return Dir[glob_pattern] end # # Gets a path to a random tipe. # # @param [String, nil] category # The optional tips category to select the random tip from. # # @return [String] # The path to the random tip. # def random_tip_path(category=nil) tip_paths(category).sample end # # Searches through all tip files for the given text. # # @param [String] text # The text to search for. # # @param [String, nil] category # The optional tips category to search within. # # @return [Array] # The paths to the tip files containing the matching text. # def search_tip_files(text, category: nil) tip_paths(category).select do |path| File.read(path).include?(text) end end # # Prints a tip at the given path. # # @param [String] path # The path to the tip file. # def print_tip(path) contents = File.read(path) puts contents unless contents.end_with?("#{$/}#{$/}") puts puts end end # # Prints a random tip. # # @param [String, nil] category # The optional tips category to select the random tip from. # # @api private # def print_random_tip(category=nil) print_tip(random_tip_path(category)) end # # Prints all tips that contain the given text. # def print_matching_tips(text, category: nil) search_tip_files(text, category: category).each do |path| print_tip(path) end end end end end end