# Throw away pastebin

Just a place to throw away some text.

## `.gitignore`

```txt
# macOS
.DS_Store

# Window
*.exe

# IntelliJ
.idea

# VSCode
.vscode

# Go
coverage.out
vendor

# GoReleaser
dist
```

## GitHub Actions

`dependabot.yml`:

```yaml
version: 2
updates:
  - package-ecosystem: "gomod"
    directory: "/"
    schedule:
      interval: "daily"
  - package-ecosystem: "github-actions"
    directory: "/"
    schedule:
      interval: "daily"
```

`go.yml`:

```yaml
name: Go

on:
  push:
    branches:
      - main
    paths:
      - "**.go"
      - "go.mod"
      - "go.sum"
  pull_request:
    branches:
      - main
    paths:
      - "**.go"
      - "go.mod"
      - "go.sum"

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}
  cancel-in-progress: true

jobs:
  test:
    name: Test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-go@v4
        with:
          go-version: "stable"
      - run: go test -race -failfast ./...
  build:
    name: Build
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest, windows-latest]
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-go@v4
        with:
          go-version: "stable"
      - run: go build .
  golangci-lint:
    name: golangci-lint
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0
      - uses: actions/setup-go@v4
        with:
          go-version: "stable"
      - uses: golangci/golangci-lint-action@v3
        with:
          version: latest
```

## Go

`.golangci.yml`:

```yaml
run:
  timeout: 5m
  tests: false

output:
  sort-results: true

linters:
  disable-all: true
  enable:
    # Default
    - errcheck
    - gosimple
    - govet
    - ineffassign
    - staticcheck
    - typecheck
    - unused
    # Custom
    - err113
    - errchkjson
    - errname
    - errorlint
    - forcetypeassert
    - gocritic
    - gofumpt
    - gosec
    - importas
    - makezero
    - nilnil
    - noctx
    - prealloc
    - reassign
    - sqlclosecheck
    - unconvert
  fast: true

linters-settings:
  # Default
  govet:
    check-shadowing: false
    disable-all: true
    enable:
      - assign
      - atomic
      - bools
      - buildtag
      - composites
      - copylocks
      - fieldalignment
      - httpresponse
      - loopclosure
      - lostcancel
      - nilfunc
      - printf
      - unmarshal
      - unreachable
      - unusedresult
  staticcheck:
    checks: ["all", "-SA1019"]
  # Custom
  gocritic:
    disabled-checks:
      - ifElseChain
      - singleCaseSwitch
      - unnamedResult
      - whyNoLint
    enabled-tags:
      - diagnostic
      - style
  gosec:
    excludes:
      - G101
      - G112
      - G115
      - G204
      - G402
      - G404
      - G501
      - G505
    exclude-generated: true
  reassign:
    patterns:
      - ".*"

issues:
  exclude-dirs:
    - ".*test.*"
    - ".*mock.*"
    - ".*example.*"
    - ".*utils.*"
  exclude-files:
    - ".*Mock.*"
    - ".*_mock.*"
```

`.goreleaser.yml`:

```yaml
before:
  hooks:
    - go mod tidy
builds:
  - main: .
    goos:
      - linux
      - windows
      - darwin
    goarch:
      - amd64
      - arm64
universal_binaries:
  - replace: true
archives:
  - format_overrides:
      - goos: windows
        format: zip
changelog:
  skip: false
  use: github
```

## Git clean up

```sh
# Delete untracked
git clean -fdx

git gc
```

## Delete `.DS_Store`

With [find](https://stackoverflow.com/q/30483670):

```sh
find . -name ".DS_Store" -print -type f -delete
```

With [fd](https://github.com/sharkdp/fd):

```sh
fd -H '^\.DS_Store$' -tf -X rm
```

## [sd](https://github.com/chmln/sd)

Remove proto options:

```sh
sd -F 'import "validate/validate.proto";' '' api/raw/*.proto
sd -F 'import "marshal-zap.proto";' '' api/raw/*.proto
sd -f s '\s\[.*?];' ';' api/raw/*.proto
```

## [fdupes](https://github.com/adrianlopezroche/fdupes)

Remove duplicated files:

```sh
fdupes -rdN .
```

## [rsync](https://github.com/WayneD/rsync)

```sh
# Result is dst/src
rsync -avzP src dst

# Result is dst/* with * is from src
rsync -avzP src/ dst
```

Commonly flags:

- `-v`: verbose
- `-z`: compress
- `-P`: enable both `--partial`, `--progress` to easily resume after interrupt
- `-n`: dry run

Be careful flags (need dry run if not sure):

- `-u`: skip if files in **dst** is already newer than in **src**, if you want
  to sync both ways
- `--delete`: delete files in **dst** if not exist in **src**, useful to sync
  dst with src

## [ffmpeg](https://github.com/FFmpeg/FFmpeg)

```sh
# -crf: quality, 0 is lossless, more is lower quality
# -an: no audio 
# -c:a aac -b:a 128k: audio codec and bitrate
ffmpeg -i input -c:v libx265 -crf 26 -preset fast -an output.mp4
```

Links:

- [H.265/HEVC Video Encoding Guide](https://trac.ffmpeg.org/wiki/Encode/H.265)

## [libvips](https://github.com/libvips/libvips)

Convert:

```sh
# Add --vips-progress to show progress
vips jxlsave filename.jpg filename.jxl --keep=none
vips jpegsave filename.png filename.jpg --keep=none

# Batch convert (require fd)
fd "jpg|jpeg|png|webp|gif" --exec vips jxlsave {} {.}.jxl --keep=none
fd "jpg|jpeg|png|webp|gif" --exec-batch rm

fd "png|webp|gif" --exec vips jpegsave {} {.}.jpg --keep=none
fd "png|webp|gif" --exec-batch rm

# Rotate
vips rot filename.jxl new_filename.jxl d90
```

## [yt-dlp](https://github.com/yt-dlp/yt-dlp)

Download:

```sh
yt-dlp -f - "https://www.youtube.com/watch?v=video_id"
```

## [F2](https://github.com/ayoisaiah/f2)

Rename:

```sh
# If dry run, remove --exec
f2 --replace "{mtime.YYYY}{mtime.MM}{mtime.DD}_{mtime.H}{mtime.mm}{mtime.ss}_{hash.md5}{ext}" --exec

# Include ImageSize (require exiftool)
f2 --replace "{mtime.YYYY}{mtime.MM}{mtime.DD}_{mtime.H}{mtime.mm}{mtime.ss}_{xt.ImageSize}_{hash.md5}{ext}" --exec

# Not include time
f2 --exclude="\d+x\d+_[a-z\d]{32}" --sort=mtime --replace "{xt.ImageSize}_{hash.md5}{ext}" --exec

# Remove space in directory
f2 --find " " --replace "_" --string-mode --only-dir --exec
```