| 1 | module help |
| 2 | |
| 3 | import os |
| 4 | |
| 5 | // Topics whose module uses the cli or flag modules (both support --help). |
| 6 | const cli_topics = ['new', 'init', 'repeat'] |
| 7 | |
| 8 | fn hdir(base string) string { |
| 9 | return os.join_path(base, 'vlib', 'v', 'help') |
| 10 | } |
| 11 | |
| 12 | fn help_dir() string { |
| 13 | vexe := get_vexe() |
| 14 | if vexe != '' { |
| 15 | return hdir(os.dir(vexe)) |
| 16 | } |
| 17 | // use @VEXEROOT, but only if everything else fails; the negative of using it, |
| 18 | // is that it will depend on the filesystem of the host that built v |
| 19 | return hdir(@VEXEROOT) |
| 20 | } |
| 21 | |
| 22 | @[params] |
| 23 | pub struct ExitOptions { |
| 24 | pub: |
| 25 | exit_code int |
| 26 | } |
| 27 | |
| 28 | // print_and_exit prints the help topic and exits. |
| 29 | @[noreturn] |
| 30 | pub fn print_and_exit(topic string, opts ExitOptions) { |
| 31 | if topic == 'topics' { |
| 32 | print_known_topics() |
| 33 | exit(opts.exit_code) |
| 34 | } |
| 35 | fail_code := if opts.exit_code != 0 { opts.exit_code } else { 1 } |
| 36 | for c in topic { |
| 37 | if !c.is_letter() && !c.is_digit() && c != `-` { |
| 38 | print_topic_unknown(topic) |
| 39 | exit(fail_code) |
| 40 | } |
| 41 | } |
| 42 | if topic in cli_topics { |
| 43 | vexe := get_vexe() |
| 44 | os.system('${os.quoted_path(vexe)} ${topic} --help') |
| 45 | exit(opts.exit_code) |
| 46 | } |
| 47 | mut topic_path := '' |
| 48 | for path in os.walk_ext(help_dir(), '.txt') { |
| 49 | if topic == os.file_name(path).all_before('.txt') { |
| 50 | topic_path = path |
| 51 | break |
| 52 | } |
| 53 | } |
| 54 | if topic_path == '' { |
| 55 | print_topic_unknown(topic) |
| 56 | print_known_topics() |
| 57 | exit(fail_code) |
| 58 | } |
| 59 | topic_content := os.read_file(topic_path) or { |
| 60 | msg := err.str() |
| 61 | eprintln('error: failed reading topic file: ${msg}') |
| 62 | exit(fail_code) |
| 63 | } |
| 64 | cleaned := topic_content.trim_space() |
| 65 | println(cleaned) |
| 66 | exit(opts.exit_code) |
| 67 | } |
| 68 | |
| 69 | fn print_topic_unknown(topic string) { |
| 70 | eprintln('error: unknown help topic "${topic}". Use `v help` for usage information.') |
| 71 | } |
| 72 | |
| 73 | fn print_known_topics() { |
| 74 | topic_paths := os.walk_ext(help_dir(), '.txt') |
| 75 | mut res := []string{} |
| 76 | for path in topic_paths { |
| 77 | topic := os.file_name(path).all_before('.txt') |
| 78 | if topic != 'default' { |
| 79 | res << topic |
| 80 | } |
| 81 | } |
| 82 | sorted_topics := res.sorted() |
| 83 | println('Known help topics: ${sorted_topics}') |
| 84 | } |
| 85 | |
| 86 | fn get_vexe() string { |
| 87 | mut vexe := os.getenv('VEXE') |
| 88 | if vexe == '' { |
| 89 | vexe = os.executable() |
| 90 | } |
| 91 | return vexe |
| 92 | } |
| 93 | |