howzit 2.0.8 → 2.0.9
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 +4 -4
- data/CHANGELOG.md +15 -0
- data/README.md +4 -343
- data/bin/howzit +101 -83
- data/howzit.gemspec +2 -0
- data/lib/howzit/buildnote.rb +11 -9
- data/lib/howzit/config.rb +39 -5
- data/lib/howzit/console_logger.rb +37 -0
- data/lib/howzit/prompt.rb +6 -5
- data/lib/howzit/stringutils.rb +1 -1
- data/lib/howzit/topic.rb +21 -4
- data/lib/howzit/util.rb +10 -5
- data/lib/howzit/version.rb +1 -1
- data/lib/howzit.rb +2 -0
- data/spec/cli_spec.rb +27 -0
- data/spec/spec_helper.rb +1 -0
- metadata +32 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: e11e4e9f19c26666de0d9dbfbfd0ab1b3c1bee495575fe0962ab5157a185e613
         | 
| 4 | 
            +
              data.tar.gz: 7430c1da6d45f7dc873e01a8c1e6618da2dab503659921b9b72d690ad7aff181
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 739879dd1a53689e005511745003dd9b9d2ff5a8fa964cec3cb1754ef78e740c488d0a9040cee6b6de5e5eaf62a4a9c50dcc74a236db732e1c78ef4f9c8978cd
         | 
| 7 | 
            +
              data.tar.gz: '009601634be888e709ee5709fc2bb990b5dff1a274144469621a9b23dc5108778fec2f8838fc46f03999df8c31d9872f3ad8b9de57afb6bb534035a8f8070c25'
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,3 +1,18 @@ | |
| 1 | 
            +
            ### 2.0.9
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            2022-08-05 07:29
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            #### IMPROVED
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            - Avoid error trace on interrupt
         | 
| 8 | 
            +
            - Better stty settings for y/n prompt
         | 
| 9 | 
            +
            - Better coloring of default options in dialogs
         | 
| 10 | 
            +
             | 
| 11 | 
            +
            #### FIXED
         | 
| 12 | 
            +
             | 
| 13 | 
            +
            - Encoding issues with older ruby versions
         | 
| 14 | 
            +
            - Globbing for build notes was picking up files that contained "build" but not at the beginning of the filename
         | 
| 15 | 
            +
             | 
| 1 16 | 
             
            ### 2.0.8
         | 
| 2 17 |  | 
| 3 18 | 
             
            2022-08-04 13:28
         | 
    
        data/README.md
    CHANGED
    
    | @@ -37,350 +37,9 @@ You can install `howzit` by running: | |
| 37 37 |  | 
| 38 38 | 
             
                gem install howzit
         | 
| 39 39 |  | 
| 40 | 
            -
             | 
| 40 | 
            +
            ### Usage
         | 
| 41 41 |  | 
| 42 | 
            -
             | 
| 43 | 
            -
             | 
| 44 | 
            -
            > Tip: Add "buildprivate.md" to your global gitignore (`git config --get core.excludesfile`). In a project where you don't want to share your build notes, just name the file "buildprivate.md" instead of "buildnotes.md" and it will automatically be ignored.
         | 
| 45 | 
            -
             | 
| 46 | 
            -
            If there are files that match the "build*" pattern that should not be recognized as build notes by howzit, add them to `~/.config/howzit/ignore.yaml`. This file is a simple list of patterns that should be ignored when scanning for build note files. Use `(?:i)` at the beginning of a pattern to make it case insensitive.
         | 
| 47 | 
            -
             | 
| 48 | 
            -
            The topics of the notes are delineated by Markdown headings, level 2 or higher, with the heading being the title of the topic. I split all of mine apart with h2s. For example, a short one from the little website I was working on yesterday:
         | 
| 49 | 
            -
             | 
| 50 | 
            -
                ## Build
         | 
| 51 | 
            -
             | 
| 52 | 
            -
                gulp js: compiles and minifies all js to dist/js/main.min.js
         | 
| 53 | 
            -
             | 
| 54 | 
            -
                gulp css: compass compile to dist/css/
         | 
| 55 | 
            -
             | 
| 56 | 
            -
                gulp watch
         | 
| 57 | 
            -
             | 
| 58 | 
            -
                gulp (default): [css,js]
         | 
| 59 | 
            -
             | 
| 60 | 
            -
                ## Deploy
         | 
| 61 | 
            -
             | 
| 62 | 
            -
                gulp sync: rsync /dist/ to scoffb.local
         | 
| 63 | 
            -
             | 
| 64 | 
            -
                ## Package management
         | 
| 65 | 
            -
             | 
| 66 | 
            -
                yarn
         | 
| 67 | 
            -
             | 
| 68 | 
            -
                ## Components
         | 
| 69 | 
            -
             | 
| 70 | 
            -
                - UIKit
         | 
| 71 | 
            -
             | 
| 72 | 
            -
            Howzit expects there to only be one header level used to split topics. Anything before the first header is ignored. If your topics use h2 (`##`), you can use a single h1 (`#`) line at the top to title the project.
         | 
| 73 | 
            -
             | 
| 74 | 
            -
            ### @Commands
         | 
| 75 | 
            -
             | 
| 76 | 
            -
            You can include commands that can be executed by howzit. Commands start at the beginning of a line anywhere in a topic. Only one topic's commands can be run at once, but all commands in the topic will be executed when howzit is run with `-r`. Commands can include any of:
         | 
| 77 | 
            -
             | 
| 78 | 
            -
            - `@run(COMMAND)`
         | 
| 79 | 
            -
             | 
| 80 | 
            -
                The command in parenthesis will be executed as is from the current directory of the shell
         | 
| 81 | 
            -
            - `@copy(TEXT)`
         | 
| 82 | 
            -
             | 
| 83 | 
            -
                On macOS this will copy the text within the parenthesis to the clipboard. An easy way to offer a shortcut to a longer build command while still allowing it to be edited prior to execution.
         | 
| 84 | 
            -
            - `@open(FILE|URL)`
         | 
| 85 | 
            -
             | 
| 86 | 
            -
                Will open the file or URL using the default application for the filetype. On macOS this uses the `open` command, on Windows it uses `start`, and on Linux it uses `xdg-open`, which may require separate installation.
         | 
| 87 | 
            -
            - `@include(TOPIC)`
         | 
| 88 | 
            -
             | 
| 89 | 
            -
                Includes all tasks from another topic, matching the name (partial match allowed) and returning first match.
         | 
| 90 | 
            -
            - `@before...@end`
         | 
| 91 | 
            -
                
         | 
| 92 | 
            -
                A block defined between @before and @end markers will be considered prerequisite for any task the topic can run. If one or more of these blocks exist in the topic, they will be displayed before running and a yes/no dialog will request confirmation that the prerequisites have been met. The content between these markers is still included when viewing the topic, but the tags themselves do not show up in output.
         | 
| 93 | 
            -
            - `@after...@end`
         | 
| 94 | 
            -
             | 
| 95 | 
            -
                A block defined between @after and @end markers will be displayed after a topic is run. Use it to remind yourself of additional tasks after automated ones have been executed. The content between these markers is still included when viewing the topic, but the tags themselves do not show up in output.
         | 
| 96 | 
            -
             | 
| 97 | 
            -
            ### Adding Titles
         | 
| 98 | 
            -
             | 
| 99 | 
            -
            When displaying a topic, howzit can display a title instead of the contents of a directive. Any text after the closing parenthesis will be considered the task title.
         | 
| 100 | 
            -
             | 
| 101 | 
            -
            ```
         | 
| 102 | 
            -
            @run(~/scripts/deploy.sh) Deploy script
         | 
| 103 | 
            -
            ```
         | 
| 104 | 
            -
             | 
| 105 | 
            -
            When the topic is displayed, it will now show "Run Deploy script" instead of the path to the script. This can be overridden with the `--show-code` flag, which will instead show the contents of the directive.
         | 
| 106 | 
            -
             | 
| 107 | 
            -
            For adding titles to run blocks (fenced code), see below.
         | 
| 108 | 
            -
             | 
| 109 | 
            -
            ### Run blocks (embedded scripts)
         | 
| 110 | 
            -
             | 
| 111 | 
            -
            For longer scripts you can write shell scripts and then call them with `@run(myscript.sh)`. For those in-between cases where you need a few commands but aren't motivated to create a separate file, you can use fenced code blocks with `run` as the language.
         | 
| 112 | 
            -
             | 
| 113 | 
            -
                ```run OPTIONAL TITLE
         | 
| 114 | 
            -
                #!/bin/bash
         | 
| 115 | 
            -
                # Commands...
         | 
| 116 | 
            -
                ```
         | 
| 117 | 
            -
             | 
| 118 | 
            -
            The contents of the block will be written to a temporary file and executed with `/bin/sh -c`. This means that you need a hashbang at the beginning to tell the shell how to interpret the script. If no hashbang is given, the script will be executed as a `sh` script.
         | 
| 119 | 
            -
             | 
| 120 | 
            -
            Example:
         | 
| 121 | 
            -
             | 
| 122 | 
            -
                ```run Just Testing
         | 
| 123 | 
            -
                #!/bin/bash
         | 
| 124 | 
            -
                echo "Just needed a few lines"
         | 
| 125 | 
            -
                echo "To get through all these commands"
         | 
| 126 | 
            -
                echo "Almost there!"
         | 
| 127 | 
            -
                say "Phew, we did it."
         | 
| 128 | 
            -
                ```
         | 
| 129 | 
            -
             | 
| 130 | 
            -
            Multiple blocks can be included in a topic. @commands take priority over code blocks and will be run first if they exist in the same topic.
         | 
| 131 | 
            -
             | 
| 132 | 
            -
            ### Requiring Confirmation
         | 
| 133 | 
            -
             | 
