hello: create new standalone module example

We want to revive golang.org/x/example as a test case for
an experiment with a 'gonew' command.

This CL changes the hello world program to be standalone
and demonstrate a bit more about flag parsing and command-line
logging.

Change-Id: Iee481344c801f046813806a537d59e3242f9152a
Reviewed-on: https://go-review.googlesource.com/c/example/+/513996
Reviewed-by: Cameron Balahan <cbalahan@google.com>
Run-TryBot: Russ Cox <rsc@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Auto-Submit: Russ Cox <rsc@golang.org>
diff --git a/README.md b/README.md
index 2dad874..253a18f 100644
--- a/README.md
+++ b/README.md
@@ -13,21 +13,25 @@
 ```
 https://go.googlesource.com/example is the canonical Git repository.
 It is mirrored at https://github.com/golang/example.
-## [hello](hello/) and [stringutil](stringutil/)
+
+## [hello](hello/) and [hello/reverse](hello/reverse/)
 
 ```
 $ cd hello
 $ go build
+$ ./hello -help
 ```
-A trivial "Hello, world" program that uses a stringutil package.
+A trivial "Hello, world" program that uses a library package.
 
-Command [hello](hello/) covers:
+The [hello](hello/) command covers:
 
 * The basic form of an executable command
 * Importing packages (from the standard library and the local repository)
 * Printing strings ([fmt](//golang.org/pkg/fmt/))
+* Command-line flags ([flag](//golang.org/pkg/flag/))
+* Logging ([log](//golang.org/pkg/log/))
 
-Library [stringutil](stringutil/) covers:
+The [reverse](hello/reverse/) reverse covers:
 
 * The basic form of a library
 * Conversion between string and []rune
@@ -37,7 +41,7 @@
 
 ```
 $ cd outyet
-$ go build
+$ go run .
 ```
 A web server that answers the question: "Is Go 1.x out yet?"
 
diff --git a/hello/go.mod b/hello/go.mod
new file mode 100644
index 0000000..eb0dea6
--- /dev/null
+++ b/hello/go.mod
@@ -0,0 +1,4 @@
+module golang.org/x/example/hello
+
+go 1.19
+
diff --git a/hello/hello.go b/hello/hello.go
index 38802d2..ce2a423 100644
--- a/hello/hello.go
+++ b/hello/hello.go
@@ -2,14 +2,71 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
+// Hello is a hello, world program, demonstrating
+// how to write a simple command-line program.
+//
+// Usage:
+//
+//	hello [options] [name]
+//
+// The options are:
+//
+//	-g greeting
+//		Greet with the given greeting, instead of "Hello".
+//
+//	-r
+//		Greet in reverse.
+//
+// By default, hello greets the world.
+// If a name is specified, hello greets that name instead.
 package main
 
 import (
+	"flag"
 	"fmt"
+	"log"
+	"os"
 
-	"golang.org/x/example/stringutil"
+	"golang.org/x/example/hello/reverse"
+)
+
+func usage() {
+	fmt.Fprintf(os.Stderr, "usage: hello [options] [name]\n")
+	flag.PrintDefaults()
+	os.Exit(2)
+}
+
+var (
+	greeting    = flag.String("g", "Hello", "Greet with `greeting`")
+	reverseFlag = flag.Bool("r", false, "Greet in reverse")
 )
 
 func main() {
-	fmt.Println(stringutil.Reverse("!selpmaxe oG ,olleH"))
+	// Configure logging for a command-line program.
+	log.SetFlags(0)
+	log.SetPrefix("hello: ")
+
+	// Parse flags.
+	flag.Usage = usage
+	flag.Parse()
+
+	// Parse and validate arguments.
+	name := "world"
+	args := flag.Args()
+	if len(args) >= 2 {
+		usage()
+	}
+	if len(args) >= 1 {
+		name = args[0]
+	}
+	if name == "" { // hello '' is an error
+		log.Fatalf("invalid name %q", name)
+	}
+
+	// Run actual logic.
+	if *reverseFlag {
+		fmt.Printf("%s, %s!\n", reverse.String(*greeting), reverse.String(name))
+		return
+	}
+	fmt.Printf("%s, %s!\n", *greeting, name)
 }
diff --git a/hello/reverse/reverse.go b/hello/reverse/reverse.go
new file mode 100644
index 0000000..b6fe74a
--- /dev/null
+++ b/hello/reverse/reverse.go
@@ -0,0 +1,15 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package reverse can reverse things, particularly strings.
+package reverse
+
+// String returns its argument string reversed rune-wise left to right.
+func String(s string) string {
+	r := []rune(s)
+	for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
+		r[i], r[j] = r[j], r[i]
+	}
+	return string(r)
+}
diff --git a/stringutil/reverse_test.go b/hello/reverse/reverse_test.go
similarity index 71%
rename from stringutil/reverse_test.go
rename to hello/reverse/reverse_test.go
index 9dbe42f..d130117 100644
--- a/stringutil/reverse_test.go
+++ b/hello/reverse/reverse_test.go
@@ -2,11 +2,11 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-package stringutil
+package reverse
 
 import "testing"
 
-func TestReverse(t *testing.T) {
+func TestString(t *testing.T) {
 	for _, c := range []struct {
 		in, want string
 	}{
@@ -14,9 +14,9 @@
 		{"Hello, 世界", "界世 ,olleH"},
 		{"", ""},
 	} {
-		got := Reverse(c.in)
+		got := String(c.in)
 		if got != c.want {
-			t.Errorf("Reverse(%q) == %q, want %q", c.in, got, c.want)
+			t.Errorf("String(%q) == %q, want %q", c.in, got, c.want)
 		}
 	}
 }
diff --git a/stringutil/reverse.go b/stringutil/reverse.go
deleted file mode 100644
index c7b2463..0000000
--- a/stringutil/reverse.go
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2023 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Package stringutil contains utility functions for working with strings.
-package stringutil
-
-// Reverse returns its argument string reversed rune-wise left to right.
-func Reverse(s string) string {
-	r := []rune(s)
-	for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
-		r[i], r[j] = r[j], r[i]
-	}
-	return string(r)
-}