From 751e5a41e1644e5489faeebff7fec8f6894cd526 Mon Sep 17 00:00:00 2001 From: RuneImp Date: Wed, 10 Feb 2021 18:31:42 -0800 Subject: [PATCH 1/3] updated release and distrobution code --- .goreleaser.yml | 8 ++++++++ Justfile | 5 ++++- distro/.gitignore | 1 + 3 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 distro/.gitignore diff --git a/.goreleaser.yml b/.goreleaser.yml index 0e43240..c771a30 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -9,6 +9,14 @@ before: builds: - env: - CGO_ENABLED=0 + goarch: + - 386 + - amd64 + - arm + - arm64 + goarm: + - 6 + - 7 goos: - darwin - freebsd diff --git a/Justfile b/Justfile index 468f376..81711cb 100644 --- a/Justfile +++ b/Justfile @@ -10,13 +10,16 @@ alias arc := archive archive: #!/bin/sh just _term-wipe - tag="$(git tag --points-at master)" + tag="$(git tag --points-at main)" app="{{PROJECT_NAME}}" arc="${app}_${tag}" # echo "app = '${app}'" # echo "tag = '${tag}'" # echo "arc = '${arc}'" + if [ ! -e distro ]; then + mkdir distro + fi if [ -e dist ]; then echo "Move dist -> distro/${arc}" mv dist "distro/${arc}" diff --git a/distro/.gitignore b/distro/.gitignore new file mode 100644 index 0000000..72e8ffc --- /dev/null +++ b/distro/.gitignore @@ -0,0 +1 @@ +* From 774df43ec088703263861245267f954c3c144c78 Mon Sep 17 00:00:00 2001 From: RuneImp Date: Tue, 13 Apr 2021 17:56:41 -0700 Subject: [PATCH 2/3] added option to add timezone to datetime in filename added option to base the datetime on the modification time of the file being compressed added unit testing updated option parsing updated help display updated docs --- CHANGELOG.md | 11 +++ INSTALL.md | 14 +-- Justfile | 13 +++ README.md | 42 ++++++--- go.mod | 2 + go.sum | 9 ++ main.go | 243 +++++++++++++++++++++++++++++++++++++++++---------- main_test.go | 111 +++++++++++++++++++++++ 8 files changed, 379 insertions(+), 66 deletions(-) create mode 100644 go.sum create mode 100644 main_test.go diff --git a/CHANGELOG.md b/CHANGELOG.md index cee34e4..942091d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,17 @@ ChangeLog: ========== +v1.1.0 +------ + +* Added option to add timezone to datetime in filename +* Added option to base the datetime on the modification time of the file being compressed +* Added unit testing +* Updated option parsing +* Updated help display +* Updated docs + + v1.0.0 ------ diff --git a/INSTALL.md b/INSTALL.md index e541f81..e536f3f 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -5,18 +5,18 @@ Installation 1. Download a release from `https://github.com/runeimp/gzipdate/releases` 2. For archives or packages: * For Zip archives (`.zip`) I recommend: - 1. `unzip gzipdate_1.0.1_windows_x86_64.zip` - 2. `cd gzipdate_1.0.1_windows_x86_64` + 1. `unzip gzipdate_1.1.0_windows_x86_64.zip` + 2. `cd gzipdate_1.1.0_windows_x86_64` 3. `copy gzipdate.exe YOUR_PREFERED_PATH` * For Tar-Gzip archives (`.tar.gz`) I recommend: - 1. `tar xfz gzipdate_1.0.1_freebsd_x86_64.tar.gz` - 2. `cd gzipdate_1.0.1_freebsd_x86_64` + 1. `tar xfz gzipdate_1.1.0_freebsd_x86_64.tar.gz` + 2. `cd gzipdate_1.1.0_freebsd_x86_64` 3. `cp gzipdate YOUR_PREFERED_PATH` or `ln -s gzipdate YOUR_PREFERED_PATH/gzipdate` if your source folder is not going to get deleted later. * For the Debian packages (`.deb`) I recommend: - * `sudo dpkg -i /path/to/gzipdate_1.0.1_linux_x86_64.deb` to install and upgrade. There are no dependencies so dpkg is fine for this task. + * `sudo dpkg -i /path/to/gzipdate_1.1.0_linux_x86_64.deb` to install and upgrade. There are no dependencies so dpkg is fine for this task. * For the RedHat Package Manager (`.rpm`) I recommend: - * `rpm -i /path/to/gzipdate_1.0.1_linux_x86_64.rpm` to install - * `rpm -U /path/to/gzipdate_1.0.1_linux_x86_64.rpm` to upgrade + * `rpm -i /path/to/gzipdate_1.1.0_linux_x86_64.rpm` to install + * `rpm -U /path/to/gzipdate_1.1.0_linux_x86_64.rpm` to upgrade 3. Copy the binary to a directory in your PATH and make sure it is executable for your system. It _should_ be ready to go by default. diff --git a/Justfile b/Justfile index 81711cb..94ed031 100644 --- a/Justfile +++ b/Justfile @@ -56,6 +56,19 @@ run +args='': go run main.go {{args}} +# Run a test +@test cmd="coverage": + just _term-wipe + just test-{{cmd}} + +# Run Go Unit Tests +@test-coverage: + just _term-wipe + echo "You need to run:" + echo "go test -coverprofile=c.out" + echo "go tool cover -func=c.out" + + _term-wipe: #!/bin/sh if [[ ${#VISUAL_STUDIO_CODE} -gt 0 ]]; then diff --git a/README.md b/README.md index ad6d55d..2c0dd0b 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,10 @@ Simple command line app for the specific creation and handling of Gzip archives. Features -------- -* Create gzip archives for each of a list of files, adding a file system safe [ISO-8601][ISO 8601 - Wikipedia] datatime value to the filename when creating the archive. The format is `YYYY-MM-DD_HHmmss`. +* Create gzip archives for each of a list of files, adding a file system safe [ISO-8601][ISO 8601 - Wikipedia] datatime value to the filename when creating the archive. + * The format is either `YYYY-MM-DD_HHmmss_TZ` or `YYYY-MM-DD_HHmmss`. + * The default is `YYYY-MM-DD_HHmmss` but in v1.1+ you can use `YYYY-MM-DD_HHmmss_TZ` by specifying an environment variable `GZIPDATE=TIMEZONE` or `GZIPDATE=TZ`, or using the option `-t`, `-tz`, `-timezone`, or `--timezone` for a single execution. + * The default datetime is based on the current system time. But you can specify to use the modification time of the file with the options `-f`, `-file`, `-file-date`, or `--file-date` * Extract the archived file from Gzip archives restoring their original names if available. The original name is always available for archives created by GzipDate. * Does not delete source files by default. Though they can be automatically deleted with a command line switch. * Always uses maximum compression when creating archives @@ -20,35 +23,45 @@ Usage Examples ### Help -```text -$ gzipdate -h -GzipDate v1.0.0 +```bash +runeimp$ gzipdate -h +GzipDate v1.1.0 USAGE: gzipdate [OPTIONS] [FILENAMES] OPTIONS: - -d | -del | -delete Delete the source file after successful processing - -h | -help Display this help info - -v | -ver | -version Display this apps version number + -d | -del | --delete Delete the source file after processing + -f | -file | --file-date Use the files modification time for the date + instead of the current time + -h | -help | --help Display this help info + -t | -tz | --timezone Turn the timezone feature on + -v | -ver | --version Display this apps version number + -- Disable option parsing and consider all following + arguments as file names only + + +Options are not position dependent and may be interspersed with file names. +POSIX options in the first column can be grouped together with the exception +of -h and -v which must be independent. Long options in the third column can +use a Multics style single hyphen prefix or the Gnu style double hyphen prefix +as displayed. -Options may be interspersed with file names if so desired. -They are not position dependent. ``` ### Brogue Save Game Backup -```text +```bash runeimp$ ls -hl total 112 -rw-r--r-- 1 runeimp staff 54K Apr 16 10:33 Saved game.broguesave -runeimp$ gzipdate -d * -Saving 21400 bytes from "Saved game.broguesave" to "Saved game.broguesave_2020-04-16_104846.gz" +runeimp$ gzipdate -dt * +Saving 21400 bytes from "Saved game.broguesave" to "Saved game.broguesave_2020-04-16_104846_PST.gz" Deleting source: "Saved game.broguesave" runeimp$ ls -hl total 48 --rw-r--r-- 1 runeimp staff 21K Apr 16 10:48 Saved game.broguesave_2020-04-16_104846.gz +-rw-r--r-- 1 runeimp staff 21K Apr 16 10:48 Saved game.broguesave_2020-04-16_104846_PST.gz runeimp$ gzipdate *.gz 54984 B written to "Saved game.broguesave" @@ -56,7 +69,7 @@ runeimp$ gzipdate *.gz runeimp$ ls -hl total 160 -rw-r--r-- 1 runeimp staff 54K Apr 16 10:33 Saved game.broguesave --rw-r--r-- 1 runeimp staff 21K Apr 16 10:48 Saved game.broguesave_2020-04-16_104846.gz +-rw-r--r-- 1 runeimp staff 21K Apr 16 10:48 Saved game.broguesave_2020-04-16_104846_PST.gz ``` Note that the size and date of "Saved game.broguesave" is the same in the original as in the version restored from the archive. @@ -76,5 +89,6 @@ Installation See the [installation docs](INSTALL.md) + [ISO 8601 - Wikipedia]: https://en.wikipedia.org/wiki/ISO_8601 diff --git a/go.mod b/go.mod index 53a5ad7..99f7dcc 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,5 @@ module github.com/runeimp/gzipdate go 1.14 + +require golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 // indirect diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..f9be939 --- /dev/null +++ b/go.sum @@ -0,0 +1,9 @@ +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w= +golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68 h1:nxC68pudNYkKU6jWhgrqdreuFiOQWj1Fs7T3VrH4Pjw= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/main.go b/main.go index 3601092..020c5cc 100644 --- a/main.go +++ b/main.go @@ -9,19 +9,25 @@ import ( "log" "os" "path" + "strings" "time" + + "golang.org/x/crypto/ssh/terminal" ) -/* - * CONSTANTS - */ +// +// CONSTANTS +// const ( - AppName = "GzipDate" - AppVersion = "1.0.0" - cliDeleteUsage = "Delete the source file after successful processing" - cliHelpUsage = "Display this help info" - cliVersionUsage = "Display this apps version number" - cliUsageHeader = `%s + AppName = "GzipDate" + AppVersion = "1.1.0" + cliUsageDelete = "Delete the source file after processing" + cliUsageDoubleHyphen = "Disable option parsing and consider all following arguments as file names only" + cliUsageFileDate = "Use the files modification time for the date instead of the current time" + cliUsageHelp = "Display this help info" + cliUsageTimeZone = "Turn the timezone feature on" + cliUsageVersion = "Display this apps version number" + cliUsageHeader = `%s USAGE: gzipdate [OPTIONS] [FILENAMES] @@ -29,38 +35,35 @@ OPTIONS: ` ) -/* - * DERIVED CONSTANTS - */ +// +// DERIVED CONSTANTS +// var ( AppLabel = fmt.Sprintf("%s v%s", AppName, AppVersion) ) -/* - * VARIABLES - */ +// +// VARIABLES +// var ( deleteSource = false files []string showHelp = false + termWidth int + timeFormat = "2006-01-02_150405" + useFileDate = false + useTimeZone = false ) +// +// MAIN ENTRY POINT +// func main() { + var err error - // Bespoke CLI Handler because flags is lame - for _, arg := range os.Args[1:] { - switch arg { - case "-d", "-del", "-delete", "--delete": - deleteSource = true - case "-h", "-help", "--help": - helpOutput() - os.Exit(0) - case "-v", "-ver", "-version", "--version": - fmt.Println(AppLabel) - os.Exit(0) - default: - files = append(files, arg) - } + termWidth, _, _ = terminal.GetSize(int(os.Stdin.Fd())) + if termWidth == 0 { + termWidth = 80 } if len(os.Args[1:]) == 0 { @@ -68,9 +71,18 @@ func main() { os.Exit(1) } - // fmt.Printf("Delete Source File? %t\n", deleteSource) + err = argParse(os.Args[1:]) + if err != nil { + fmt.Fprintf(os.Stderr, "%s\n", err.Error()) + os.Exit(1) + } - var err error + gzdEnv := strings.ToUpper(os.Getenv("GZIPDATE")) + if gzdEnv == "TIMEZONE" || gzdEnv == "TZ" { + useTimeZone = true + } + + // fmt.Printf("Delete Source File? %t\n", deleteSource) if len(files) > 0 { for _, filename := range files { @@ -99,6 +111,74 @@ func main() { } } +// +// FUNCTIONS +// +func argParse(args []string) error { + // Bespoke CLI Handler because flags is lame + parseArgs := true + for _, arg := range args { + if parseArgs { + switch arg { + case "--": + parseArgs = false + case "-d", "-del", "-delete", "--delete": + deleteSource = true + case "-f", "-file", "-file-date", "--file-date": + useFileDate = true + case "-h", "-help", "--help": + helpOutput() + os.Exit(0) + case "-t", "-tz", "-timezone", "--timezone": + useTimeZone = true + case "-v", "-ver", "-version", "--version": + fmt.Println(AppLabel) + os.Exit(0) + default: + if len(arg) > 0 { + if arg[0:1] == "-" { + // POSIX group processing + for _, c := range arg[1:] { + switch c { + case 'd': + deleteSource = true + case 'f': + useFileDate = true + case 't': + useTimeZone = true + case 'h', 'v': + return fmt.Errorf("invalid use of -%s in a POSIX group", string(c)) + // fmt.Fprintf(os.Stderr, "Invalid use of -%s in a POSIX group\n", string(c)) + // os.Exit(1) + default: + return fmt.Errorf("unknown option -%s", string(c)) + // fmt.Fprintf(os.Stderr, "Unknown POSIX group option: %q\n", c) + // fmt.Fprintf(os.Stderr, "Unknown option -%s\n", string(c)) + // os.Exit(1) + } + } + } else { + // Arg files + files = append(files, arg) + } + } + } + } else { + files = append(files, arg) + } + } + + return nil +} + +func datetimeFilename(filename string, t time.Time) string { + if useTimeZone { + timeFormat = "2006-01-02_150405_MST" + } + datetime := t.Format(timeFormat) + return fmt.Sprintf("%s_%s.gz", filename, datetime) +} + func gzipDecode(content []byte) error { newFilename := "filename.unknown" @@ -141,15 +221,12 @@ func gzipDecode(content []byte) error { return err } -func gzipEncode(filename string) error { +func fileContentAndModTime(filename string) ([]byte, time.Time) { var ( - destination *os.File - err error - file *os.File - fileinfo os.FileInfo - nBytes int64 + err error + file *os.File + fileinfo os.FileInfo ) - // content, err := ioutil.ReadFile(filename) file, err = os.Open(filename) if err != nil { log.Fatal(err) @@ -159,11 +236,42 @@ func gzipEncode(filename string) error { _, err = file.Read(content) if err != nil { log.Fatal(err) + os.Exit(2) } + return content, fileinfo.ModTime() +} + +func gzipEncode(filename string) error { + var ( + destination *os.File + err error + modTime time.Time + nBytes int64 + ) + // content, err := ioutil.ReadFile(filename) + // file, err = os.Open(filename) + // if err != nil { + // log.Fatal(err) + // } + // fileinfo, err = file.Stat() + // content := make([]byte, fileinfo.Size()) + // _, err = file.Read(content) + // if err != nil { + // log.Fatal(err) + // } + + content, modTime := fileContentAndModTime(filename) now := time.Now() - datetime := now.Format("2006-01-02_150405") - newFilename := fmt.Sprintf("%s_%s.gz", filename, datetime) + if useFileDate { + now = modTime + } + newFilename := datetimeFilename(filename, now) + // if useTimeZone { + // timeFormat = "2006-01-02_150405_MST" + // } + // datetime := now.Format(timeFormat) + // newFilename := fmt.Sprintf("%s_%s.gz", filename, datetime) // fmt.Printf("gzipEncode() | filename = %q | content length = %d B | newFilename = %q\n", filename, len(content), newFilename) var buf bytes.Buffer @@ -175,7 +283,7 @@ func gzipEncode(filename string) error { // Setting the Header fields is optional. zw.Name = filename zw.Comment = fmt.Sprintf("Compressed with %s", AppLabel) - zw.ModTime = fileinfo.ModTime() + zw.ModTime = modTime if _, err := zw.Write(content); err != nil { log.Fatal(err) @@ -197,11 +305,56 @@ func gzipEncode(filename string) error { return err } +func helpWrap(msg, prefix string) string { + if len([]rune(msg)) > termWidth { + words := strings.Split(msg, " ") + lines := []string{""} + i := 0 + for _, word := range words { + // fmt.Fprintf(os.Stderr, "helpWrap() | i: %d\n", i) + // fmt.Fprintf(os.Stderr, "helpWrap() | word: %q\n", word) + tmpMsg := lines[i] + word + " " + if len([]rune(tmpMsg)) < termWidth { + lines[i] = tmpMsg + } else { + last := len(lines[i]) - 1 + lines[i] = lines[i][:last] + i++ + word = fmt.Sprintf("%s%s ", prefix, word) + lines = append(lines, word) + } + } + last := len(lines[i]) - 1 + lines[i] = lines[i][:last] + // fmt.Fprintf(os.Stderr, "helpWrap() | len(lines): %d\n", len(lines)) + msg = strings.Join(lines, "\n") + } + msg += "\n" + + return msg +} + func helpOutput() { + // fmt.Fprintf(os.Stderr, "helpOutput() | termWidth: %d\n", termWidth) fmt.Printf(cliUsageHeader, AppLabel) - fmt.Printf(" -d | -del | -delete %s\n", cliDeleteUsage) - fmt.Printf(" -h | -help %s\n", cliHelpUsage) - fmt.Printf(" -v | -ver | -version %s\n", cliVersionUsage) + // fmt.Printf(" -d | -del | -delete %s\n", cliUsageDelete) + // fmt.Printf(" -f | -file | -file-date %s\n", cliUsageFileDate) + // fmt.Printf(" -h | -help | -help %s\n", cliUsageHelp) + // fmt.Printf(" -t | -tz | -timezone %s\n", cliUsageTimeZone) + // fmt.Printf(" -v | -ver | -version %s\n", cliUsageVersion) + prefix := " " + msg := helpWrap(fmt.Sprintf(" -d | -del | --delete %s", cliUsageDelete), prefix) + msg += helpWrap(fmt.Sprintf(" -f | -file | --file-date %s", cliUsageFileDate), prefix) + msg += helpWrap(fmt.Sprintf(" -h | -help | --help %s", cliUsageHelp), prefix) + msg += helpWrap(fmt.Sprintf(" -t | -tz | --timezone %s", cliUsageTimeZone), prefix) + msg += helpWrap(fmt.Sprintf(" -v | -ver | --version %s", cliUsageVersion), prefix) + msg += helpWrap(fmt.Sprintf(" -- %s", cliUsageDoubleHyphen), prefix) + fmt.Println(msg) fmt.Println() - fmt.Printf("Options may be interspersed with file names if so desired.\nThey are not position dependent.\n\n") + // fmt.Printf(`Options are not position dependent and may be interspersed with file names. POSIX options in the first column can be grouped together with the exception of -h and -v which must be independent. Long options in the third column can use a Multics style single hyphen prefix as displayed or the Gnu style double hyphen prefix. + + // `) + msg = "Options are not position dependent and may be interspersed with file names. POSIX options in the first column can be grouped together with the exception of -h and -v which must be independent. Long options in the third column can use a Multics style single hyphen prefix or the Gnu style double hyphen prefix as displayed." + prefix = "" + fmt.Printf("%s\n", helpWrap(msg, prefix)) } diff --git a/main_test.go b/main_test.go new file mode 100644 index 0000000..f5fc470 --- /dev/null +++ b/main_test.go @@ -0,0 +1,111 @@ +package main + +import "testing" + +func reset() { + deleteSource = false + files = []string{} + useFileDate = false + useTimeZone = false +} + +func TestPosixOptionGroup1(t *testing.T) { + reset() + + args := []string{"-dt", "test-file.txt"} + if deleteSource && useTimeZone { + t.Errorf("deleteSource and useTimeZone already set to true") + } else if deleteSource { + t.Errorf("deleteSource already set to true") + } else if useTimeZone { + t.Errorf("useTimeZone already set to true") + } + + argParse(args) + + if deleteSource == false && useTimeZone == false { + t.Errorf("deleteSource and useTimeZone were not set to true") + } else if deleteSource == false { + t.Errorf("deleteSource was not set to true") + } else if useTimeZone == false { + t.Errorf("useTimeZone was not set to true") + } + +} + +func TestPosixOptionGroup2(t *testing.T) { + reset() + + args := []string{"-td", "test-file.txt"} + argParse(args) + + if deleteSource == false && useTimeZone == false { + t.Errorf("deleteSource and useTimeZone were not set to true") + } else if deleteSource == false { + t.Errorf("deleteSource was not set to true") + } else if useTimeZone == false { + t.Errorf("useTimeZone was not set to true") + } +} + +func TestPosixOptionGroup3(t *testing.T) { + reset() + + args := []string{"-tx", "test-file.txt"} + expect := "unknown option -x" + err := argParse(args) + got := "" + if err != nil { + got = err.Error() + } + + if got != expect { + t.Errorf("expected %q but got %q", expect, got) + } +} + +func TestPosixOptionGroup4(t *testing.T) { + reset() + + args := []string{"-tv", "test-file.txt"} + expect := "invalid use of -v in a POSIX group" + err := argParse(args) + got := "" + if err != nil { + got = err.Error() + } + + if got != expect { + t.Errorf("expected %q but got %q", expect, got) + } +} + +func TestOptionParsing(t *testing.T) { + reset() + + args := []string{"-t", "test-file.txt", "--", "--version"} + expect := []string{"test-file.txt", "--version"} + argParse(args) + + for i, got := range files { + if i < len(expect) && got != expect[i] { + t.Errorf("expected [%d] %q but got %q", i, expect[i], got) + } + } +} + +func TestFilenameGeneration(t *testing.T) { + reset() + + filename := "test-file.txt" + + args := []string{"-ft", filename} + argParse(args) + expect := "test-file.txt_2021-04-13_133403_PDT.gz" + _, modTime := fileContentAndModTime(filename) + got := datetimeFilename(filename, modTime) + + if got != expect { + t.Errorf("expected %q but got %q", expect, got) + } +} From 7aa1d246e9a1c1a7106278bdb3e76b22a4996091 Mon Sep 17 00:00:00 2001 From: RuneImp Date: Tue, 13 Apr 2021 17:58:32 -0700 Subject: [PATCH 3/3] updated readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 2c0dd0b..0131661 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -GzipDate -======== +GzipDate v1.1.0 +=============== Simple command line app for the specific creation and handling of Gzip archives.