| 134 | 
            -
            You can have howzit confirm whether to execute an @command at runtime by including a question mark to the directive, e.g. `@run?(...)`. This will present a yes/no dialog before running the directive, with a default response of "yes" if you just hit return. To make the default response "no," add an exclamation point, e.g. `@run?!(...)`. 
         | 
| 135 | 
            -
             | 
| 136 | 
            -
            This works for any directive, including `@include`, and run blocks, which can use `run?` as the language specifier.
         | 
| 137 | 
            -
             | 
| 138 | 
            -
            ### Variables
         | 
| 139 | 
            -
             | 
| 140 | 
            -
            When running commands in a topic, you can use a double dash (`--`) in the command line (surrounded by spaces) and anything after it will be interpreted as shell arguments. These can be used in commands with `$` placeholders. `$1` represents the first argument, counting up from there. Use `$@` to pass all arguments as a shell-escaped string.
         | 
| 141 | 
            -
             | 
| 142 | 
            -
            For example, the topic titled "Test" could contain an @run command with placeholders:
         | 
| 143 | 
            -
             | 
| 144 | 
            -
                ## Test
         | 
| 145 | 
            -
                @run(./myscript.sh $@)
         | 
| 146 | 
            -
             | 
| 147 | 
            -
            Then you would run it on the command line using:
         | 
| 148 | 
            -
             | 
| 149 | 
            -
                howzit -r test -- -x "arg 1" arg2
         | 
| 150 | 
            -
             | 
| 151 | 
            -
            This would execute the command as `./myscript.sh -x arg\ 1 arg2`.
         | 
| 152 | 
            -
             | 
| 153 | 
            -
            Placeholders can be used in both commands and run blocks. If a placeholder doesn't have an argument supplied, it's not replaced (e.g. leaves `$2` in the command).
         | 
| 154 | 
            -
             | 
| 155 | 
            -
            ### Templates and metadata
         | 
| 156 | 
            -
             | 
| 157 | 
            -
            You can create templates to reuse topics in multiple build note files. Create files using the same formatting as a build note in `~/.config/howzit/templates` with `.md` extensions. Name them the way you'll reference them:
         | 
| 158 | 
            -
             | 
| 159 | 
            -
                ~/.config/howzit/templates
         | 
| 160 | 
            -
                - markdown.md
         | 
| 161 | 
            -
                - ruby.md
         | 
| 162 | 
            -
                - obj-c.md
         | 
| 163 | 
            -
             | 
| 164 | 
            -
            > Use `howzit --templates` for a list of templates you've created, along with the topics they'll add when included. Just in case you make a bunch and can't remember what they're called or what they do. I was just planning ahead.
         | 
| 165 | 
            -
             | 
| 166 | 
            -
            You can then include the topics from a template in any build note file using a `template:` key at the top of the file.
         | 
| 167 | 
            -
             | 
| 168 | 
            -
            Howzit allows MultiMarkdown-style metadata at the top of a build notes file. These are key/value pairs separated by a colon:
         | 
| 169 | 
            -
             | 
| 170 | 
            -
                template: markdown
         | 
| 171 | 
            -
                key 1: value 1
         | 
| 172 | 
            -
                key 2: value 2
         | 
| 173 | 
            -
             | 
| 174 | 
            -
            The template key can include multiple template names separated by commas.
         | 
| 175 | 
            -
             | 
| 176 | 
            -
            Additional metadata keys populate variables you can then use inside of your templates (and build notes), using `[%key]`. You can define a default value for a placeholder with `[%key:default]`.
         | 
| 177 | 
            -
             | 
| 178 | 
            -
            For example, in the template `markdown.md` you could have:
         | 
| 179 | 
            -
             | 
| 180 | 
            -
                ### Spellcheck
         | 
| 181 | 
            -
             | 
| 182 | 
            -
                Check spelling of all Markdown files in git repo.
         | 
| 183 | 
            -
             | 
| 184 | 
            -
                ```run
         | 
| 185 | 
            -
                #!/bin/bash
         | 
| 186 | 
            -
                for dir in [%dirs:.]; do
         | 
| 187 | 
            -
                    cd "$dir"
         | 
| 188 | 
            -
                    /Users/ttscoff/scripts/spellcheck.bash
         | 
| 189 | 
            -
                    cd -
         | 
| 190 | 
            -
                done
         | 
| 191 | 
            -
                ```
         | 
| 192 | 
            -
             | 
| 193 | 
            -
            Then, in a `buildnotes.md` file in your project, you could include at the top of the file:
         | 
| 194 | 
            -
             | 
| 195 | 
            -
                template: markdown
         | 
| 196 | 
            -
                dirs: . docs
         | 
| 197 | 
            -
             | 
| 198 | 
            -
                # My Project...
         | 
| 199 | 
            -
             | 
| 200 | 
            -
            If you only want to include certain topics from a template file, use the format `template_name[topic]` or include multiple topics separated by commas: `template_name[topic 1, topic 2]`. You can also use `*` as a wildcard, where `template_name[build*]` would include topics "Build" and "Build and Run".
         | 
| 201 | 
            -
             | 
| 202 | 
            -
            If a topic in the current project's build note has an identical name to a template topic, the local topic takes precedence. This allows you to include a template but modify just a part of it by duplicating the topic title.
         | 
| 203 | 
            -
             | 
| 204 | 
            -
            Templates can include other templates with a `template:` key at the top of the template.
         | 
| 205 | 
            -
             | 
| 206 | 
            -
            You can define what metadata keys are required for the template using a `required:` key at the top of the template. For example, if the template `script.md` uses a placeholder `[%executable]` that can't have a default value as it's specific to each project, you can add:
         | 
| 207 | 
            -
             | 
| 208 | 
            -
                required: executable 
         | 
| 209 | 
            -
             | 
| 210 | 
            -
            at the top of `project.md`. If the template is included in a build notes file and the `executable:` key is not defined, an error will be shown.
         | 
| 211 | 
            -
             | 
| 212 | 
            -
            ## Using howzit
         | 
| 213 | 
            -
             | 
| 214 | 
            -
            Run `howzit` on its own to view the current folder's buildnotes.
         | 
| 215 | 
            -
             | 
| 216 | 
            -
            Include a topic name to see just that topic, or no argument to display all.
         | 
| 217 | 
            -
             | 
| 218 | 
            -
                howzit build
         | 
| 219 | 
            -
             | 
| 220 | 
            -
            You can combine multiple topic searches by separating with a comma. When multiple results are returned, the `:multiple_results:` configuration determines how they're handled.
         | 
| 221 | 
            -
             | 
| 222 | 
            -
                howzit build,deploy
         | 
| 223 | 
            -
             | 
| 224 | 
            -
            Use `-l` to list all topics.
         | 
| 225 | 
            -
             | 
| 226 | 
            -
                howzit -l
         | 
| 227 | 
            -
             | 
| 228 | 
            -
            Use `-r` to execute any @copy, @run, or @open commands in the given topic. Options can come after the topic argument, so to run the commands from the last topic you viewed, just hit the up arrow to load the previous command and add `-r`.
         | 
| 229 | 
            -
             | 
| 230 | 
            -
                howzit build -r
         | 
| 231 | 
            -
             | 
| 232 | 
            -
            Other options:
         | 
| 233 | 
            -
             | 
| 234 | 
            -
                Usage: howzit [OPTIONS] [TOPIC]
         | 
| 235 | 
            -
             | 
| 236 | 
            -
                Show build notes for the current project (buildnotes.md). Include a topic name to see just that topic, or no argument to display all.
         | 
| 237 | 
            -
             | 
| 238 | 
            -
                Options:
         | 
| 239 | 
            -
                    -c, --create                     Create a skeleton build note in the current working directory
         | 
| 240 | 
            -
                    -e, --edit                       Edit buildnotes file in current working directory
         | 
| 241 | 
            -
                                using $EDITOR
         | 
| 242 | 
            -
                        --grep PATTERN               Display sections matching a search pattern
         | 
| 243 | 
            -
                    -L, --list-completions           List topics for completion
         | 
| 244 | 
            -
                    -l, --list                       List available topics
         | 
| 245 | 
            -
                    -m, --matching TYPE              Topics matching type
         | 
| 246 | 
            -
                                                     (partial, exact, fuzzy, beginswith)
         | 
| 247 | 
            -
                        --multiple TYPE              Multiple result handling
         | 
| 248 | 
            -
                                                     (first, all, choose)
         | 
| 249 | 
            -
                    -R, --list-runnable              List topics containing @ directives (verbose)
         | 
| 250 | 
            -
                    -r, --run                        Execute @run, @open, and/or @copy commands for given topic
         | 
| 251 | 
            -
                    -s, --select                     Select topic from menu
         | 
| 252 | 
            -
                    -T, --task-list                  List topics containing @ directives (completion-compatible)
         | 
| 253 | 
            -
                    -t, --title                      Output title with build notes
         | 
| 254 | 
            -
                    -q, --quiet                      Silence info message
         | 
| 255 | 
            -
                        --verbose                    Show all messages
         | 
| 256 | 
            -
                    -u, --[no-]upstream              Traverse up parent directories for additional build notes
         | 
| 257 | 
            -
                        --show-code                  Display the content of fenced run blocks
         | 
| 258 | 
            -
                    -w, --wrap COLUMNS               Wrap to specified width (default 80, 0 to disable)
         | 
| 259 | 
            -
                        --edit-config                Edit configuration file using default $EDITOR
         | 
| 260 | 
            -
                        --title-only                 Output title only
         | 
| 261 | 
            -
                        --templates                  List available templates
         | 
| 262 | 
            -
                        --[no-]color                 Colorize output (default on)
         | 
| 263 | 
            -
                        --[no-]md-highlight          Highlight Markdown syntax (default on), requires mdless or mdcat
         | 
| 264 | 
            -
                        --[no-]pager                 Paginate output (default on)
         | 
