-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathdocopt-convert
executable file
·118 lines (79 loc) · 2.28 KB
/
docopt-convert
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#!/usr/bin/env perl
use strict;
use warnings;
no warnings 'uninitialized';
use Docopt;
use JSON;
use autobox::Core;
use Path::Tiny;
use Try::Tiny;
my $options = docopt();
my $app_argv = $options->{"<argv>"};
my $doc;
my $basename;
foreach my $doc_file_name ($options->{"<file.docopt>"}->split(",")) {
my $doc_file = path($doc_file_name);
my $current_doc .= $doc_file->slurp;
if ($current_doc =~ /^### docopt [#|\n]*(.+)/sm) {
$current_doc = $1;
}
$doc .= $current_doc;
$basename ||= $doc_file->basename;
}
my $docopt_ran = 0;
$doc =~ s/\$0/$basename/gm;
parse_external_doc($doc, $app_argv);
sub parse_external_doc {
my ($doc, $argv) = @_;
my $app_options = docopt(doc => $doc, argv => $argv);
$docopt_ran = 1;
convert_booleans($app_options);
my $env_vars = generate_env_vars($app_options);
my $json =
JSON->new->pretty($options->{'--pretty'})->encode($app_options);
$json =~ s/"boolean:(true|false)"/$1/gm;
print $json if $options->{'--json'};
print $env_vars if $options->{'--env'};
}
sub generate_env_vars {
my ($app_options) = @_;
my $env_vars;
foreach my $key (keys %$app_options) {
my $value = $app_options->{$key};
next if $value =~ /^\s*$/;
$key =~ s/\W/_/g;
$key =~ s/^_*//g;
$key =~ s/_*$//g;
$key = "docopt_" . $key;
$value = 1 if $value =~ /^boolean:true$/;
$value = 0 if $value =~ /^boolean:false$/;
$env_vars .= "export $key='$value'; ";
}
return $env_vars;
}
sub convert_booleans {
my ($twig) = @_;
if (!ref $twig eq 'HASH') {
return;
}
$twig->each(
sub {
my ($key, $value) = @_;
rec($value) if ref($value) eq 'HASH';
$twig->{$key} = $value == 1 ? "boolean:true" : "boolean:false"
if ref $value eq 'boolean';
}
);
}
# Prevent docopt to exit with 0 if --help is specified
END { exit 1 if !$docopt_ran; }
__END__
=head1 NAME
docopt-convert - Convert a docopt specification
=head1 SYNOPSIS
docopt-convert [options] <file.docopt> -- [<argv>...]
Options:
-h --help Show this screen.
--json Output JSON
--env Output environment variables for eval
-p --pretty Pretty print JSON