Class: OKF::CLI::Index

Inherits:
Command show all
Defined in:
lib/okf/cli/index.rb

Overview

The progressive-disclosure map (spec ยง6): every directory that holds concepts or carries an index.md, with its authored index body, a type/tag rollup, its child directories, and โ€” for a directory with no index.md โ€” the listing synthesized from the concepts there. The "orient before you read" view. --dir is repeatable and selects a directory and its subtree (root is the bundle root), --depth N bounds how far below the starting point that goes, and --no-body drops the prose to a skeleton; advisory, exit 0.

The two narrowings are what make the map usable on a deep bundle: every directory is a section, so a few hundred concepts is a map nobody reads at once. --depth 1 is the top of the tree, --dir X --depth 1 is one branch of it, and the pair walks down a level at a time.

Constant Summary

Constants inherited from Command

Command::DUCK_TYPE

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Command

hidden?, #initialize

Constructor Details

This class inherits a constructor from OKF::CLI::Command

Class Method Details

.groupObject



22
23
24
# File 'lib/okf/cli/index.rb', line 22

def self.group
  :read
end

.help_rowsObject



26
27
28
29
30
# File 'lib/okf/cli/index.rb', line 26

def self.help_rows
  [
    [ "index     <dir|@slug> [--dir D] [--depth N] [--no-body]", "the index map: dirs, their listings and rollups" ]
  ]
end

.idObject



18
19
20
# File 'lib/okf/cli/index.rb', line 18

def self.id
  :index
end

Instance Method Details

#call(argv) ⇒ Object



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/okf/cli/index.rb', line 32

def call(argv)
  options = { json: false, body: true, dirs: nil, areas: nil, depth: nil, ancestors: true }
  parser = OptionParser.new do |o|
    o.banner = "Usage: okf index <dir|@slug> [--dir PATH] [--depth N] [--no-body] [--json]"
    json_flags(o, options, "emit the index map as JSON")
    projection_flags(o, options)
    o.on("--dir PATH", "only this directory and the ones below it",
      "(repeatable; `root` for the bundle root)") { |v| (options[:dirs] ||= []) << v }
    depth_flag(o, options)
    ancestors_flag(o, options)
    o.on("--area AREA", "deprecated: use --dir (this directory exactly)") do |v|
      (options[:areas] ||= []) << v
      deprecated("--area", "--dir")
    end
    o.on("--[no-]body", "include each index's prose body (default: yes)") { |v| options[:body] = v }
    help_flag(o)
  end
  dir = positional_dir(parser, argv) or return 2
  bad_depth = depth_error(options)
  return bad_depth if bad_depth
  # --area is exact and names no starting point, so --depth has nothing to
  # be relative *to*: the pair used to union the area with every directory
  # at that depth from the root. Refusing beats answering with more.
  #
  # --dir is refused for the same reason and not a weaker one: one flag is
  # exact and the other a prefix, so the pair came back with the area *and*
  # the subtree โ€” an answer to neither question, from a combination only
  # someone mid-migration would type. A deprecated flag that quietly widens
  # is worse than one that is merely old.
  if options[:areas] && (options[:depth] || options[:dirs])
    return usage_error("--area and #{options[:dirs] ? "--dir" : "--depth"} do not combine: use --dir")
  end

  folder = OKF::Bundle::Folder.load(dir)
  report_skipped(folder)
  entries = folder.directory_index
  selected, chain = select_directories(entries, options)
  if options[:json]
    # --no-body is shorthand for --except body, so asking for the body by
    # name in the same breath is a contradiction. Letting --fields quietly
    # win would hand back the very thing the other flag was there to drop.
    if !options[:body] && Array(options[:fields]).map(&:downcase).include?("body")
      return usage_error("--no-body and --fields body contradict each other: drop one")
    end

    options[:except] = Array(options[:except]) + [ "body" ] unless options[:body] || options[:fields]
    return print_index_map_json(dir, selected, chain, options)
  end
  print_index_map(dir, selected, chain, options[:body])
  0
end