| 265 | 
            -
                    -h, --help                       Display this screen
         | 
| 266 | 
            -
                    -v, --version                    Display version number
         | 
| 267 | 
            -
                        --default                    Answer all prompts with default response
         | 
| 268 | 
            -
             | 
| 269 | 
            -
             | 
| 270 | 
            -
            ## Configuration
         | 
| 271 | 
            -
             | 
| 272 | 
            -
            Some of the command line options can be set as defaults. The first time you run `howzit`, a YAML file is written to `~/.config/howzit/howzit.yaml`. You can open it in your default editor automatically by running `howzit --edit-config`. It contains the available options:
         | 
| 273 | 
            -
             | 
| 274 | 
            -
                ---
         | 
| 275 | 
            -
                :color: true
         | 
| 276 | 
            -
                :config_editor: subl
         | 
| 277 | 
            -
                :editor: subl
         | 
| 278 | 
            -
                :header_format: block
         | 
| 279 | 
            -
                :highlight: true
         | 
| 280 | 
            -
                :highlighter: mdcat
         | 
| 281 | 
            -
                :include_upstream: true
         | 
| 282 | 
            -
                :log_level: 0
         | 
| 283 | 
            -
                :matching: fuzzy
         | 
| 284 | 
            -
                :multiple_matches: choose
         | 
| 285 | 
            -
                :output_title: false
         | 
| 286 | 
            -
                :pager: auto
         | 
| 287 | 
            -
                :paginate: true
         | 
| 288 | 
            -
                :show_all_code: false
         | 
| 289 | 
            -
                :show_all_on_error: false
         | 
| 290 | 
            -
                :wrap: 0
         | 
| 291 | 
            -
             | 
| 292 | 
            -
            If `:color:` is false, output will not be colored, and markdown highlighting will be bypassed.
         | 
| 293 | 
            -
             | 
| 294 | 
            -
            If `:color:` is true and `:highlight:` is true, the `:highlighter:` option will be used to add Markdown highlighting.
         | 
| 295 | 
            -
             | 
| 296 | 
            -
            If `:paginate:` is true, the `:pager:` option will be used to determine the tool used for pagination. If it's false and you're using iTerm, "marks" will be added to topic titles allowing keyboard navigation.
         | 
| 297 | 
            -
             | 
| 298 | 
            -
            `:highlighter:` and `:pager:` can be set to `auto` (default) or a command of your choice for markdown highlighting and pagination.
         | 
| 299 | 
            -
             | 
| 300 | 
            -
            `:matching:` can be "partial", "beginswith", "fuzzy" or "exact" (see below).
         | 
| 301 | 
            -
             | 
| 302 | 
            -
            If `:include_upstream:` is true, build note files in parent directories will be included in addition to the current directory. Priority goes from current directory to root in descending order, so the current directory is top priority, and a build notes file in / is the lowest. Higher priority topics  will not be overwritten by a duplicate topic from a lower priority note.
         | 
| 303 | 
            -
             | 
| 304 | 
            -
            Set `:log_level:` to 0 for debug messages, or 3 to suppress superfluous info messages.
         | 
| 305 | 
            -
             | 
| 306 | 
            -
            `:multiple_matches:` determines how howzit will handle cases where a search results in multiple matches. It can be set to "first" (first match in notes), "best" (shortest topic match), "all" (display all results), or "choose" (displays a menu of results). Default is "choose." When grepping for results, only "all" or "choose" are valid, if the default is something else, "choose" will be used. Can be overridden with the `--multiple TYPE` flag.
         | 
| 307 | 
            -
             | 
| 308 | 
            -
            `:header_format:` changes the way topic titles are displayed. Setting it to "border" will add a horizontal rule and brackets around the title. Setting it to "block" will mark topic titles with a unicode block instead.
         | 
| 309 | 
            -
             | 
| 310 | 
            -
            ### Matching
         | 
| 311 | 
            -
             | 
| 312 | 
            -
            All matching is case insensitive. This setting can be overridden by the `--matching TYPE` flag on the command line.
         | 
| 313 | 
            -
             | 
| 314 | 
            -
            - `:matching: partial`
         | 
| 315 | 
            -
             | 
| 316 | 
            -
                Partial is the default, search matches any part of the topic title.
         | 
| 317 | 
            -
             | 
| 318 | 
            -
                _Example:_ `howzit other` matches 'An<mark>other</mark> Topic'.
         | 
| 319 | 
            -
             | 
| 320 | 
            -
            - `:matching: beginswith`
         | 
| 321 | 
            -
             | 
| 322 | 
            -
                Matches from the start of the title.
         | 
| 323 | 
            -
             | 
| 324 | 
            -
                _Example:_ `howzit another` matches '<mark>Another</mark> Topic', but neither 'other' or 'topic' will.
         | 
| 325 | 
            -
             | 
| 326 | 
            -
            - `:matching: fuzzy`
         | 
| 327 | 
            -
             | 
| 328 | 
            -
                Matches anything containing the search characters in order, no matter what comes between them.
         | 
| 329 | 
            -
             | 
| 330 | 
            -
                _Example:_ `howzit asct` matches '<mark>A</mark>nother <mark>S</mark>e<mark>c</mark><mark>t</mark>ion'
         | 
| 331 | 
            -
             | 
| 332 | 
            -
            - `:matching: exact`
         | 
| 333 | 
            -
             | 
| 334 | 
            -
                Case insensitive but must match the entire title.
         | 
| 335 | 
            -
             | 
| 336 | 
            -
                _Example:_ Only `howzit another topic` will match 'Another Topic'
         | 
| 337 | 
            -
             | 
| 338 | 
            -
            ### Pager
         | 
| 339 | 
            -
             | 
| 340 | 
            -
            If set to `auto`, howzit will look for pagers in this order, using the first one it finds available:
         | 
| 341 | 
            -
             | 
| 342 | 
            -
            - $GIT_PAGER
         | 
| 343 | 
            -
            - $PAGER
         | 
| 344 | 
            -
            - bat
         | 
| 345 | 
            -
            - less
         | 
| 346 | 
            -
            - more
         | 
| 347 | 
            -
            - cat
         | 
| 348 | 
            -
            - pager
         | 
| 349 | 
            -
             | 
| 350 | 
            -
            If you're defining your own, make sure to include any flags necessary to handle the output. If you're using howzit's coloring, for example, you need to specify any options needed to display ANSI escape sequences (e.g. `less -r`).
         | 
| 351 | 
            -
             | 
| 352 | 
            -
            ### Highlighter
         | 
| 353 | 
            -
             | 
| 354 | 
            -
            If set to `auto` howzit will look for markdown highlighters in this order, using the first it finds available:
         | 
| 355 | 
            -
             | 
| 356 | 
            -
            - mdcat
         | 
| 357 | 
            -
            - mdless
         | 
| 358 | 
            -
             | 
| 359 | 
            -
            If you're combining a highlighter with howzit's pagination, include any flags needed to disable the highlighter's pagination (e.g. `mdless --no-pager`).
         | 
| 360 | 
            -
             | 
| 361 | 
            -
            ### Configuring from the Command Line
         | 
| 362 | 
            -
             | 
| 363 | 
            -
            You can get and set config options from the command line using `--config-get` and `--config-set`. If you run `--config-get` with no argument, it will display all config options. If you add a key (exact match required) you can get just the value for that key.
         | 
| 364 | 
            -
             | 
| 365 | 
            -
            Using `--config-set` requires an argument in the format `key=value`. The type of the value (boolean, integer, string, symbol) will be automatically determined and converted. To change your highlighter, for example, use `howzit --config-set highlighter=mdcat`.
         | 
| 366 | 
            -
             | 
| 367 | 
            -
            ## Shell Integration
         | 
| 368 | 
            -
             | 
| 369 | 
            -
            I personally like to alias `bld` to `howzit -r`. If you define a function in your shell, you can have it default to "build" but accept an alternate argument. There's an example for Fish included, and in Bash it would be as simple as `howzit -r ${1:build}`.
         | 
| 370 | 
            -
             | 
| 371 | 
            -
            For completion you can use `howzit -L` to list all topics, and `howzit -T` to list all "runnable" topics (topics containing an @directive or run block). Completion examples for Fish are included in the `fish` directory.
         | 
| 372 | 
            -
             | 
| 373 | 
            -
            ## Similar Projects
         | 
| 374 | 
            -
             | 
