😀
ゴルーチンを使ってwindows用のtouchコマンドを作ってみた
概要
windowsでtouchが使えないので、以下の機能を持つtouchコマンド作ってみた。
- 複数ファイルを一度に作る (例) touch file1 file2 file3
- 既存ファイルは上書きしない
mainコード
main.go
package main
import (
"errors"
"flag"
"os"
"sync"
)
func main() {
flag.Parse()
execute(flag.Args())
}
func execute(fileNames []string) {
wg := sync.WaitGroup{}
for _, name := range fileNames {
wg.Add(1)
go touch(name, &wg)
}
wg.Wait()
}
func touch(fileName string, wg *sync.WaitGroup) {
defer wg.Done()
if fileExists(fileName) {
return
}
createFile(fileName)
}
func fileExists(name string) bool {
if _, err := os.Stat(name); err != nil {
return false
}
return true
}
func createFile(fileName string) error {
if file, err := os.Create(fileName); err == nil {
file.Close()
return nil
}
return errors.New("")
}
testコード
main_test.go
package main
import (
"os"
"sync"
"testing"
)
func TestFileExists(t *testing.T) {
const fileName = "file"
if exist := fileExists(fileName); exist != false {
t.Fatalf("it should return false because %s doesn't exist", fileName)
}
// setup for test
file, err := os.Create(fileName)
if err != nil {
t.Fatalf("test setup failed")
}
defer os.Remove(fileName)
defer file.Close()
if exist := fileExists(fileName); exist != true {
t.Fatalf("it should return true because %s exists", fileName)
}
}
func TestCreateFile(t *testing.T) {
const fileName = "file"
err := createFile(fileName)
defer os.Remove(fileName)
if _, e := os.Stat(fileName); e != nil {
t.Fatalf("it should create %s", fileName)
}
if err != nil {
t.Fatalf("it should return nil becuase file is created now")
}
}
func TestTouch(t *testing.T) {
const fileName = "file"
wg := sync.WaitGroup{}
wg.Add(1)
go touch(fileName, &wg)
defer os.Remove(fileName)
wg.Wait()
if !fileExists(fileName) {
t.Fatalf("it should create %s", fileName)
}
wg.Add(1)
go touch(fileName, &wg)
wg.Wait()
if !fileExists(fileName) {
t.Fatalf("it should remain %s", fileName)
}
}
func TestExecute(t *testing.T) {
fileNames := []string{"file1", "file2", "file3"}
execute(fileNames)
defer func() {
for _, name := range fileNames {
os.Remove(name)
}
}()
for _, name := range fileNames {
if exist := fileExists(name); exist != true {
t.Fatalf("it should create %s", name)
}
}
}
Discussion