Compare commits

...

15 commits
v0.1.4 ... main

Author SHA1 Message Date
itchyny
cf6f0458b7 bump up version to 0.1.6 2023-04-26 19:00:01 +09:00
itchyny
e40bbff081 update CHANGELOG.md for v0.1.6 2023-04-26 18:54:19 +09:00
itchyny
7c8adbbb4c split EDITOR in Go to remove dependency on sh (ref #19) 2023-04-21 22:12:21 +09:00
itchyny
f627dff093 bump up version to 0.1.5 2023-04-09 12:49:00 +09:00
itchyny
834e2a759b update CHANGELOG.md for v0.1.5 2023-04-09 12:37:48 +09:00
itchyny
03ad35008b update copyright year in LICENSE 2023-04-09 12:37:48 +09:00
itchyny
97dd98cb16 update dependencies 2023-04-09 12:37:48 +09:00
itchyny
6a82806d14 migrate from deprecated create-release action 2023-04-09 12:37:48 +09:00
itchyny
467ba873c3 support EDITOR with spaces in the editor path (close #19, ref #10) 2023-04-09 12:37:37 +09:00
itchyny
fec2c9b389 improve Makefile 2023-04-09 12:27:02 +09:00
itchyny
e81d936dd5 switch from math/rand to crypto/rand package 2023-04-09 12:25:22 +09:00
itchyny
49d37b4903 add package comment and enable all checks of staticcheck 2023-04-09 12:23:33 +09:00
itchyny
8d31a98aa7 switch from deprecated io/ioutil to os package 2023-04-09 12:22:40 +09:00
itchyny
0d6dba4de7 update GitHub action dependencies 2023-04-09 12:20:54 +09:00
itchyny
d6ee613353 specify minimum permission for the default token in workflows 2023-04-09 12:19:53 +09:00
10 changed files with 68 additions and 70 deletions

View file

@ -6,6 +6,9 @@ on:
- main - main
pull_request: pull_request:
permissions:
contents: read
jobs: jobs:
test: test:
name: Test name: Test
@ -15,9 +18,9 @@ jobs:
os: [ubuntu-latest, macos-latest, windows-latest] os: [ubuntu-latest, macos-latest, windows-latest]
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: Setup Go - name: Setup Go
uses: actions/setup-go@v2 uses: actions/setup-go@v4
with: with:
go-version: 1.x go-version: 1.x
- name: Test - name: Test

View file

@ -5,28 +5,24 @@ on:
tags: tags:
- 'v*' - 'v*'
permissions:
contents: write
jobs: jobs:
release: release:
name: Release name: Release
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout code - name: Checkout code
uses: actions/checkout@v2 uses: actions/checkout@v3
- name: Setup Go - name: Setup Go
uses: actions/setup-go@v2 uses: actions/setup-go@v4
with: with:
go-version: 1.x go-version: 1.x
- name: Cross build - name: Cross build
run: make cross run: make cross
- name: Create Release - name: Create Release
id: create_release uses: ncipollo/release-action@v1
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with: with:
tag_name: ${{ github.ref }} name: Release ${{ github.ref_name }}
release_name: Release ${{ github.ref }} artifacts: 'goxz/*'
- name: Upload
run: make upload
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

View file

@ -1,4 +1,10 @@
# Changelog # Changelog
## [v0.1.6](https://github.com/itchyny/mmv/compare/v0.1.5..v0.1.6) (2023-04-26)
* Remove dependency on shell for splitting EDITOR with spaces.
## [v0.1.5](https://github.com/itchyny/mmv/compare/v0.1.4..v0.1.5) (2023-04-09)
* Support EDITOR with spaces in the editor path.
## [v0.1.4](https://github.com/itchyny/mmv/compare/v0.1.3..v0.1.4) (2021-09-18) ## [v0.1.4](https://github.com/itchyny/mmv/compare/v0.1.3..v0.1.4) (2021-09-18)
* Release `arm64` artifacts. * Release `arm64` artifacts.

View file

@ -1,6 +1,6 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2020-2021 itchyny Copyright (c) 2020-2023 itchyny
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

View file

@ -1,8 +1,8 @@
BIN := mmv BIN := mmv
VERSION := $$(make -s show-version) VERSION := $$(make -s show-version)
VERSION_PATH := cmd/$(BIN) VERSION_PATH := cmd/$(BIN)
CURRENT_REVISION := $(shell git rev-parse --short HEAD) CURRENT_REVISION = $(shell git rev-parse --short HEAD)
BUILD_LDFLAGS := "-s -w -X main.revision=$(CURRENT_REVISION)" BUILD_LDFLAGS = "-s -w -X main.revision=$(CURRENT_REVISION)"
GOBIN ?= $(shell go env GOPATH)/bin GOBIN ?= $(shell go env GOPATH)/bin
.PHONY: all .PHONY: all
@ -14,19 +14,18 @@ build:
.PHONY: install .PHONY: install
install: install:
go install -ldflags=$(BUILD_LDFLAGS) ./... go install -ldflags=$(BUILD_LDFLAGS) ./cmd/$(BIN)
.PHONY: show-version .PHONY: show-version
show-version: $(GOBIN)/gobump show-version: $(GOBIN)/gobump
@gobump show -r $(VERSION_PATH) @gobump show -r "$(VERSION_PATH)"
$(GOBIN)/gobump: $(GOBIN)/gobump:
@go install github.com/x-motemen/gobump/cmd/gobump@latest @go install github.com/x-motemen/gobump/cmd/gobump@latest
.PHONY: cross .PHONY: cross
cross: $(GOBIN)/goxz CREDITS cross: $(GOBIN)/goxz CREDITS
goxz -n $(BIN) -pv=v$(VERSION) -arch=amd64,arm64 \ goxz -n $(BIN) -pv=v$(VERSION) -build-ldflags=$(BUILD_LDFLAGS) ./cmd/$(BIN)
-build-ldflags=$(BUILD_LDFLAGS) ./cmd/$(BIN)
$(GOBIN)/goxz: $(GOBIN)/goxz:
go install github.com/Songmu/goxz/cmd/goxz@latest go install github.com/Songmu/goxz/cmd/goxz@latest
@ -45,7 +44,7 @@ test: build
.PHONY: lint .PHONY: lint
lint: $(GOBIN)/staticcheck lint: $(GOBIN)/staticcheck
go vet ./... go vet ./...
staticcheck ./... staticcheck -checks all ./...
$(GOBIN)/staticcheck: $(GOBIN)/staticcheck:
go install honnef.co/go/tools/cmd/staticcheck@latest go install honnef.co/go/tools/cmd/staticcheck@latest
@ -57,21 +56,9 @@ clean:
.PHONY: bump .PHONY: bump
bump: $(GOBIN)/gobump bump: $(GOBIN)/gobump
ifneq ($(shell git status --porcelain),) test -z "$$(git status --porcelain || echo .)"
$(error git workspace is dirty) test "$$(git branch --show-current)" = "main"
endif
ifneq ($(shell git rev-parse --abbrev-ref HEAD),main)
$(error current branch is not main)
endif
@gobump up -w "$(VERSION_PATH)" @gobump up -w "$(VERSION_PATH)"
git commit -am "bump up version to $(VERSION)" git commit -am "bump up version to $(VERSION)"
git tag "v$(VERSION)" git tag "v$(VERSION)"
git push origin main git push --atomic origin main tag "v$(VERSION)"
git push origin "refs/tags/v$(VERSION)"
.PHONY: upload
upload: $(GOBIN)/ghr
ghr "v$(VERSION)" goxz
$(GOBIN)/ghr:
go install github.com/tcnksm/ghr@latest

View file

@ -4,14 +4,12 @@ import (
"errors" "errors"
"flag" "flag"
"fmt" "fmt"
"io/ioutil"
"math/rand"
"os" "os"
"os/exec" "os/exec"
"runtime" "runtime"
"strings" "strings"
"time"
"github.com/kballard/go-shellquote"
_ "github.com/mattn/getwild" _ "github.com/mattn/getwild"
"github.com/mattn/go-tty" "github.com/mattn/go-tty"
@ -20,14 +18,10 @@ import (
const name = "mmv" const name = "mmv"
const version = "0.1.4" const version = "0.1.6"
var revision = "HEAD" var revision = "HEAD"
func init() {
rand.Seed(time.Now().UnixNano())
}
func main() { func main() {
os.Exit(run(os.Args[1:])) os.Exit(run(os.Args[1:]))
} }
@ -86,7 +80,7 @@ func rename(args []string) error {
xs[src] = true xs[src] = true
} }
f, err := ioutil.TempFile("", name+"-") f, err := os.CreateTemp("", name+"-")
if err != nil { if err != nil {
return err return err
} }
@ -109,7 +103,10 @@ func rename(args []string) error {
if editor == "" { if editor == "" {
editor = "vi" editor = "vi"
} }
editorWithArgs := strings.Fields(editor) editorWithArgs, err := shellquote.Split(editor)
if err != nil {
return fmt.Errorf("%s: %s", err, editor)
}
editorWithArgs = append(editorWithArgs, f.Name()) editorWithArgs = append(editorWithArgs, f.Name())
cmd := exec.Command(editorWithArgs[0], editorWithArgs[1:]...) cmd := exec.Command(editorWithArgs[0], editorWithArgs[1:]...)
@ -120,7 +117,7 @@ func rename(args []string) error {
return fmt.Errorf("abort renames: %s", err) return fmt.Errorf("abort renames: %s", err)
} }
cnt, err := ioutil.ReadFile(f.Name()) cnt, err := os.ReadFile(f.Name())
if err != nil { if err != nil {
return err return err
} }

12
go.mod
View file

@ -1,10 +1,14 @@
module github.com/itchyny/mmv module github.com/itchyny/mmv
go 1.16 go 1.20
require ( require (
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
github.com/mattn/getwild v0.0.2-0.20200919000855-c2e221927ad6 github.com/mattn/getwild v0.0.2-0.20200919000855-c2e221927ad6
github.com/mattn/go-isatty v0.0.14 // indirect github.com/mattn/go-tty v0.0.4
github.com/mattn/go-tty v0.0.3 )
golang.org/x/sys v0.0.0-20210917161153-d61c044b1678 // indirect
require (
github.com/mattn/go-isatty v0.0.18 // indirect
golang.org/x/sys v0.7.0 // indirect
) )

19
go.sum
View file

@ -1,17 +1,18 @@
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 h1:Z9n2FFNUXsshfwJMBgNA0RU6/i7WVaAegv3PtuIHPMs=
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8=
github.com/mattn/getwild v0.0.2-0.20200919000855-c2e221927ad6 h1:uWR+2CTTaHQzDS/DApbJ2H8UEPQl90atrKtczXj2xcs= github.com/mattn/getwild v0.0.2-0.20200919000855-c2e221927ad6 h1:uWR+2CTTaHQzDS/DApbJ2H8UEPQl90atrKtczXj2xcs=
github.com/mattn/getwild v0.0.2-0.20200919000855-c2e221927ad6/go.mod h1:AG+GKQydHp7iLJn+VV+D7y8LeYs5bQ0Xz4fmKd5o1Sg= github.com/mattn/getwild v0.0.2-0.20200919000855-c2e221927ad6/go.mod h1:AG+GKQydHp7iLJn+VV+D7y8LeYs5bQ0Xz4fmKd5o1Sg=
github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84=
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98=
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.6/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/mattn/go-runewidth v0.0.7/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
github.com/mattn/go-tty v0.0.3 h1:5OfyWorkyO7xP52Mq7tB36ajHDG5OHrmBGIS/DtakQI= github.com/mattn/go-tty v0.0.4 h1:NVikla9X8MN0SQAqCYzpGyXv0jY7MNl3HOWD2dkle7E=
github.com/mattn/go-tty v0.0.3/go.mod h1:ihxohKRERHTVzN+aSVRwACLCeqIoZAWpoICkkvrWyR0= github.com/mattn/go-tty v0.0.4/go.mod h1:u5GGXBtZU6RQoKV8gY5W6UhMudbR5vXnUe7j3pxse28=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210917161153-d61c044b1678 h1:J27LZFQBFoihqXoegpscI10HpjZ7B5WQLLKL2FZXQKw= golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
golang.org/x/sys v0.0.0-20210917161153-d61c044b1678/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=

11
mmv.go
View file

@ -1,10 +1,11 @@
// Package mmv provides a method to rename multiple files.
package mmv package mmv
import ( import (
"math/rand" "crypto/rand"
"encoding/base64"
"os" "os"
"path/filepath" "path/filepath"
"strconv"
"strings" "strings"
) )
@ -250,8 +251,12 @@ func buildRenames(files map[string]string) ([]rename, error) {
// create a temporary path where there is no file currently // create a temporary path where there is no file currently
func temporaryPath(dir string) (string, error) { func temporaryPath(dir string) (string, error) {
bs := make([]byte, 16)
for i := 0; i < 256; i++ { for i := 0; i < 256; i++ {
path := filepath.Join(dir, strconv.FormatUint(rand.Uint64()|1<<60, 16)) if _, err := rand.Read(bs); err != nil {
return "", err
}
path := filepath.Join(dir, base64.RawURLEncoding.EncodeToString(bs))
if _, err := os.Stat(path); err != nil && os.IsNotExist(err) { if _, err := os.Stat(path); err != nil && os.IsNotExist(err) {
return path, nil return path, nil
} }

View file

@ -1,7 +1,6 @@
package mmv package mmv
import ( import (
"io/ioutil"
"os" "os"
"path/filepath" "path/filepath"
"reflect" "reflect"
@ -385,9 +384,9 @@ func TestRename(t *testing.T) {
} }
for _, tc := range testCases { for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) { t.Run(tc.name, func(t *testing.T) {
dir, err := ioutil.TempDir("", "mmv-") dir, err := os.MkdirTemp("", "mmv-")
if err != nil { if err != nil {
t.Fatalf("ioutil.TempDir returned an error: %s", err) t.Fatalf("os.MkdirTemp returned an error: %s", err)
} }
t.Cleanup(func() { os.RemoveAll(dir) }) t.Cleanup(func() { os.RemoveAll(dir) })
if err := os.Chdir(dir); err != nil { if err := os.Chdir(dir); err != nil {
@ -423,7 +422,7 @@ func setupFiles(contents map[string]string) error {
return err return err
} }
} }
if err := ioutil.WriteFile(f, []byte(cnt), 0o600); err != nil { if err := os.WriteFile(f, []byte(cnt), 0o600); err != nil {
return err return err
} }
} }
@ -432,7 +431,7 @@ func setupFiles(contents map[string]string) error {
func fileContents(dir string) map[string]string { func fileContents(dir string) map[string]string {
m := make(map[string]string) m := make(map[string]string)
fis, _ := ioutil.ReadDir(dir) fis, _ := os.ReadDir(dir)
for _, fi := range fis { for _, fi := range fis {
if fi.IsDir() { if fi.IsDir() {
for k, v := range fileContents(filepath.Join(dir, fi.Name())) { for k, v := range fileContents(filepath.Join(dir, fi.Name())) {
@ -440,7 +439,7 @@ func fileContents(dir string) map[string]string {
} }
} else { } else {
path := filepath.Join(dir, fi.Name()) path := filepath.Join(dir, fi.Name())
cnt, _ := ioutil.ReadFile(path) cnt, _ := os.ReadFile(path)
m[filepath.ToSlash(path)] = string(cnt) m[filepath.ToSlash(path)] = string(cnt)
} }
} }