| 375 | 
            -
            - [mask](https://github.com/jakedeichert/mask/)
         | 
| 376 | 
            -
            - [maid](https://github.com/egoist/maid)
         | 
| 377 | 
            -
            - [saku](https://github.com/kt3k/saku)
         | 
| 378 | 
            -
             | 
| 379 | 
            -
            There are a few projects that tackle the same concept (a Markdown makefile). Most of them are superior task runners, so if you're looking for a `make` replacement, I recommend exploring the links above. What I like about `howzit` (and what keeps me from switching) is that it's documentation-first, and that I can display the description for each topic on the command line. The others also don't have options for listing topics or runnable tasks, so I can't use completion (or my cool script that adds available tasks to my Macbook Pro Touch Bar...). But no, I don't think `howzit` is as good an overall task runner as `mask` or `maid`.
         | 
| 380 | 
            -
             | 
| 381 | 
            -
            ## Roadmap
         | 
| 382 | 
            -
             | 
| 383 | 
            -
            - Recognize header hierarchy, allow showing/running all sub-topics
         | 
| 42 | 
            +
            [See the wiki](https://github.com/ttscoff/howzit/wiki) for documentation.
         | 
| 384 43 |  | 
| 385 44 | 
             
            ## Author
         | 
| 386 45 |  | 
| @@ -401,9 +60,11 @@ purpose. | |
| 401 60 |  | 
| 402 61 | 
             
            ## Documentation
         | 
| 403 62 |  | 
| 63 | 
            +
            - [Howzit Wiki][Wiki].
         | 
| 404 64 | 
             
            - [YARD documentation][RubyDoc] is hosted by RubyDoc.info.
         | 
| 405 65 | 
             
            - [Interactive documentation][Omniref] is hosted by Omniref.
         | 
| 406 66 |  | 
| 67 | 
            +
            [Wiki]: https://github.com/ttscoff/howzit/wiki
         | 
| 407 68 | 
             
            [RubyDoc]: http://www.rubydoc.info/gems/howzit
         | 
| 408 69 | 
             
            [Omniref]: https://www.omniref.com/ruby/gems/howzit
         | 
| 409 70 |  | 
    
        data/bin/howzit
    CHANGED
    
    | @@ -18,28 +18,10 @@ OptionParser.new do |opts| | |
| 18 18 | 
             
              opts.separator ''
         | 
| 19 19 | 
             
              opts.separator 'Options:'
         | 
| 20 20 |  | 
| 21 | 
            -
              opts. | 
| 22 | 
            -
                Howzit.buildnote.create_note
         | 
| 23 | 
            -
                Process.exit 0
         | 
| 24 | 
            -
              end
         | 
| 21 | 
            +
              opts.separator "  Behavior:\n\n" #=================================================================== BEHAVIOR
         | 
| 25 22 |  | 
| 26 | 
            -
              opts.on(' | 
| 27 | 
            -
             | 
| 28 | 
            -
                Howzit.buildnote.edit
         | 
| 29 | 
            -
                Process.exit 0
         | 
| 30 | 
            -
              end
         | 
| 31 | 
            -
             | 
| 32 | 
            -
              opts.on('--grep PATTERN', 'Display sections matching a search pattern') do |pat|
         | 
| 33 | 
            -
                Howzit.options[:grep] = pat
         | 
| 34 | 
            -
              end
         | 
| 35 | 
            -
             | 
| 36 | 
            -
              opts.on('-L', '--list-completions', 'List topics for completion') do
         | 
| 37 | 
            -
                Howzit.options[:list_topics] = true
         | 
| 38 | 
            -
                Howzit.options[:list_topic_titles] = true
         | 
| 39 | 
            -
              end
         | 
| 40 | 
            -
             | 
| 41 | 
            -
              opts.on('-l', '--list', 'List available topics') do
         | 
| 42 | 
            -
                Howzit.options[:list_topics] = true
         | 
| 23 | 
            +
              opts.on('--default', 'Answer all prompts with default response') do
         | 
| 24 | 
            +
                Howzit.options[:default] = true
         | 
| 43 25 | 
             
              end
         | 
| 44 26 |  | 
| 45 27 | 
             
              opts.on('-m', '--matching TYPE', MATCHING_OPTIONS,
         | 
| @@ -52,52 +34,63 @@ OptionParser.new do |opts| | |
| 52 34 | 
             
                Howzit.options[:multiple_matches] = c.to_sym
         | 
| 53 35 | 
             
              end
         | 
| 54 36 |  | 
| 55 | 
            -
              opts.on('- | 
| 56 | 
            -
                Howzit.options[: | 
| 37 | 
            +
              opts.on('-u', '--[no-]upstream', 'Traverse up parent directories for additional build notes') do |p|
         | 
| 38 | 
            +
                Howzit.options[:include_upstream] = p
         | 
| 57 39 | 
             
              end
         | 
| 58 40 |  | 
| 59 | 
            -
              opts. | 
| 60 | 
            -
                Howzit.options[:run] = true
         | 
| 61 | 
            -
              end
         | 
| 41 | 
            +
              opts.separator "\n  Listing:\n\n" #=================================================================== LISTING
         | 
| 62 42 |  | 
| 63 | 
            -
              opts.on('- | 
| 64 | 
            -
                Howzit.options[: | 
| 43 | 
            +
              opts.on('-L', '--list-completions', 'List topics for completion') do
         | 
| 44 | 
            +
                Howzit.options[:list_topics] = true
         | 
| 45 | 
            +
                Howzit.options[:list_topic_titles] = true
         | 
| 65 46 | 
             
              end
         | 
| 66 47 |  | 
| 67 | 
            -
              opts.on('- | 
| 68 | 
            -
                Howzit.options[: | 
| 69 | 
            -
                Howzit.options[:list_runnable_titles] = true
         | 
| 48 | 
            +
              opts.on('-l', '--list', 'List available topics') do
         | 
| 49 | 
            +
                Howzit.options[:list_topics] = true
         | 
| 70 50 | 
             
              end
         | 
| 71 51 |  | 
| 72 | 
            -
              opts.on('- | 
| 73 | 
            -
                Howzit.options[: | 
| 52 | 
            +
              opts.on('-R', '--list-runnable', 'List topics containing @ directives (verbose)') do
         | 
| 53 | 
            +
                Howzit.options[:list_runnable] = true
         | 
| 74 54 | 
             
              end
         | 
| 75 55 |  | 
| 76 | 
            -
              opts.on('- | 
| 77 | 
            -
                Howzit.options[: | 
| 78 | 
            -
                Howzit. | 
| 56 | 
            +
              opts.on('-T', '--task-list', 'List topics containing @ directives (completion-compatible)') do
         | 
| 57 | 
            +
                Howzit.options[:list_runnable] = true
         | 
| 58 | 
            +
                Howzit.options[:list_runnable_titles] = true
         | 
| 79 59 | 
             
              end
         | 
| 80 60 |  | 
| 81 | 
            -
              opts.on(' | 
| 82 | 
            -
                Howzit. | 
| 83 | 
            -
                 | 
| 61 | 
            +
              opts.on('--templates', 'List available templates') do
         | 
| 62 | 
            +
                Dir.chdir(Howzit.config.template_folder)
         | 
| 63 | 
            +
                Dir.glob('*.md').each do |file|
         | 
| 64 | 
            +
                  template = File.basename(file, '.md')
         | 
| 65 | 
            +
                  puts Howzit::Color.template("{Mk}template:{Yk}#{template}{x}")
         | 
| 66 | 
            +
                  puts Howzit::Color.template('{bk}[{bl}tasks{bk}]──────────────────────────────────────┐{x}')
         | 
| 67 | 
            +
                  metadata = file.extract_metadata
         | 
| 68 | 
            +
                  topics = Howzit.buildnote.read_file(file)
         | 
| 69 | 
            +
                  topics.each do |topic|
         | 
| 70 | 
            +
                    puts Howzit::Color.template(" {bk}│{bw}-{x} {bcK}#{template}:#{topic.title.sub(/^.*?:/, '')}{x}")
         | 
| 71 | 
            +
                  end
         | 
| 72 | 
            +
                  unless metadata.empty?
         | 
| 73 | 
            +
                    meta = []
         | 
| 74 | 
            +
                    meta << metadata['required'].split(/\s*,\s*/).map { |m| "*{bw}#{m}{xw}" } if metadata.key?('required')
         | 
| 75 | 
            +
                    meta << metadata['optional'].split(/\s*,\s*/).map(&:to_s) if metadata.key?('optional')
         | 
| 76 | 
            +
                    puts Howzit::Color.template('{bk}[{bl}meta{bk}]───────────────────────────────────────┤{x}')
         | 
| 77 | 
            +
                    puts Howzit::Color.template(" {bk}│ {xw}#{meta.join(', ')}{x}")
         | 
| 78 | 
            +
                  end
         | 
| 79 | 
            +
                  puts Howzit::Color.template(' {bk}└───────────────────────────────────────────┘{x}')
         | 
| 80 | 
            +
                end
         | 
| 81 | 
            +
                Process.exit 0
         | 
| 84 82 | 
             
              end
         | 
| 85 83 |  | 
| 86 | 
            -
              opts.on('- | 
| 87 | 
            -
                Howzit.options[: | 
| 88 | 
            -
                Howzit. | 
| 84 | 
            +
              opts.on('--title-only', 'Output title only') do
         | 
| 85 | 
            +
                Howzit.options[:output_title] = true
         | 
| 86 | 
            +
                Howzit.options[:title_only] = true
         | 
| 89 87 | 
             
              end
         | 
| 90 88 |  | 
| 91 | 
            -
              opts. | 
| 92 | 
            -
                Howzit.options[:include_upstream] = p
         | 
| 93 | 
            -
              end
         | 
| 89 | 
            +
              opts.separator("\n  Commands:\n\n") #=================================================================== COMMANDS
         | 
| 94 90 |  | 
| 95 | 
            -
              opts.on(' | 
| 96 | 
            -
                Howzit. | 
| 97 | 
            -
             | 
| 98 | 
            -
             | 
| 99 | 
            -
              opts.on('-w', '--wrap COLUMNS', 'Wrap to specified width (default 80, 0 to disable)') do |w|
         | 
| 100 | 
            -
                Howzit.options[:wrap] = w.to_i
         | 
| 91 | 
            +
              opts.on('-c', '--create', 'Create a skeleton build note in the current working directory') do
         | 
| 92 | 
            +
                Howzit.buildnote.create_note
         | 
| 93 | 
            +
                Process.exit 0
         | 
| 101 94 | 
             
              end
         | 
| 102 95 |  | 
| 103 96 | 
             
              opts.on('--config-get [KEY]', 'Display the configuration settings or setting for a specific key') do |k|
         | 
| @@ -133,49 +126,41 @@ OptionParser.new do |opts| | |
| 133 126 | 
             
                Process.exit 0
         | 
| 134 127 | 
             
              end
         | 
| 135 128 |  | 
| 136 | 
            -
              opts.on('--edit-config',  | 
| 129 | 
            +
              opts.on('--edit-config', "Edit configuration file using editor (#{Howzit.options[:editor]})") do
         | 
| 137 130 | 
             
                Howzit.config.editor
         | 
| 138 131 | 
             
                Process.exit 0
         | 
| 139 132 | 
             
              end
         | 
| 140 133 |  | 
| 141 | 
            -
               | 
| 142 | 
            -
             | 
| 143 | 
            -
                Howzit. | 
| 134 | 
            +
              desc = %(Edit buildnotes file in current working directory using editor (#{Howzit.options[:config_editor]}))
         | 
| 135 | 
            +
              opts.on('-e', '--edit', desc) do
         | 
| 136 | 
            +
                Howzit.buildnote.edit
         | 
| 137 | 
            +
                Process.exit 0
         | 
| 144 138 | 
             
              end
         | 
| 145 139 |  | 
| 146 | 
            -
              opts.on('-- | 
| 147 | 
            -
                 | 
| 148 | 
            -
                Dir.glob('*.md').each do |file|
         | 
| 149 | 
            -
                  template = File.basename(file, '.md')
         | 
| 150 | 
            -
                  puts Howzit::Color.template("{Mk}template:{Yk}#{template}{x}")
         | 
| 151 | 
            -
                  puts Howzit::Color.template('{bk}[{bl}tasks{bk}]──────────────────────────────────────┐{x}')
         | 
| 152 | 
            -
                  metadata = file.extract_metadata
         | 
| 153 | 
            -
                  topics = Howzit.buildnote.read_file(file)
         | 
| 154 | 
            -
                  topics.each do |topic|
         | 
| 155 | 
            -
                    puts Howzit::Color.template(" {bk}│{bw}-{x} {bcK}#{template}:#{topic.title.sub(/^.*?:/, '')}{x}")
         | 
| 156 | 
            -
                  end
         | 
| 157 | 
            -
                  unless metadata.empty?
         | 
| 158 | 
            -
                    meta = []
         | 
| 159 | 
            -
                    meta << metadata['required'].split(/\s*,\s*/).map { |m| "*{bw}#{m}{xw}" } if metadata.key?('required')
         | 
| 160 | 
            -
                    meta << metadata['optional'].split(/\s*,\s*/).map(&:to_s) if metadata.key?('optional')
         | 
| 161 | 
            -
                    puts Howzit::Color.template('{bk}[{bl}meta{bk}]───────────────────────────────────────┤{x}')
         | 
| 162 | 
            -
                    puts Howzit::Color.template(" {bk}│ {xw}#{meta.join(', ')}{x}")
         | 
| 163 | 
            -
                  end
         | 
| 164 | 
            -
                  puts Howzit::Color.template(' {bk}└───────────────────────────────────────────┘{x}')
         | 
| 165 | 
            -
                end
         | 
| 166 | 
            -
                Process.exit 0
         | 
| 140 | 
            +
              opts.on('--grep PATTERN', 'Display sections matching a search pattern') do |pat|
         | 
| 141 | 
            +
                Howzit.options[:grep] = pat
         | 
| 167 142 | 
             
              end
         | 
| 168 143 |  | 
| 169 | 
            -
              opts.on(' | 
| 170 | 
            -
             | 
| 171 | 
            -
             | 
| 144 | 
            +
              opts.on('-r', '--run', 'Execute @run, @open, and/or @copy commands for given topic') do
         | 
| 145 | 
            +
                Howzit.options[:run] = true
         | 
| 146 | 
            +
              end
         | 
| 147 | 
            +
             | 
| 148 | 
            +
              opts.on('-s', '--select', 'Select topic from menu') do
         | 
| 149 | 
            +
                Howzit.options[:choose] = true
         | 
| 172 150 | 
             
              end
         | 
| 173 151 |  | 
| 152 | 
            +
              opts.separator("\n  Formatting:\n\n") #=================================================================== FORMATTING
         | 
| 153 | 
            +
             | 
| 174 154 | 
             
              opts.on('--[no-]color', 'Colorize output (default on)') do |c|
         | 
| 175 155 | 
             
                Howzit.options[:color] = c
         | 
| 176 156 | 
             
                Howzit.options[:highlight] = false unless c
         | 
| 177 157 | 
             
              end
         | 
| 178 158 |  | 
| 159 | 
            +
              opts.on('--header-format TYPE', HEADER_FORMAT_OPTIONS,
         | 
| 160 | 
            +
                      "Formatting style for topic titles (#{HEADER_FORMAT_OPTIONS.join(', ')})") do |t|
         | 
| 161 | 
            +
                Howzit.options[:header_format] = t
         | 
| 162 | 
            +
              end
         | 
| 163 | 
            +
             | 
| 179 164 | 
             
              opts.on('--[no-]md-highlight', 'Highlight Markdown syntax (default on), requires mdless or mdcat') do |m|
         | 
| 180 165 | 
             
                Howzit.options[:highlight] = Howzit.options[:color] ? m : false
         | 
| 181 166 | 
             
              end
         | 
| @@ -184,6 +169,37 @@ OptionParser.new do |opts| | |
| 184 169 | 
             
                Howzit.options[:paginate] = p
         | 
| 185 170 | 
             
              end
         | 
| 186 171 |  | 
| 172 | 
            +
              opts.on('--show-code', 'Display the content of fenced run blocks') do
         | 
| 173 | 
            +
                Howzit.options[:show_all_code] = true
         | 
| 174 | 
            +
              end
         | 
| 175 | 
            +
             | 
| 176 | 
            +
              opts.on('-t', '--title', 'Output title with build notes') do
         | 
| 177 | 
            +
                Howzit.options[:output_title] = true
         | 
| 178 | 
            +
              end
         | 
| 179 | 
            +
             | 
| 180 | 
            +
              opts.on('-w', '--wrap COLUMNS', 'Wrap to specified width (default 80, 0 to disable)') do |w|
         | 
| 181 | 
            +
                Howzit.options[:wrap] = w.to_i
         | 
| 182 | 
            +
              end
         | 
| 183 | 
            +
             | 
| 184 | 
            +
              opts.separator("\n  Logging:\n\n") #=================================================================== LOGGING
         | 
| 185 | 
            +
             | 
| 186 | 
            +
              opts.on('-d', '--debug', 'Show debug messages (and all messages)') do
         | 
| 187 | 
            +
                Howzit.options[:log_level] = 0
         | 
| 188 | 
            +
                Howzit.console.reset_level
         | 
| 189 | 
            +
              end
         | 
| 190 | 
            +
             | 
| 191 | 
            +
              opts.on('-q', '--quiet', 'Silence info message') do
         | 
| 192 | 
            +
                Howzit.options[:log_level] = 4
         | 
| 193 | 
            +
                Howzit.console.reset_level
         | 
| 194 | 
            +
              end
         | 
| 195 | 
            +
             | 
| 196 | 
            +
              opts.on('--verbose', 'Show all messages') do
         | 
| 197 | 
            +
                Howzit.options[:log_level] = 1
         | 
| 198 | 
            +
                Howzit.console.reset_level
         | 
| 199 | 
            +
              end
         | 
| 200 | 
            +
             | 
| 201 | 
            +
              opts.separator("\n  Misc:\n\n") #=================================================================== MISC
         | 
| 202 | 
            +
             | 
| 187 203 | 
             
              opts.on('-h', '--help', 'Display this screen') do
         | 
| 188 204 | 
             
                puts opts
         | 
| 189 205 | 
             
                Process.exit 0
         | 
| @@ -193,12 +209,14 @@ OptionParser.new do |opts| | |
| 193 209 | 
             
                puts "how v#{Howzit::VERSION}"
         | 
| 194 210 | 
             
                Process.exit 0
         | 
| 195 211 | 
             
              end
         | 
| 196 | 
            -
             | 
| 197 | 
            -
              opts.on('--default', 'Answer all prompts with default response') do
         | 
| 198 | 
            -
                Howzit.options[:default] = true
         | 
| 199 | 
            -
              end
         | 
| 200 212 | 
             
            end.parse!(args)
         | 
| 201 213 |  | 
| 214 | 
            +
            trap('INT') do
         | 
| 215 | 
            +
              puts
         | 
| 216 | 
            +
              puts 'Cancelled'
         | 
| 217 | 
            +
              Process.exit 0
         | 
| 218 | 
            +
            end
         | 
| 219 | 
            +
             | 
| 202 220 | 
             
            Howzit.options[:multiple_matches] = Howzit.options[:multiple_matches].to_sym
         | 
| 203 221 | 
             
            Howzit.options[:header_format] = Howzit.options[:header_format].to_sym
         | 
| 204 222 |  | 
    
        data/howzit.gemspec
    CHANGED
    
    | @@ -30,6 +30,7 @@ Gem::Specification.new do |spec| | |
| 30 30 |  | 
| 31 31 | 
             
              spec.add_development_dependency 'rubocop', '~> 0.28'
         | 
| 32 32 | 
             
              spec.add_development_dependency 'rspec', '~> 3.1'
         | 
| 33 | 
            +
              spec.add_development_dependency 'cli-test', '~> 1.0'
         | 
| 33 34 | 
             
              spec.add_development_dependency 'simplecov', '~> 0.9'
         | 
| 34 35 | 
             
              # spec.add_development_dependency 'codecov', '~> 0.1'
         | 
| 35 36 | 
             
              spec.add_development_dependency 'fuubar', '~> 2.0'
         | 
| @@ -40,5 +41,6 @@ Gem::Specification.new do |spec| | |
| 40 41 |  | 
| 41 42 | 
             
              spec.add_runtime_dependency 'mdless', '~> 1.0', '>= 1.0.28'
         | 
| 42 43 | 
             
              spec.add_runtime_dependency 'tty-screen', '~> 0.8'
         | 
| 44 | 
            +
              spec.add_runtime_dependency 'tty-box', '~> 0.7'
         | 
| 43 45 | 
             
              # spec.add_runtime_dependency 'tty-prompt', '~> 0.23'
         | 
| 44 46 | 
             
            end
         | 
    
        data/lib/howzit/buildnote.rb
    CHANGED
    
    | @@ -10,7 +10,7 @@ module Howzit | |
| 10 10 | 
             
                def initialize(file: nil, args: [])
         | 
| 11 11 | 
             
                  @topics = []
         | 
| 12 12 | 
             
                  create_note if note_file.nil?
         | 
| 13 | 
            -
                  @metadata =  | 
| 13 | 
            +
                  @metadata = Util.read_file(note_file).split(/^#/)[0].strip.get_metadata
         | 
| 14 14 |  | 
| 15 15 | 
             
                  read_help(file)
         | 
| 16 16 | 
             
                end
         | 
| @@ -89,7 +89,7 @@ module Howzit | |
| 89 89 | 
             
                # Create a buildnotes skeleton
         | 
| 90 90 | 
             
                def create_note
         | 
| 91 91 | 
             
                  trap('SIGINT') do
         | 
| 92 | 
            -
                    Howzit.console.info "\ | 
| 92 | 
            +
                    Howzit.console.info "\nCancelled"
         | 
| 93 93 | 
             
                    exit!
         | 
| 94 94 | 
             
                  end
         | 
| 95 95 | 
             
                  default = !$stdout.isatty || Howzit.options[:default]
         | 
| @@ -210,9 +210,11 @@ module Howzit | |
| 210 210 | 
             
                  buildnotes.reverse
         | 
| 211 211 | 
             
                end
         | 
| 212 212 |  | 
| 213 | 
            -
                def  | 
| 214 | 
            -
                  return false if filename.downcase !~  | 
| 213 | 
            +
                def build_note?(filename)
         | 
| 214 | 
            +
                  return false if filename.downcase !~ /^(howzit[^.]*|build[^.]+)/
         | 
| 215 | 
            +
             | 
| 215 216 | 
             
                  return false if Howzit.config.should_ignore(filename)
         | 
| 217 | 
            +
             | 
| 216 218 | 
             
                  true
         | 
| 217 219 | 
             
                end
         | 
| 218 220 |  | 
| @@ -222,7 +224,7 @@ module Howzit | |
| 222 224 | 
             
                  # with "build" and have an extension of txt, md, or markdown.
         | 
| 223 225 |  | 
| 224 226 | 
             
                  Dir.glob('*.{txt,md,markdown}').each do |f|
         | 
| 225 | 
            -
                    if  | 
| 227 | 
            +
                    if build_note?(f)
         | 
| 226 228 | 
             
                      filename = f
         | 
| 227 229 | 
             
                      break
         | 
| 228 230 | 
             
                    end
         | 
| @@ -262,7 +264,7 @@ module Howzit | |
| 262 264 | 
             
                end
         | 
| 263 265 |  | 
| 264 266 | 
             
                def ensure_requirements(template)
         | 
| 265 | 
            -
                  t_leader =  | 
| 267 | 
            +
                  t_leader = Util.read_file(template).split(/^#/)[0].strip
         | 
| 266 268 | 
             
                  if t_leader.length > 0
         | 
| 267 269 | 
             
                    t_meta = t_leader.get_metadata
         | 
| 268 270 | 
             
                    if t_meta.key?('required')
         | 
| @@ -330,7 +332,7 @@ module Howzit | |
| 330 332 |  | 
| 331 333 | 
             
                  return m[0] unless File.exist?(file)
         | 
| 332 334 |  | 
| 333 | 
            -
                  content =  | 
| 335 | 
            +
                  content = Util.read_file(file)
         | 
| 334 336 | 
             
                  home = ENV['HOME']
         | 
| 335 337 | 
             
                  short_path = File.dirname(file.sub(/^#{home}/, '~'))
         | 
| 336 338 | 
             
                  prefix = "#{short_path}/#{File.basename(file)}:"
         | 
| @@ -344,7 +346,7 @@ module Howzit | |
| 344 346 | 
             
                end
         | 
| 345 347 |  | 
| 346 348 | 
             
                def note_title(truncate = 0)
         | 
| 347 | 
            -
                  help =  | 
| 349 | 
            +
                  help = Util.read_file(note_file)
         | 
| 348 350 | 
             
                  title = help.match(/(?:^(\S.*?)(?=\n==)|^# ?(.*?)$)/)
         | 
| 349 351 | 
             
                  title = if title
         | 
| 350 352 | 
             
                            title[1].nil? ? title[2] : title[1]
         | 
| @@ -361,7 +363,7 @@ module Howzit | |
| 361 363 |  | 
| 362 364 | 
             
                  filename = path.nil? ? note_file : path
         | 
| 363 365 |  | 
| 364 | 
            -
                  help =  | 
| 366 | 
            +
                  help = Util.read_file(filename)
         | 
| 365 367 |  | 
| 366 368 | 
             
                  @title = note_title
         | 
| 367 369 |  | 
    
        data/lib/howzit/config.rb
    CHANGED
    
    | @@ -3,6 +3,7 @@ module Howzit | |
| 3 3 | 
             
              class Config
         | 
| 4 4 | 
             
                attr_reader :options
         | 
| 5 5 |  | 
| 6 | 
            +
                # Configuration defaults
         | 
| 6 7 | 
             
                DEFAULTS = {
         | 
| 7 8 | 
             
                  color: true,
         | 
| 8 9 | 
             
                  config_editor: ENV['EDITOR'] || nil,
         | 
| @@ -46,7 +47,7 @@ module Howzit | |
| 46 47 | 
             
                def should_ignore(filename)
         | 
| 47 48 | 
             
                  return false unless File.exist?(ignore_file)
         | 
| 48 49 |  | 
| 49 | 
            -
                  @ignore_patterns ||= YAML.safe_load( | 
| 50 | 
            +
                  @ignore_patterns ||= YAML.safe_load(Util.read_file(ignore_file))
         | 
| 50 51 |  | 
| 51 52 | 
             
                  ignore = false
         | 
| 52 53 |  | 
| @@ -78,6 +79,11 @@ module Howzit | |
| 78 79 |  | 
| 79 80 | 
             
                private
         | 
| 80 81 |  | 
| 82 | 
            +
                ##
         | 
| 83 | 
            +
                ## Load command line options
         | 
| 84 | 
            +
                ##
         | 
| 85 | 
            +
                ## @return     [Hash] options with command line flags merged in
         | 
| 86 | 
            +
                ##
         | 
| 81 87 | 
             
                def load_options
         | 
| 82 88 | 
             
                  Color.coloring = $stdout.isatty
         | 
| 83 89 | 
             
                  flags = {
         | 
| @@ -98,19 +104,39 @@ module Howzit | |
| 98 104 | 
             
                  @options = flags.merge(config)
         | 
| 99 105 | 
             
                end
         | 
| 100 106 |  | 
| 107 | 
            +
                ##
         | 
| 108 | 
            +
                ## Get the config directory
         | 
| 109 | 
            +
                ##
         | 
| 110 | 
            +
                ## @return     [String] path to config directory
         | 
| 111 | 
            +
                ##
         | 
| 101 112 | 
             
                def config_dir
         | 
| 102 113 | 
             
                  File.expand_path(CONFIG_DIR)
         | 
| 103 114 | 
             
                end
         | 
| 104 115 |  | 
| 116 | 
            +
                ##
         | 
| 117 | 
            +
                ## Get the config file
         | 
| 118 | 
            +
                ##
         | 
| 119 | 
            +
                ## @return     [String] path to config file
         | 
| 120 | 
            +
                ##
         | 
| 105 121 | 
             
                def config_file
         | 
| 106 122 | 
             
                  File.join(config_dir, CONFIG_FILE)
         | 
| 107 123 | 
             
                end
         | 
| 108 124 |  | 
| 125 | 
            +
                ##
         | 
| 126 | 
            +
                ## Get the ignore config file
         | 
| 127 | 
            +
                ##
         | 
| 128 | 
            +
                ## @return     [String] path to ignore config file
         | 
| 129 | 
            +
                ##
         | 
| 109 130 | 
             
                def ignore_file
         | 
| 110 131 | 
             
                  File.join(config_dir, IGNORE_FILE)
         | 
| 111 132 | 
             
                end
         | 
| 112 133 |  | 
| 113 | 
            -
                 | 
| 134 | 
            +
                ##
         | 
| 135 | 
            +
                ## Create a new config file (and directory if needed)
         | 
| 136 | 
            +
                ##
         | 
| 137 | 
            +
                ## @param      default     [Hash] default configuration to write
         | 
| 138 | 
            +
                ##
         | 
| 139 | 
            +
                def create_config(default)
         | 
| 114 140 | 
             
                  unless File.directory?(config_dir)
         | 
| 115 141 | 
             
                    Howzit::ConsoleLogger.new(1).info "Creating config directory at #{config_dir}"
         | 
| 116 142 | 
             
                    FileUtils.mkdir_p(config_dir)
         | 
| @@ -118,20 +144,28 @@ module Howzit | |
| 118 144 |  | 
| 119 145 | 
             
                  unless File.exist?(config_file)
         | 
| 120 146 | 
             
                    Howzit::ConsoleLogger.new(1).info "Writing fresh config file to #{config_file}"
         | 
| 121 | 
            -
                    write_config( | 
| 147 | 
            +
                    write_config(default)
         | 
| 122 148 | 
             
                  end
         | 
| 123 149 | 
             
                  config_file
         | 
| 124 150 | 
             
                end
         | 
| 125 151 |  | 
| 152 | 
            +
                ##
         | 
| 153 | 
            +
                ## Load the config file
         | 
| 154 | 
            +
                ##
         | 
| 155 | 
            +
                ## @return     [Hash] configuration object
         | 
| 156 | 
            +
                ##
         | 
| 126 157 | 
             
                def load_config
         | 
| 127 158 | 
             
                  file = create_config(DEFAULTS)
         | 
| 128 | 
            -
                  config = YAML.load( | 
| 159 | 
            +
                  config = YAML.load(Util.read_file(file))
         | 
| 129 160 | 
             
                  newconfig = config ? DEFAULTS.merge(config) : DEFAULTS
         | 
| 130 161 | 
             
                  write_config(newconfig)
         | 
| 131 162 | 
             
                  newconfig.dup
         | 
| 132 163 | 
             
                end
         | 
| 133 164 |  | 
| 134 | 
            -
                 | 
| 165 | 
            +
                ##
         | 
| 166 | 
            +
                ## Open the config in an editor
         | 
| 167 | 
            +
                ##
         | 
| 168 | 
            +
                def edit_config
         | 
| 135 169 | 
             
                  editor = Howzit.options.fetch(:config_editor, ENV['EDITOR'])
         | 
| 136 170 |  | 
| 137 171 | 
             
                  raise 'No config_editor defined' if editor.nil?
         | 
| @@ -12,30 +12,67 @@ module Howzit | |
| 12 12 | 
             
              class ConsoleLogger
         | 
| 13 13 | 
             
                attr_accessor :log_level
         | 
| 14 14 |  | 
| 15 | 
            +
                ##
         | 
| 16 | 
            +
                ## Init the console logging object
         | 
| 17 | 
            +
                ##
         | 
| 18 | 
            +
                ## @param      level  [Integer] log level
         | 
| 19 | 
            +
                ##
         | 
| 15 20 | 
             
                def initialize(level = nil)
         | 
| 16 21 | 
             
                  @log_level = level.to_i || Howzit.options[:log_level]
         | 
| 17 22 | 
             
                end
         | 
| 18 23 |  | 
| 24 | 
            +
                ##
         | 
| 25 | 
            +
                ## Get the log level from options
         | 
| 26 | 
            +
                ##
         | 
| 27 | 
            +
                ## @return     [Integer] log level
         | 
| 28 | 
            +
                ##
         | 
| 19 29 | 
             
                def reset_level
         | 
| 20 30 | 
             
                  @log_level = Howzit.options[:log_level]
         | 
| 21 31 | 
             
                end
         | 
| 22 32 |  | 
| 33 | 
            +
                ##
         | 
| 34 | 
            +
                ## Write a message to the console based on the urgency
         | 
| 35 | 
            +
                ## level and user's log level setting
         | 
| 36 | 
            +
                ##
         | 
| 37 | 
            +
                ## @param      msg    [String] The message
         | 
| 38 | 
            +
                ## @param      level  [Symbol] The level
         | 
| 39 | 
            +
                ##
         | 
| 23 40 | 
             
                def write(msg, level = :info)
         | 
| 24 41 | 
             
                  $stderr.puts msg if LOG_LEVELS[level] >= @log_level
         | 
| 25 42 | 
             
                end
         | 
| 26 43 |  | 
| 44 | 
            +
                ##
         | 
| 45 | 
            +
                ## Write a message at debug level
         | 
| 46 | 
            +
                ##
         | 
| 47 | 
            +
                ## @param      msg   The message
         | 
| 48 | 
            +
                ##
         | 
| 27 49 | 
             
                def debug(msg)
         | 
| 28 50 | 
             
                  write msg, :debug
         | 
| 29 51 | 
             
                end
         | 
| 30 52 |  | 
| 53 | 
            +
                ##
         | 
| 54 | 
            +
                ## Write a message at info level
         | 
| 55 | 
            +
                ##
         | 
| 56 | 
            +
                ## @param      msg   The message
         | 
| 57 | 
            +
                ##
         | 
| 31 58 | 
             
                def info(msg)
         | 
| 32 59 | 
             
                  write msg, :info
         | 
| 33 60 | 
             
                end
         | 
| 34 61 |  | 
| 62 | 
            +
                ##
         | 
| 63 | 
            +
                ## Write a message at warn level
         | 
| 64 | 
            +
                ##
         | 
| 65 | 
            +
                ## @param      msg   The message
         | 
| 66 | 
            +
                ##
         | 
| 35 67 | 
             
                def warn(msg)
         | 
| 36 68 | 
             
                  write msg, :warn
         | 
| 37 69 | 
             
                end
         | 
| 38 70 |  | 
| 71 | 
            +
                ##
         | 
| 72 | 
            +
                ## Write a message at error level
         | 
| 73 | 
            +
                ##
         | 
| 74 | 
            +
                ## @param      msg   The message
         | 
| 75 | 
            +
                ##
         | 
| 39 76 | 
             
                def error(msg)
         | 
| 40 77 | 
             
                  write msg, :error
         | 
| 41 78 | 
             
                end
         | 
    
        data/lib/howzit/prompt.rb
    CHANGED
    
    | @@ -8,14 +8,15 @@ module Howzit | |
| 8 8 | 
             
                    return default unless $stdout.isatty
         | 
| 9 9 |  | 
| 10 10 | 
             
                    return default if Howzit.options[:default]
         | 
| 11 | 
            -
             | 
| 12 | 
            -
                    system 'stty cbreak'
         | 
| 11 | 
            +
                    tty_state = `stty -g`
         | 
| 12 | 
            +
                    system 'stty raw -echo cbreak isig'
         | 
| 13 13 | 
             
                    yn = color_single_options(default ? %w[Y n] : %w[y N])
         | 
| 14 14 | 
             
                    $stdout.syswrite "\e[1;37m#{prompt} #{yn}\e[1;37m? \e[0m"
         | 
| 15 15 | 
             
                    res = $stdin.sysread 1
         | 
| 16 16 | 
             
                    res.chomp!
         | 
| 17 17 | 
             
                    puts
         | 
| 18 18 | 
             
                    system 'stty cooked'
         | 
| 19 | 
            +
                    system "stty #{tty_state}"
         | 
| 19 20 | 
             
                    res.empty? ? default : res =~ /y/i
         | 
| 20 21 | 
             
                  end
         | 
| 21 22 |  | 
| @@ -24,12 +25,12 @@ module Howzit | |
| 24 25 | 
             
                    choices.each do |choice|
         | 
| 25 26 | 
             
                      case choice
         | 
| 26 27 | 
             
                      when /[A-Z]/
         | 
| 27 | 
            -
                        out.push(Color.template("{ | 
| 28 | 
            +
                        out.push(Color.template("{bw}#{choice}{x}"))
         | 
| 28 29 | 
             
                      else
         | 
| 29 | 
            -
                        out.push(Color.template("{ | 
| 30 | 
            +
                        out.push(Color.template("{dw}#{choice}{xg}"))
         | 
| 30 31 | 
             
                      end
         | 
| 31 32 | 
             
                    end
         | 
| 32 | 
            -
                    Color.template("{ | 
| 33 | 
            +
                    Color.template("{xg}[#{out.join('/')}{xg}]{x}")
         | 
| 33 34 | 
             
                  end
         | 
| 34 35 |  | 
| 35 36 | 
             
                  def options_list(matches)
         | 
    
        data/lib/howzit/stringutils.rb
    CHANGED
    
    
    
        data/lib/howzit/topic.rb
    CHANGED
    
    | @@ -9,6 +9,12 @@ module Howzit | |
| 9 9 |  | 
| 10 10 | 
             
                attr_reader :title, :tasks, :prereqs, :postreqs
         | 
| 11 11 |  | 
| 12 | 
            +
                ##
         | 
| 13 | 
            +
                ## Initialize a topic object
         | 
| 14 | 
            +
                ##
         | 
| 15 | 
            +
                ## @param      title    [String] The topic title
         | 
| 16 | 
            +
                ## @param      content  [String] The raw topic content
         | 
| 17 | 
            +
                ##
         | 
| 12 18 | 
             
                def initialize(title, content)
         | 
| 13 19 | 
             
                  @title = title
         | 
| 14 20 | 
             
                  @content = content
         | 
| @@ -17,18 +23,29 @@ module Howzit | |
| 17 23 | 
             
                  @tasks = gather_tasks
         | 
| 18 24 | 
             
                end
         | 
| 19 25 |  | 
| 26 | 
            +
                ##
         | 
| 27 | 
            +
                ## Search title and contents for a pattern
         | 
| 28 | 
            +
                ##
         | 
| 29 | 
            +
                ## @param      term  [String] the search pattern
         | 
| 30 | 
            +
                ##
         | 
| 20 31 | 
             
                def grep(term)
         | 
| 21 32 | 
             
                  @title =~ /#{term}/i || @content =~ /#{term}/i
         | 
| 22 33 | 
             
                end
         | 
| 23 34 |  | 
| 24 | 
            -
                # Handle run command, execute directives
         | 
| 35 | 
            +
                # Handle run command, execute directives in topic
         | 
| 25 36 | 
             
                def run(nested: false)
         | 
| 26 37 | 
             
                  output = []
         | 
| 27 38 | 
             
                  tasks = 0
         | 
| 39 | 
            +
                  cols = begin
         | 
| 40 | 
            +
                    TTY::Screen.columns > 60 ? 60 : TTY::Screen.columns
         | 
| 41 | 
            +
                  rescue StandardError
         | 
| 42 | 
            +
                    60
         | 
| 43 | 
            +
                  end
         | 
| 44 | 
            +
             | 
| 28 45 | 
             
                  if @tasks.count.positive?
         | 
| 29 46 | 
             
                    unless @prereqs.empty?
         | 
| 30 | 
            -
                      puts @prereqs.join("\n\n")
         | 
| 31 | 
            -
                      res = Prompt.yn(' | 
| 47 | 
            +
                      puts TTY::Box.frame("{by}#{@prereqs.join("\n\n").wrap(cols - 4)}{x}".c, width: cols)
         | 
| 48 | 
            +
                      res = Prompt.yn('Have the above prerequisites been met?', default: true)
         | 
| 32 49 | 
             
                      Process.exit 1 unless res
         | 
| 33 50 |  | 
| 34 51 | 
             
                    end
         | 
| @@ -85,7 +102,7 @@ module Howzit | |
| 85 102 | 
             
                  end
         | 
| 86 103 | 
             
                  output.push("{bm}Ran #{tasks} #{tasks == 1 ? 'task' : 'tasks'}{x}".c) if Howzit.options[:log_level] < 2 && !nested
         | 
| 87 104 |  | 
| 88 | 
            -
                  puts postreqs.join("\n\n") unless postreqs.empty?
         | 
| 105 | 
            +
                  puts TTY::Box.frame("{bw}#{@postreqs.join("\n\n").wrap(cols - 4)}{x}".c, width: cols) unless @postreqs.empty?
         | 
| 89 106 |  | 
| 90 107 | 
             
                  output
         | 
| 91 108 | 
             
                end
         | 
    
        data/lib/howzit/util.rb
    CHANGED
    
    | @@ -1,21 +1,26 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 1 3 | 
             
            module Howzit
         | 
| 4 | 
            +
              # Util class
         | 
| 2 5 | 
             
              module Util
         | 
| 3 6 | 
             
                class << self
         | 
| 7 | 
            +
                  def read_file(path)
         | 
| 8 | 
            +
                    IO.read(path).force_encoding('utf-8').strip
         | 
| 9 | 
            +
                  end
         | 
| 10 | 
            +
             | 
| 4 11 | 
             
                  def valid_command?(command)
         | 
| 5 12 | 
             
                    cmd = command.split(' ')[0]
         | 
| 6 13 | 
             
                    command_exist?(cmd)
         | 
| 7 14 | 
             
                  end
         | 
| 8 | 
            -
             | 
| 15 | 
            +
             | 
| 9 16 | 
             
                  def command_exist?(command)
         | 
| 10 17 | 
             
                    exts = ENV.fetch('PATHEXT', '').split(::File::PATH_SEPARATOR)
         | 
| 11 18 | 
             
                    if Pathname.new(command).absolute?
         | 
| 12 | 
            -
                      ::File.exist?(command) ||
         | 
| 13 | 
            -
                        exts.any? { |ext| ::File.exist?("#{command}#{ext}") }
         | 
| 19 | 
            +
                      ::File.exist?(command) || exts.any? { |ext| ::File.exist?("#{command}#{ext}") }
         | 
| 14 20 | 
             
                    else
         | 
| 15 21 | 
             
                      ENV.fetch('PATH', '').split(::File::PATH_SEPARATOR).any? do |dir|
         | 
| 16 22 | 
             
                        file = ::File.join(dir, command)
         | 
| 17 | 
            -
                        ::File.exist?(file) ||
         | 
| 18 | 
            -
                          exts.any? { |ext| ::File.exist?("#{file}#{ext}") }
         | 
| 23 | 
            +
                        ::File.exist?(file) || exts.any? { |ext| ::File.exist?("#{file}#{ext}") }
         | 
| 19 24 | 
             
                      end
         | 
| 20 25 | 
             
                    end
         | 
| 21 26 | 
             
                  end
         | 
    
        data/lib/howzit/version.rb
    CHANGED
    
    
    
        data/lib/howzit.rb
    CHANGED
    
    | @@ -21,6 +21,7 @@ require 'tempfile' | |
| 21 21 | 
             
            require 'yaml'
         | 
| 22 22 |  | 
| 23 23 | 
             
            require 'tty/screen'
         | 
| 24 | 
            +
            require 'tty/box'
         | 
| 24 25 | 
             
            # require 'tty/prompt'
         | 
| 25 26 |  | 
| 26 27 | 
             
            CONFIG_DIR = '~/.config/howzit'
         | 
| @@ -30,6 +31,7 @@ MATCHING_OPTIONS = %w[partial exact fuzzy beginswith].freeze | |
| 30 31 | 
             
            MULTIPLE_OPTIONS = %w[first best all choose].freeze
         | 
| 31 32 | 
             
            HEADER_FORMAT_OPTIONS = %w[border block].freeze
         | 
| 32 33 |  | 
| 34 | 
            +
            # Main module for howzit
         | 
| 33 35 | 
             
            module Howzit
         | 
| 34 36 | 
             
              class << self
         | 
| 35 37 | 
             
                attr_accessor :arguments, :cli_args
         | 
    
        data/spec/cli_spec.rb
    ADDED
    
    | @@ -0,0 +1,27 @@ | |
| 1 | 
            +
            # frozen_string_literal: true
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            require 'spec_helper'
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            # https://github.com/thoiberg/cli-test
         | 
| 6 | 
            +
            describe 'CLI' do
         | 
| 7 | 
            +
              include CliTest
         | 
| 8 | 
            +
             | 
| 9 | 
            +
              it 'executes successfully' do
         | 
| 10 | 
            +
                execute_script('bin/howzit', use_bundler: true)
         | 
| 11 | 
            +
                expect(last_execution).to be_successful
         | 
| 12 | 
            +
              end
         | 
| 13 | 
            +
             | 
| 14 | 
            +
              it 'lists available topics' do
         | 
| 15 | 
            +
                execute_script('bin/howzit', use_bundler: true, args: %w[-L])
         | 
| 16 | 
            +
                expect(last_execution).to be_successful
         | 
| 17 | 
            +
                expect(last_execution.stdout).to match(/Topic Balogna/)
         | 
| 18 | 
            +
                expect(last_execution.stdout.split(/\n/).count).to eq 3
         | 
| 19 | 
            +
              end
         | 
| 20 | 
            +
             | 
| 21 | 
            +
              it 'lists available tasks' do
         | 
| 22 | 
            +
                execute_script('bin/howzit', use_bundler: true, args: %w[-T])
         | 
| 23 | 
            +
                expect(last_execution).to be_successful
         | 
| 24 | 
            +
                expect(last_execution.stdout).to match(/Topic Balogna/)
         | 
| 25 | 
            +
                expect(last_execution.stdout.split(/\n/).count).to eq 2
         | 
| 26 | 
            +
              end
         | 
| 27 | 
            +
            end
         | 
    
        data/spec/spec_helper.rb
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: howzit
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 2.0. | 
| 4 | 
            +
              version: 2.0.9
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Brett Terpstra
         | 
| 8 8 | 
             
            autorequire:
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2022-08- | 
| 11 | 
            +
            date: 2022-08-05 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: bundler
         | 
| @@ -136,6 +136,20 @@ dependencies: | |
| 136 136 | 
             
                - - "~>"
         | 
| 137 137 | 
             
                  - !ruby/object:Gem::Version
         | 
| 138 138 | 
             
                    version: '3.1'
         | 
| 139 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 140 | 
            +
              name: cli-test
         | 
| 141 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 142 | 
            +
                requirements:
         | 
| 143 | 
            +
                - - "~>"
         | 
| 144 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 145 | 
            +
                    version: '1.0'
         | 
| 146 | 
            +
              type: :development
         | 
| 147 | 
            +
              prerelease: false
         | 
| 148 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 149 | 
            +
                requirements:
         | 
| 150 | 
            +
                - - "~>"
         | 
| 151 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 152 | 
            +
                    version: '1.0'
         | 
| 139 153 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 140 154 | 
             
              name: simplecov
         | 
| 141 155 | 
             
              requirement: !ruby/object:Gem::Requirement
         | 
| @@ -240,6 +254,20 @@ dependencies: | |
| 240 254 | 
             
                - - "~>"
         | 
| 241 255 | 
             
                  - !ruby/object:Gem::Version
         | 
| 242 256 | 
             
                    version: '0.8'
         | 
| 257 | 
            +
            - !ruby/object:Gem::Dependency
         | 
| 258 | 
            +
              name: tty-box
         | 
| 259 | 
            +
              requirement: !ruby/object:Gem::Requirement
         | 
| 260 | 
            +
                requirements:
         | 
| 261 | 
            +
                - - "~>"
         | 
| 262 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 263 | 
            +
                    version: '0.7'
         | 
| 264 | 
            +
              type: :runtime
         | 
| 265 | 
            +
              prerelease: false
         | 
| 266 | 
            +
              version_requirements: !ruby/object:Gem::Requirement
         | 
| 267 | 
            +
                requirements:
         | 
| 268 | 
            +
                - - "~>"
         | 
| 269 | 
            +
                  - !ruby/object:Gem::Version
         | 
| 270 | 
            +
                    version: '0.7'
         | 
| 243 271 | 
             
            description: Command line project documentation and task runner
         | 
| 244 272 | 
             
            email:
         | 
| 245 273 | 
             
            - me@brettterpstra.com
         | 
| @@ -283,6 +311,7 @@ files: | |
| 283 311 | 
             
            - spec/.rubocop.yml
         | 
| 284 312 | 
             
            - spec/buildnote_spec.rb
         | 
| 285 313 | 
             
            - spec/buildnotes.md.bak
         | 
| 314 | 
            +
            - spec/cli_spec.rb
         | 
| 286 315 | 
             
            - spec/ruby_gem_spec.rb
         | 
| 287 316 | 
             
            - spec/spec_helper.rb
         | 
| 288 317 | 
             
            - spec/task_spec.rb
         | 
| @@ -316,6 +345,7 @@ test_files: | |
| 316 345 | 
             
            - spec/.rubocop.yml
         | 
| 317 346 | 
             
            - spec/buildnote_spec.rb
         | 
| 318 347 | 
             
            - spec/buildnotes.md.bak
         | 
| 348 | 
            +
            - spec/cli_spec.rb
         | 
| 319 349 | 
             
            - spec/ruby_gem_spec.rb
         | 
| 320 350 | 
             
            - spec/spec_helper.rb
         | 
| 321 351 | 
             
            - spec/task_spec.rb
         |