1919package main
2020
2121import (
22+ "flag"
2223 "fmt"
2324 "net/url"
2425 "os"
2526 "path"
2627 "strings"
2728
2829 // CaltechLibrary Packages
29- "github.com/caltechlibrary/cli"
3030 "github.com/caltechlibrary/datatools"
3131)
3232
3333var (
34- description = `
35- %s can parse a URL and return the specific elements
34+ helpText = `---
35+ title: "{app_name} (1) user manual"
36+ author: "R. S. Doiel"
37+ pubDate: 2023-01-09
38+ ---
39+
40+ # NAME
41+
42+ {app_name}
43+
44+ # SYNOPSIS
45+
46+ {app_name} [OPTIONS] URL_TO_PARSE
47+
48+ # DESCRIPTION
49+
50+ {app_name} can parse a URL and return the specific elements
3651requested (e.g. protocol, hostname, path, query string)
37- `
3852
39- examples = `
53+ # OPTIONS
54+
55+ -help
56+ : display help
57+
58+ -license
59+ : display license
60+
61+ -version
62+ : display version
63+
64+ -H, -host
65+ : Display the hostname (and port if specified) found in URL.
66+
67+ -P, -protocol
68+ : Display the protocol of URL (defaults to http)
69+
70+ -base, -basename
71+ : Display the base filename at the end of the path.
72+
73+ -d, -delimiter
74+ : Set the output delimited for parsed display. (defaults to tab)
75+
76+ -dir, -dirname
77+ : Display all but the last element of the path
78+
79+ -ext, -extname
80+ : Display the filename extension (e.g. .html).
81+
82+ -i, -input
83+ : input filename
84+
85+ -nl, -newline
86+ : if true add a trailing newline
87+
88+ -o, -output
89+ : output filename
90+
91+ -p, -path
92+ : Display the path after the hostname.
93+
94+ -quiet
95+ : suppress error messages
96+
97+
98+ # EXAMPLES
99+
40100With no options returns "http\texample.com\t/my/page.html"
41101
42- %s http://example.com/my/page.html
102+ ~~~
103+ {app_name} http://example.com/my/page.html
104+ ~~~
43105
44106Get protocol. Returns "http".
45107
46- %s -protocol http://example.com/my/page.html
108+ ~~~
109+ {app_name} -protocol http://example.com/my/page.html
110+ ~~~
47111
48112Get host or domain name. Returns "example.com".
49113
50- %s -host http://example.com/my/page.html
114+ ~~~
115+ {app_name} -host http://example.com/my/page.html
116+ ~~~
51117
52118Get path. Returns "/my/page.html".
53119
54- %s -path http://example.com/my/page.html
120+ ~~~
121+ {app_name} -path http://example.com/my/page.html
122+ ~~~
55123
56124Get dirname. Returns "my"
57125
58- %s -dirname http://example.com/my/page.html
126+ ~~~
127+ {app_name} -dirname http://example.com/my/page.html
128+ ~~~
59129
60130Get basename. Returns "page.html".
61131
62- %s -basename http://example.com/my/page.html
132+ ~~~
133+ {app_name} -basename http://example.com/my/page.html
134+ ~~~
63135
64136Get extension. Returns ".html".
65137
66- %s -extname http://example.com/my/page.html
138+ ~~~
139+ {app_name} -extname http://example.com/my/page.html
140+ ~~~
67141
68- Without options urlparse returns protocol, host and path
142+ Without options {app_name} returns protocol, host and path
69143fields separated by a tab.
144+
145+ {app_name} {version}
70146`
71147
72148 // Standard Options
@@ -95,6 +171,10 @@ fields separated by a tab.
95171 delimiter = "\t "
96172)
97173
174+ func fmtTxt (src string , appName string , version string ) string {
175+ return strings .ReplaceAll (strings .ReplaceAll (src , "{app_name}" , appName ), "{version}" , version )
176+ }
177+
98178func main () {
99179 const (
100180 delimiterUsage = "Set the output delimited for parsed display. (defaults to tab)"
@@ -106,90 +186,98 @@ func main() {
106186 extnameUsage = "Display the filename extension (e.g. .html)."
107187 )
108188
109- app := cli .NewCli (datatools .Version )
110- appName := app .AppName ()
189+ appName := path .Base (os .Args [0 ])
111190
112- // Add Help Docs
113- app . AddHelp ( "license " , [] byte ( fmt . Sprintf ( datatools . LicenseText , appName , datatools . Version )) )
114- app . AddHelp ( "description " , [] byte ( fmt . Sprintf ( description , appName )) )
115- app . AddHelp ( "examples " , [] byte ( fmt . Sprintf ( examples , appName , appName , appName , appName , appName , appName , appName )) )
191+ // Standard Options
192+ flag . BoolVar ( & showHelp , "help " , false , "display help" )
193+ flag . BoolVar ( & showLicense , "license " , false , "display license" )
194+ flag . BoolVar ( & showVersion , "version " , false , "display version" )
116195
117- // Document non-option parameters
118- app .SetParams ("URL_TO_PARSE" )
196+ flag .StringVar (& inputFName , "i" , "" , "input filename" )
197+ flag .StringVar (& inputFName , "input" , "" , "input filename" )
198+ flag .StringVar (& outputFName , "o" , "" , "output filename" )
199+ flag .StringVar (& outputFName , "output" , "" , "output filename" )
200+
119201
120- // Standard Options
121- app .BoolVar (& showHelp , "h,help" , false , "display help" )
122- app .BoolVar (& showLicense , "l,license" , false , "display license" )
123- app .BoolVar (& showVersion , "v,version" , false , "display version" )
124- app .BoolVar (& showExamples , "examples" , false , "display example(s)" )
125- app .StringVar (& inputFName , "i,input" , "" , "input filename" )
126- app .StringVar (& outputFName , "o,output" , "" , "output filename" )
127- app .BoolVar (& generateMarkdown , "generate-markdown" , false , "generate markdown documentation" )
128- app .BoolVar (& generateManPage , "generate-manpage" , false , "generate man page" )
129- app .BoolVar (& quiet , "quiet" , false , "suppress error messages" )
130- app .BoolVar (& newLine , "nl,newline" , false , "if true add a trailing newline" )
202+ flag .BoolVar (& quiet , "quiet" , false , "suppress error messages" )
203+ flag .BoolVar (& newLine , "nl" , false , "if true add a trailing newline" )
204+ flag .BoolVar (& newLine , "newline" , false , "if true add a trailing newline" )
131205
132206 // App Specific Options
133- app .StringVar (& delimiter , "d,delimiter" , delimiter , delimiterUsage )
134- app .BoolVar (& showProtocol , "P,protocol" , false , protocolUsage )
135- app .BoolVar (& showHost , "H,host" , false , hostUsage )
136- app .BoolVar (& showPath , "p,path" , false , pathUsage )
137- app .BoolVar (& showDir , "dir,dirname" , false , dirnameUsage )
138- app .BoolVar (& showBase , "base,basename" , false , basenameUsage )
139- app .BoolVar (& showExtension , "ext,extname" , false , extnameUsage )
207+ flag .StringVar (& delimiter , "d" , delimiter , delimiterUsage )
208+ flag .StringVar (& delimiter , "delimiter" , delimiter , delimiterUsage )
209+ flag .BoolVar (& showProtocol , "P" , false , protocolUsage )
210+ flag .BoolVar (& showProtocol , "protocol" , false , protocolUsage )
211+ flag .BoolVar (& showHost , "H" , false , hostUsage )
212+ flag .BoolVar (& showHost , "host" , false , hostUsage )
213+ flag .BoolVar (& showPath , "p" , false , pathUsage )
214+ flag .BoolVar (& showPath , "path" , false , pathUsage )
215+ flag .BoolVar (& showDir , "dir" , false , dirnameUsage )
216+ flag .BoolVar (& showDir , "dirname" , false , dirnameUsage )
217+ flag .BoolVar (& showBase , "base" , false , basenameUsage )
218+ flag .BoolVar (& showBase , "basename" , false , basenameUsage )
219+ flag .BoolVar (& showExtension , "ext" , false , extnameUsage )
220+ flag .BoolVar (& showExtension , "extname" , false , extnameUsage )
221+
222+ // Parse env and options
223+ flag .Parse ()
224+ args := flag .Args ()
140225
141226 // Setup IO
142227 var err error
143- app .Eout = os .Stderr
144228
145- app . In , err = cli . Open ( inputFName , os .Stdin )
146- cli . ExitOnError ( app . Eout , err , quiet )
147- defer cli . CloseFile ( inputFName , app . In )
229+ in := os .Stdin
230+ out := os . Stdout
231+ eout := os . Stderr
148232
149- app .Out , err = cli .Create (outputFName , os .Stdout )
150- cli .ExitOnError (app .Eout , err , quiet )
151- defer cli .CloseFile (outputFName , app .Out )
233+ if inputFName != "" {
234+ in , err = os .Open (inputFName )
235+ if err != nil {
236+ fmt .Fprintln (eout , err )
237+ os .Exit (1 )
238+ }
239+ defer in .Close ()
240+ }
241+
242+ if outputFName != "" {
243+ out , err = os .Create (outputFName )
244+ if err != nil {
245+ fmt .Fprintln (eout , err )
246+ os .Exit (1 )
247+ }
248+ defer out .Close ()
249+ }
152250
153- // Parse env and options
154- app .Parse ()
155- args := app .Args ()
156251
157252 // Process Options
158- if generateMarkdown {
159- app .GenerateMarkdown (app .Out )
160- os .Exit (0 )
161- }
162- if generateManPage {
163- app .GenerateManPage (app .Out )
164- os .Exit (0 )
165- }
166- if showHelp || showExamples {
167- if len (args ) > 0 {
168- fmt .Fprintln (app .Out , app .Help (args ... ))
169- } else {
170- app .Usage (app .Out )
171- }
253+ if showHelp {
254+ fmt .Fprintf (out , "%s\n " , fmtTxt (helpText , appName , datatools .Version ))
172255 os .Exit (0 )
173256 }
174257 if showLicense {
175- fmt .Fprintln ( app . Out , app . License () )
258+ fmt .Fprintf ( out , "%s \n " , datatools . LicenseText )
176259 os .Exit (0 )
177260 }
178261 if showVersion {
179- fmt .Fprintln ( app . Out , app .Version () )
262+ fmt .Fprintf ( out , "%s %s \n " , appName , datatools .Version )
180263 os .Exit (0 )
181264 }
182265 if newLine {
183266 eol = "\n "
184267 }
185268
269+ argc := len (args )
186270 results := []string {}
187- urlToParse := app . Arg ( 0 )
188- if urlToParse == "" {
189- cli . ExitOnError ( app . Eout , fmt . Errorf ( "Missing URL to parse" ), quiet )
271+ if argc == 0 {
272+ fmt . Fprintln ( eout , "Missing URL to parse" )
273+ os . Exit ( 1 )
190274 }
275+ urlToParse := args [0 ]
191276 u , err := url .Parse (urlToParse )
192- cli .ExitOnError (app .Eout , err , quiet )
277+ if err != nil {
278+ fmt .Fprintln (eout , err )
279+ os .Exit (1 )
280+ }
193281
194282 useDelim := delimiter
195283 if showProtocol == true {
@@ -212,9 +300,9 @@ func main() {
212300 }
213301
214302 if len (results ) == 0 {
215- fmt .Fprintf (app . Out , "%s%s%s%s%s%s" ,
303+ fmt .Fprintf (out , "%s%s%s%s%s%s" ,
216304 u .Scheme , useDelim , u .Host , useDelim , u .Path , eol )
217305 } else {
218- fmt .Fprintf (app . Out , "%s%s" , strings .Join (results , useDelim ), eol )
306+ fmt .Fprintf (out , "%s%s" , strings .Join (results , useDelim ), eol )
219307 }
220308}
0 commit comments