Compare commits
9 Commits
Author | SHA1 | Date | |
---|---|---|---|
f14c0cd9c2 | |||
63d4e6e1d2 | |||
be6d3e5a44 | |||
ae4b46bf57 | |||
3f3980de38 | |||
6fd5bd5863 | |||
0a13671df2 | |||
28d84e4dc2 | |||
60c15894c0 |
28
.github/workflows/build.yml
vendored
28
.github/workflows/build.yml
vendored
@ -17,17 +17,23 @@ on:
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ${{ matrix.os }}
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ windows-latest, ubuntu-latest, macos-latest ]
|
||||
include:
|
||||
- os: ubuntu-latest
|
||||
- target: "linux/amd64"
|
||||
GOOS: "linux"
|
||||
GOARCH: "amd64"
|
||||
BIN_SUFFIX: ""
|
||||
- os: macos-latest
|
||||
BIN_SUFFIX: ""
|
||||
- os: windows-latest
|
||||
- target: "windows/amd64"
|
||||
GOOS: "windows"
|
||||
GOARCH: "amd64"
|
||||
BIN_SUFFIX: ".exe"
|
||||
- target: "darwin/amd64"
|
||||
GOOS: "darwin"
|
||||
GOARCH: "amd64"
|
||||
BIN_SUFFIX: ""
|
||||
|
||||
steps:
|
||||
- name: Checkout codebase
|
||||
uses: actions/checkout@v2
|
||||
@ -37,7 +43,7 @@ jobs:
|
||||
- name: Set up Go 1.x
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: ^1.16
|
||||
go-version: ^1.17
|
||||
|
||||
- name: Setup vars
|
||||
id: vars
|
||||
@ -47,11 +53,13 @@ jobs:
|
||||
|
||||
- name: Build
|
||||
env:
|
||||
GOOS: ${{ matrix.GOOS }}
|
||||
GOARCH: ${{ matrix.GOARCH }}
|
||||
CGO_ENABLED: 0
|
||||
run: go build -trimpath -ldflags="-w -s -X main.AppVersion=${{ steps.vars.outputs.git_tag }}" -v -o um-${{ runner.os }}${{ matrix.BIN_SUFFIX }} ./cmd/um
|
||||
run: go build -v -trimpath -ldflags="-w -s -X main.AppVersion=${{ steps.vars.outputs.git_tag }}" -o um-${{ matrix.GOOS }}-${{ matrix.GOARCH }}${{ matrix.BIN_SUFFIX }} ./cmd/um
|
||||
|
||||
- name: Publish artifact
|
||||
uses: actions/upload-artifact@v2
|
||||
with:
|
||||
name: um-${{ runner.os }}${{ matrix.BIN_SUFFIX }}
|
||||
path: ./um-${{ runner.os }}${{ matrix.BIN_SUFFIX }}
|
||||
name: um-${{ matrix.GOOS }}-${{ matrix.GOARCH }}
|
||||
path: ./um-${{ matrix.GOOS }}-${{ matrix.GOARCH }}${{ matrix.BIN_SUFFIX }}
|
||||
|
84
.github/workflows/release.yml
vendored
Normal file
84
.github/workflows/release.yml
vendored
Normal file
@ -0,0 +1,84 @@
|
||||
name: Create Release
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "v*"
|
||||
|
||||
jobs:
|
||||
create_release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Get current time
|
||||
id: date
|
||||
run: echo "::set-output name=date::$(date +'%Y/%m/%d')"
|
||||
|
||||
- name: Create release
|
||||
id: release
|
||||
uses: actions/create-release@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
tag_name: ${{ github.ref }}
|
||||
release_name: "Build ${{ steps.date.outputs.date }}"
|
||||
draft: true
|
||||
outputs:
|
||||
upload_url: "${{ steps.release.outputs.upload_url }}"
|
||||
build:
|
||||
needs:
|
||||
- create_release
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- target: "linux/amd64"
|
||||
GOOS: "linux"
|
||||
GOARCH: "amd64"
|
||||
BIN_SUFFIX: ""
|
||||
- target: "windows/amd64"
|
||||
GOOS: "windows"
|
||||
GOARCH: "amd64"
|
||||
BIN_SUFFIX: ".exe"
|
||||
- target: "windows/386"
|
||||
GOOS: "windows"
|
||||
GOARCH: "386"
|
||||
BIN_SUFFIX: ".exe"
|
||||
- target: "darwin/amd64"
|
||||
GOOS: "darwin"
|
||||
GOARCH: "amd64"
|
||||
BIN_SUFFIX: ""
|
||||
|
||||
steps:
|
||||
- name: Checkout codebase
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup vars
|
||||
id: vars
|
||||
run: |
|
||||
echo "::set-output name=short_sha::$(git rev-parse --short HEAD)"
|
||||
echo "::set-output name=git_tag::$(git describe --tags --always)"
|
||||
|
||||
- name: Set up Go 1.x
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: ^1.17
|
||||
|
||||
- name: Build
|
||||
env:
|
||||
GOOS: ${{ matrix.GOOS }}
|
||||
GOARCH: ${{ matrix.GOARCH }}
|
||||
CGO_ENABLED: 0
|
||||
run: go build -trimpath -v -ldflags="-w -s -X main.AppVersion=${{ steps.vars.outputs.git_tag }}" -o um ./cmd/um
|
||||
|
||||
- name: Upload release assets
|
||||
uses: actions/upload-release-asset@v1
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
with:
|
||||
upload_url: ${{ needs.create_release.outputs.upload_url }}
|
||||
asset_path: um
|
||||
asset_name: um-${{ matrix.GOOS }}-${{ matrix.GOARCH }}${{ matrix.BIN_SUFFIX }}
|
||||
asset_content_type: application/octet-stream
|
||||
|
@ -13,7 +13,7 @@ Original: Web Edition https://github.com/ix64/unlock-music
|
||||
|
||||
## Hou to Build
|
||||
|
||||
- Requirements: **Golang 1.16**
|
||||
- Requirements: **Golang 1.17**
|
||||
|
||||
1. Clone this repo `git clone https://github.com/unlock-music/cli && cd cli`
|
||||
2. Build the executable `go build ./cmd/um`
|
||||
|
@ -1,12 +1,30 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type NewDecoderFunc func([]byte) Decoder
|
||||
|
||||
var decoderRegistry = make(map[string][]NewDecoderFunc)
|
||||
type decoderItem struct {
|
||||
noop bool
|
||||
decoder NewDecoderFunc
|
||||
}
|
||||
|
||||
func RegisterDecoder(ext string, dispatchFunc NewDecoderFunc) {
|
||||
decoderRegistry[ext] = append(decoderRegistry[ext], dispatchFunc)
|
||||
var decoderRegistry = make(map[string][]decoderItem)
|
||||
|
||||
func RegisterDecoder(ext string, noop bool, dispatchFunc NewDecoderFunc) {
|
||||
decoderRegistry[ext] = append(decoderRegistry[ext],
|
||||
decoderItem{noop: noop, decoder: dispatchFunc})
|
||||
}
|
||||
func GetDecoder(ext string) []NewDecoderFunc {
|
||||
return decoderRegistry[ext]
|
||||
func GetDecoder(filename string, skipNoop bool) (rs []NewDecoderFunc) {
|
||||
ext := strings.ToLower(strings.TrimLeft(filepath.Ext(filename), "."))
|
||||
for _, dec := range decoderRegistry[ext] {
|
||||
if skipNoop && dec.noop {
|
||||
continue
|
||||
}
|
||||
rs = append(rs, dec.decoder)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
@ -1,6 +1,9 @@
|
||||
package common
|
||||
|
||||
import "errors"
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type RawDecoder struct {
|
||||
file []byte
|
||||
@ -14,7 +17,7 @@ func NewRawDecoder(file []byte) Decoder {
|
||||
func (d *RawDecoder) Validate() error {
|
||||
for ext, sniffer := range snifferRegistry {
|
||||
if sniffer(d.file) {
|
||||
d.audioExt = ext
|
||||
d.audioExt = strings.ToLower(ext)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@ -42,11 +45,11 @@ func (d RawDecoder) GetMeta() Meta {
|
||||
}
|
||||
|
||||
func init() {
|
||||
RegisterDecoder("mp3", NewRawDecoder)
|
||||
RegisterDecoder("flac", NewRawDecoder)
|
||||
RegisterDecoder("ogg", NewRawDecoder)
|
||||
RegisterDecoder("m4a", NewRawDecoder)
|
||||
RegisterDecoder("wav", NewRawDecoder)
|
||||
RegisterDecoder("wma", NewRawDecoder)
|
||||
RegisterDecoder("aac", NewRawDecoder)
|
||||
RegisterDecoder("mp3", true, NewRawDecoder)
|
||||
RegisterDecoder("flac", true, NewRawDecoder)
|
||||
RegisterDecoder("ogg", true, NewRawDecoder)
|
||||
RegisterDecoder("m4a", true, NewRawDecoder)
|
||||
RegisterDecoder("wav", true, NewRawDecoder)
|
||||
RegisterDecoder("wma", true, NewRawDecoder)
|
||||
RegisterDecoder("aac", true, NewRawDecoder)
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ var snifferRegistry = map[string]Sniffer{
|
||||
".wav": SnifferWAV,
|
||||
".wma": SnifferWMA,
|
||||
".aac": SnifferAAC,
|
||||
".dff": SnifferDFF,
|
||||
}
|
||||
|
||||
func SniffAll(header []byte) (string, bool) {
|
||||
@ -46,3 +47,9 @@ func SnifferWMA(header []byte) bool {
|
||||
func SnifferAAC(header []byte) bool {
|
||||
return bytes.HasPrefix(header, []byte{0xFF, 0xF1})
|
||||
}
|
||||
|
||||
// SnifferDFF sniff a DSDIFF format
|
||||
// reference to: https://www.sonicstudio.com/pdf/dsd/DSDIFF_1.5_Spec.pdf
|
||||
func SnifferDFF(header []byte) bool {
|
||||
return bytes.HasPrefix(header, []byte("FRM8"))
|
||||
}
|
||||
|
@ -75,12 +75,8 @@ func (d *Decoder) Decode() error {
|
||||
d.audio = make([]byte, lenData)
|
||||
|
||||
for i := 0; i < lenData; i++ {
|
||||
med8 := d.key[i%17] ^ dataEncrypted[i]
|
||||
med8 ^= (med8 & 0xf) << 4
|
||||
|
||||
msk8 := maskV2PreDef[i%272] ^ maskV2[i>>4]
|
||||
msk8 ^= (msk8 & 0xf) << 4
|
||||
d.audio[i] = med8 ^ msk8
|
||||
med8 := dataEncrypted[i] ^ d.key[i%17] ^ maskV2PreDef[i%(16*17)] ^ maskV2[i>>4]
|
||||
d.audio[i] = med8 ^ (med8&0xf)<<4
|
||||
}
|
||||
if d.isVpr {
|
||||
for i := 0; i < lenData; i++ {
|
||||
@ -91,8 +87,8 @@ func (d *Decoder) Decode() error {
|
||||
}
|
||||
func init() {
|
||||
// Kugou
|
||||
common.RegisterDecoder("kgm", NewDecoder)
|
||||
common.RegisterDecoder("kgma", NewDecoder)
|
||||
common.RegisterDecoder("kgm", false, NewDecoder)
|
||||
common.RegisterDecoder("kgma", false, NewDecoder)
|
||||
// Viper
|
||||
common.RegisterDecoder("vpr", NewDecoder)
|
||||
common.RegisterDecoder("vpr", false, NewDecoder)
|
||||
}
|
||||
|
@ -6,7 +6,7 @@ import (
|
||||
"github.com/ulikunitz/xz"
|
||||
"github.com/unlock-music/cli/internal/logging"
|
||||
"go.uber.org/zap"
|
||||
"io/ioutil"
|
||||
"io"
|
||||
)
|
||||
|
||||
var maskDiffVpr = []byte{
|
||||
@ -50,7 +50,7 @@ func initMask() {
|
||||
if err != nil {
|
||||
logging.Log().Fatal("load kgm mask failed", zap.Error(err))
|
||||
}
|
||||
maskV2, err = ioutil.ReadAll(maskReader)
|
||||
maskV2, err = io.ReadAll(maskReader)
|
||||
if err != nil {
|
||||
logging.Log().Fatal("load kgm mask failed", zap.Error(err))
|
||||
}
|
||||
|
@ -124,6 +124,6 @@ func padOrTruncate(raw string, length int) string {
|
||||
|
||||
func init() {
|
||||
// Kuwo Mp3/Flac
|
||||
common.RegisterDecoder("kwm", NewDecoder)
|
||||
common.RegisterDecoder("kwm", common.NewRawDecoder)
|
||||
common.RegisterDecoder("kwm", false, NewDecoder)
|
||||
common.RegisterDecoder("kwm", false, common.NewRawDecoder)
|
||||
}
|
||||
|
@ -246,5 +246,5 @@ func (d Decoder) GetMeta() common.Meta {
|
||||
|
||||
func init() {
|
||||
// Netease Mp3/Flac
|
||||
common.RegisterDecoder("ncm", NewDecoder)
|
||||
common.RegisterDecoder("ncm", false, NewDecoder)
|
||||
}
|
||||
|
@ -39,7 +39,7 @@ func NewKey256FromMask44(mask44 []byte) (*Key256Mask, error) {
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func (q *Key256Mask) getMatrix44() (mask44 []byte, err error) {
|
||||
func (q *Key256Mask) GetMatrix44() ([]byte, error) {
|
||||
if len(q.matrix) != 128 {
|
||||
return nil, ErrMaskLength128
|
||||
}
|
||||
@ -53,7 +53,7 @@ func (q *Key256Mask) getMatrix44() (mask44 []byte, err error) {
|
||||
return nil, ErrMaskDecode
|
||||
}
|
||||
}
|
||||
q.matrix[idx44] = q.matrix[it256[0]]
|
||||
matrix44[idx44] = q.matrix[it256[0]]
|
||||
idx44++
|
||||
}
|
||||
}
|
||||
|
@ -102,27 +102,27 @@ func DecoderFuncWithExt(ext string) common.NewDecoderFunc {
|
||||
|
||||
//goland:noinspection SpellCheckingInspection
|
||||
func init() {
|
||||
common.RegisterDecoder("qmc0", DecoderFuncWithExt("mp3")) //QQ Music Mp3
|
||||
common.RegisterDecoder("qmc3", DecoderFuncWithExt("mp3")) //QQ Music Mp3
|
||||
common.RegisterDecoder("qmc0", false, DecoderFuncWithExt("mp3")) //QQ Music Mp3
|
||||
common.RegisterDecoder("qmc3", false, DecoderFuncWithExt("mp3")) //QQ Music Mp3
|
||||
|
||||
common.RegisterDecoder("qmc2", DecoderFuncWithExt("m4a")) //QQ Music M4A
|
||||
common.RegisterDecoder("qmc4", DecoderFuncWithExt("m4a")) //QQ Music M4A
|
||||
common.RegisterDecoder("qmc6", DecoderFuncWithExt("m4a")) //QQ Music M4A
|
||||
common.RegisterDecoder("qmc8", DecoderFuncWithExt("m4a")) //QQ Music M4A
|
||||
common.RegisterDecoder("qmc2", false, DecoderFuncWithExt("m4a")) //QQ Music M4A
|
||||
common.RegisterDecoder("qmc4", false, DecoderFuncWithExt("m4a")) //QQ Music M4A
|
||||
common.RegisterDecoder("qmc6", false, DecoderFuncWithExt("m4a")) //QQ Music M4A
|
||||
common.RegisterDecoder("qmc8", false, DecoderFuncWithExt("m4a")) //QQ Music M4A
|
||||
|
||||
common.RegisterDecoder("qmcflac", DecoderFuncWithExt("flac")) //QQ Music Flac
|
||||
common.RegisterDecoder("qmcogg", DecoderFuncWithExt("ogg")) //QQ Music Ogg
|
||||
common.RegisterDecoder("tkm", DecoderFuncWithExt("m4a")) //QQ Music Accompaniment M4a
|
||||
common.RegisterDecoder("qmcflac", false, DecoderFuncWithExt("flac")) //QQ Music Flac
|
||||
common.RegisterDecoder("qmcogg", false, DecoderFuncWithExt("ogg")) //QQ Music Ogg
|
||||
common.RegisterDecoder("tkm", false, DecoderFuncWithExt("m4a")) //QQ Music Accompaniment M4a
|
||||
|
||||
common.RegisterDecoder("bkcmp3", DecoderFuncWithExt("mp3")) //Moo Music Mp3
|
||||
common.RegisterDecoder("bkcflac", DecoderFuncWithExt("flac")) //Moo Music Flac
|
||||
common.RegisterDecoder("bkcmp3", false, DecoderFuncWithExt("mp3")) //Moo Music Mp3
|
||||
common.RegisterDecoder("bkcflac", false, DecoderFuncWithExt("flac")) //Moo Music Flac
|
||||
|
||||
common.RegisterDecoder("666c6163", DecoderFuncWithExt("flac")) //QQ Music Weiyun Flac
|
||||
common.RegisterDecoder("6d7033", DecoderFuncWithExt("mp3")) //QQ Music Weiyun Mp3
|
||||
common.RegisterDecoder("6f6767", DecoderFuncWithExt("ogg")) //QQ Music Weiyun Ogg
|
||||
common.RegisterDecoder("6d3461", DecoderFuncWithExt("m4a")) //QQ Music Weiyun M4a
|
||||
common.RegisterDecoder("776176", DecoderFuncWithExt("wav")) //QQ Music Weiyun Wav
|
||||
common.RegisterDecoder("666c6163", false, DecoderFuncWithExt("flac")) //QQ Music Weiyun Flac
|
||||
common.RegisterDecoder("6d7033", false, DecoderFuncWithExt("mp3")) //QQ Music Weiyun Mp3
|
||||
common.RegisterDecoder("6f6767", false, DecoderFuncWithExt("ogg")) //QQ Music Weiyun Ogg
|
||||
common.RegisterDecoder("6d3461", false, DecoderFuncWithExt("m4a")) //QQ Music Weiyun M4a
|
||||
common.RegisterDecoder("776176", false, DecoderFuncWithExt("wav")) //QQ Music Weiyun Wav
|
||||
|
||||
common.RegisterDecoder("mgg", NewMgg256Decoder) //QQ Music New Ogg
|
||||
common.RegisterDecoder("mflac", NewMflac256Decoder) //QQ Music New Flac
|
||||
common.RegisterDecoder("mgg", false, NewMgg256Decoder) //QQ Music New Ogg
|
||||
common.RegisterDecoder("mflac", false, NewMflac256Decoder) //QQ Music New Flac
|
||||
}
|
||||
|
@ -70,10 +70,10 @@ func DecoderFuncWithExt(ext string) common.NewDecoderFunc {
|
||||
|
||||
func init() {
|
||||
// QQ Music IOS M4a
|
||||
common.RegisterDecoder("tm2", DecoderFuncWithExt("m4a"))
|
||||
common.RegisterDecoder("tm6", DecoderFuncWithExt("m4a"))
|
||||
common.RegisterDecoder("tm2", false, DecoderFuncWithExt("m4a"))
|
||||
common.RegisterDecoder("tm6", false, DecoderFuncWithExt("m4a"))
|
||||
// QQ Music IOS Mp3
|
||||
common.RegisterDecoder("tm0", common.NewRawDecoder)
|
||||
common.RegisterDecoder("tm3", common.NewRawDecoder)
|
||||
common.RegisterDecoder("tm0", false, common.NewRawDecoder)
|
||||
common.RegisterDecoder("tm3", false, common.NewRawDecoder)
|
||||
|
||||
}
|
||||
|
@ -97,10 +97,10 @@ func DecoderFuncWithExt(ext string) common.NewDecoderFunc {
|
||||
|
||||
func init() {
|
||||
// Xiami Wav/M4a/Mp3/Flac
|
||||
common.RegisterDecoder("xm", NewDecoder)
|
||||
common.RegisterDecoder("xm", false, NewDecoder)
|
||||
// Xiami Typed Format
|
||||
common.RegisterDecoder("wav", DecoderFuncWithExt("wav"))
|
||||
common.RegisterDecoder("mp3", DecoderFuncWithExt("mp3"))
|
||||
common.RegisterDecoder("flac", DecoderFuncWithExt("flac"))
|
||||
common.RegisterDecoder("m4a", DecoderFuncWithExt("m4a"))
|
||||
common.RegisterDecoder("wav", false, DecoderFuncWithExt("wav"))
|
||||
common.RegisterDecoder("mp3", false, DecoderFuncWithExt("mp3"))
|
||||
common.RegisterDecoder("flac", false, DecoderFuncWithExt("flac"))
|
||||
common.RegisterDecoder("m4a", false, DecoderFuncWithExt("m4a"))
|
||||
}
|
||||
|
@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/unlock-music/cli/algo/common"
|
||||
_ "github.com/unlock-music/cli/algo/kgm"
|
||||
_ "github.com/unlock-music/cli/algo/kwm"
|
||||
@ -14,26 +15,28 @@ import (
|
||||
"go.uber.org/zap"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var AppVersion = "0.0.4"
|
||||
var AppVersion = "v0.0.6"
|
||||
|
||||
func main() {
|
||||
app := cli.App{
|
||||
Name: "Unlock Music CLI",
|
||||
HelpName: "um",
|
||||
Usage: "Unlock your encrypted music file https://github.com/unlock-music/cli",
|
||||
Version: AppVersion,
|
||||
Version: fmt.Sprintf("%s (%s,%s/%s)", AppVersion, runtime.Version(), runtime.GOOS, runtime.GOARCH),
|
||||
Flags: []cli.Flag{
|
||||
&cli.StringFlag{Name: "input", Aliases: []string{"i"}, Usage: "path to input file or dir", Required: false},
|
||||
&cli.StringFlag{Name: "output", Aliases: []string{"o"}, Usage: "path to output dir", Required: false},
|
||||
&cli.BoolFlag{Name: "skip-noop", Aliases: []string{"n"}, Usage: "skip noop decoder", Required: false, Value: true},
|
||||
},
|
||||
|
||||
Action: appMain,
|
||||
Copyright: "Copyright (c) 2020 - 2021 Unlock Music https://github.com/unlock-music/cli/blob/master/LICENSE",
|
||||
HideHelpCommand: true,
|
||||
UsageText: "um [-o /path/to/output/dir] [-i] /path/to/input",
|
||||
UsageText: "um [-o /path/to/output/dir] [--extra-flags] [-i] /path/to/input",
|
||||
}
|
||||
err := app.Run(os.Args)
|
||||
if err != nil {
|
||||
@ -41,10 +44,20 @@ func main() {
|
||||
}
|
||||
}
|
||||
|
||||
func appMain(c *cli.Context) error {
|
||||
func appMain(c *cli.Context) (err error) {
|
||||
input := c.String("input")
|
||||
if input == "" && c.Args().Present() {
|
||||
input = c.Args().Get(c.Args().Len() - 1)
|
||||
if input == "" {
|
||||
switch c.Args().Len() {
|
||||
case 0:
|
||||
input, err = os.Getwd()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case 1:
|
||||
input = c.Args().Get(0)
|
||||
default:
|
||||
return errors.New("please specify input file (or directory)")
|
||||
}
|
||||
}
|
||||
|
||||
output := c.String("output")
|
||||
@ -54,7 +67,12 @@ func appMain(c *cli.Context) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if input == output {
|
||||
return errors.New("input and output path are same")
|
||||
}
|
||||
}
|
||||
|
||||
skipNoop := c.Bool("skip-noop")
|
||||
|
||||
inputStat, err := os.Stat(input)
|
||||
if err != nil {
|
||||
@ -74,10 +92,9 @@ func appMain(c *cli.Context) error {
|
||||
}
|
||||
|
||||
if inputStat.IsDir() {
|
||||
return dealDirectory(input, output)
|
||||
return dealDirectory(input, output, skipNoop)
|
||||
} else {
|
||||
ext := strings.TrimLeft(filepath.Ext(inputStat.Name()), ".")
|
||||
allDec := common.GetDecoder(ext)
|
||||
allDec := common.GetDecoder(inputStat.Name(), skipNoop)
|
||||
if len(allDec) == 0 {
|
||||
logging.Log().Fatal("skipping while no suitable decoder")
|
||||
}
|
||||
@ -85,7 +102,7 @@ func appMain(c *cli.Context) error {
|
||||
}
|
||||
|
||||
}
|
||||
func dealDirectory(inputDir string, outputDir string) error {
|
||||
func dealDirectory(inputDir string, outputDir string, skipNoop bool) error {
|
||||
items, err := os.ReadDir(inputDir)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -94,8 +111,7 @@ func dealDirectory(inputDir string, outputDir string) error {
|
||||
if item.IsDir() {
|
||||
continue
|
||||
}
|
||||
ext := strings.TrimLeft(filepath.Ext(item.Name()), ".")
|
||||
allDec := common.GetDecoder(ext)
|
||||
allDec := common.GetDecoder(item.Name(), skipNoop)
|
||||
if len(allDec) == 0 {
|
||||
logging.Log().Info("skipping while no suitable decoder", zap.String("file", item.Name()))
|
||||
continue
|
||||
|
15
go.mod
15
go.mod
@ -1,12 +1,17 @@
|
||||
module github.com/unlock-music/cli
|
||||
|
||||
go 1.16
|
||||
go 1.17
|
||||
|
||||
require (
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
|
||||
github.com/russross/blackfriday/v2 v2.1.0 // indirect
|
||||
github.com/ulikunitz/xz v0.5.10
|
||||
github.com/urfave/cli/v2 v2.3.0
|
||||
go.uber.org/multierr v1.6.0 // indirect
|
||||
go.uber.org/zap v1.16.0
|
||||
go.uber.org/zap v1.19.1
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d // indirect
|
||||
github.com/russross/blackfriday/v2 v2.0.1 // indirect
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
|
||||
go.uber.org/atomic v1.7.0 // indirect
|
||||
go.uber.org/multierr v1.6.0 // indirect
|
||||
)
|
||||
|
58
go.sum
58
go.sum
@ -1,13 +1,11 @@
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0 h1:EoUDS0afbrsXAZ9YQ9jdu/mZ2sXgT1/2yyNng4PGlyM=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
@ -15,51 +13,57 @@ github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/ulikunitz/xz v0.5.10 h1:t92gobL9l3HE202wg3rlk19F6X+JOxl9BBrCCMYEYd8=
|
||||
github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=
|
||||
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||
go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU=
|
||||
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723 h1:sHOAIxRGBp443oHZIPB+HsUGaksVCXVQENPxwTfQdH4=
|
||||
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
||||
go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9Ejo0C68/HhF8uaILCdgjnY+goOA=
|
||||
go.uber.org/zap v1.16.0 h1:uFRZXykJGK9lLY4HtgSw44DnIcAM+kRBP7x5m+NpAOM=
|
||||
go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ=
|
||||
go.uber.org/zap v1.19.1 h1:ue41HOKd1vGURxrmeKIgELGb3jPW9DMUDGtsinblHwI=
|
||||
go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de h1:5hukYrvBGR8/eNkX5mdUezrA6JiaEZDtJb9Ei+1LlBs=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
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=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5 h1:hKsoRgsbwY1NafxrwTs+k64bikrLBkAgPir1TNCj3Zs=
|
||||
golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3 h1:fvjTMHxHEw/mxHbtzPi3JCcKXQRAnQTBRo6YCJSVHKI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXeM=
|
||||
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
|
||||
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
Reference in New Issue
Block a user