Skip to content

Commit 6fd3b3a

Browse files
committed
Improve duplicate check
Added shell completion
1 parent d5c5dca commit 6fd3b3a

File tree

10 files changed

+908
-111
lines changed

10 files changed

+908
-111
lines changed
+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
_duplicate-checker() {
2+
local i cur prev opts cmd
3+
COMPREPLY=()
4+
cur="${COMP_WORDS[COMP_CWORD]}"
5+
prev="${COMP_WORDS[COMP_CWORD-1]}"
6+
cmd=""
7+
opts=""
8+
9+
for i in ${COMP_WORDS[@]}
10+
do
11+
case "${cmd},${i}" in
12+
",$1")
13+
cmd="duplicate__checker"
14+
;;
15+
*)
16+
;;
17+
esac
18+
done
19+
20+
case "${cmd}" in
21+
duplicate__checker)
22+
opts="-r -h -V --root-folder --help --version"
23+
if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
24+
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
25+
return 0
26+
fi
27+
case "${prev}" in
28+
--root-folder)
29+
COMPREPLY=($(compgen -f "${cur}"))
30+
return 0
31+
;;
32+
-r)
33+
COMPREPLY=($(compgen -f "${cur}"))
34+
return 0
35+
;;
36+
*)
37+
COMPREPLY=()
38+
;;
39+
esac
40+
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
41+
return 0
42+
;;
43+
esac
44+
}
45+
46+
if [[ "${BASH_VERSINFO[0]}" -eq 4 && "${BASH_VERSINFO[1]}" -ge 4 || "${BASH_VERSINFO[0]}" -gt 4 ]]; then
47+
complete -F _duplicate-checker -o nosort -o bashdefault -o default duplicate-checker
48+
else
49+
complete -F _duplicate-checker -o bashdefault -o default duplicate-checker
50+
fi

.github/workflows/ci.yml

+154
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
name: Build and Release
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
tags:
8+
- "v*"
9+
10+
jobs:
11+
build:
12+
name: Build and Release Rust Binary
13+
runs-on: ${{ matrix.os }}
14+
15+
permissions:
16+
contents: write
17+
packages: write
18+
19+
strategy:
20+
matrix:
21+
os: [ubuntu-latest, macos-latest]
22+
include:
23+
- os: macos-latest
24+
target_x86: x86_64-apple-darwin
25+
target_arm: aarch64-apple-darwin
26+
- os: ubuntu-latest
27+
target: x86_64-unknown-linux-gnu
28+
29+
steps:
30+
- name: Checkout code
31+
uses: actions/checkout@v3
32+
with:
33+
fetch-depth: 5
34+
35+
- name: Install Rust
36+
uses: actions-rs/toolchain@v1
37+
with:
38+
toolchain: stable
39+
target: ${{ matrix.target || matrix.target_x86 }}
40+
41+
- name: Add macOS universal binary targets
42+
if: matrix.os == 'macos-latest'
43+
run: |
44+
rustup target add x86_64-apple-darwin aarch64-apple-darwin
45+
46+
- name: Add Linux and Windows targets
47+
if: matrix.os != 'macos-latest'
48+
run: rustup target add ${{ matrix.target }}
49+
50+
- name: Build with Cargo
51+
run: |
52+
if [[ "${{ matrix.os }}" == "macos-latest" ]]; then
53+
cargo build --release --target ${{ matrix.target_x86 }}
54+
cargo build --release --target ${{ matrix.target_arm }}
55+
lipo -create -output ./target/release/universal_binary \
56+
./target/${{ matrix.target_x86 }}/release/duplicate-checker \
57+
./target/${{ matrix.target_arm }}/release/duplicate-checker
58+
else
59+
cargo build --release --target ${{ matrix.target }}
60+
fi
61+
shell: bash
62+
63+
- name: Set prerelease flag
64+
id: prerelease_check
65+
run: |
66+
if [[ "${GITHUB_REF#refs/tags/}" == *"alpha"* || "${GITHUB_REF#refs/tags/}" == *"beta"* ]]; then
67+
echo "prerelease=true" >> $GITHUB_ENV
68+
else
69+
echo "prerelease=false" >> $GITHUB_ENV
70+
fi
71+
72+
- name: Check if release exists
73+
id: check_release
74+
run: |
75+
if gh release view "${GITHUB_REF_NAME}" &>/dev/null; then
76+
echo "release_exists=true" >> $GITHUB_ENV
77+
else
78+
echo "release_exists=false" >> $GITHUB_ENV
79+
fi
80+
env:
81+
GITHUB_TOKEN: ${{ secrets.PAT_TOKEN }}
82+
83+
- name: Create a GitHub Release
84+
if: env.release_exists == 'false'
85+
id: create_release
86+
uses: actions/create-release@v1
87+
with:
88+
tag_name: ${{ github.ref_name }}
89+
release_name: Release ${{ github.ref_name }}
90+
body: |
91+
This release includes the latest Rust binary for version ${{ github.ref_name }}.
92+
draft: false
93+
prerelease: ${{ env.prerelease }}
94+
env:
95+
GITHUB_TOKEN: ${{ secrets.PAT_TOKEN }}
96+
97+
- name: Set upload URL for existing or new release
98+
run: |
99+
if [[ "${{ env.release_exists }}" == "true" ]]; then
100+
UPLOAD_URL=$(gh api repos/${{ github.repository }}/releases/tags/${GITHUB_REF_NAME} --jq ".upload_url" | sed '')
101+
else
102+
UPLOAD_URL="${{ steps.create_release.outputs.upload_url }}"
103+
fi
104+
echo "upload_url=$UPLOAD_URL" >> $GITHUB_ENV
105+
env:
106+
GITHUB_TOKEN: ${{ secrets.PAT_TOKEN }}
107+
108+
- name: Check if macOS binary exists
109+
if: matrix.os == 'macos-latest'
110+
run: ls -la ./target/release/universal_binary
111+
112+
- name: Upload macOS Universal Binary Release Asset
113+
if: matrix.os == 'macos-latest'
114+
uses: actions/upload-release-asset@v1
115+
with:
116+
upload_url: ${{ env.upload_url }}
117+
asset_path: ./target/release/universal_binary
118+
asset_name: duplicate-checker-macos
119+
asset_content_type: application/octet-stream
120+
env:
121+
GITHUB_TOKEN: ${{ secrets.PAT_TOKEN }}
122+
123+
- name: Upload Linux Release Asset
124+
if: matrix.os == 'ubuntu-latest'
125+
uses: actions/upload-release-asset@v1
126+
with:
127+
upload_url: ${{ env.upload_url }}
128+
asset_path: ./target/${{ matrix.target }}/release/duplicate-checker
129+
asset_name: duplicate-checker-linux
130+
asset_content_type: application/octet-stream
131+
env:
132+
GITHUB_TOKEN: ${{ secrets.PAT_TOKEN }}
133+
134+
- name: Calculate SHA256 for macOS release asset
135+
if: matrix.os == 'macos-latest'
136+
id: calculate_sha
137+
run: |
138+
SHA256=$(shasum -a 256 ./target/release/universal_binary | awk '{print $1}')
139+
echo "sha256=$SHA256" >> $GITHUB_ENV
140+
141+
- name: Trigger Homebrew Formula Update via cURL
142+
if: matrix.os == 'macos-latest'
143+
run: |
144+
URL="https://github.com/${{ github.repository }}/releases/download/${{ github.ref_name }}/duplicate-checker-macos"
145+
JSON_PAYLOAD=$(jq -n --arg url "$URL" '{"event_type": "update-duplicate-checker-formula", "client_payload": {"tag": "${{ github.ref_name }}", "download_url": $url, "sha": "${{ env.sha256 }}"}}')
146+
echo "Payload: $JSON_PAYLOAD"
147+
curl -L \
148+
-X POST \
149+
-H "Accept: application/vnd.github+json" \
150+
-H "Authorization: Bearer ${{ secrets.PAT_TOKEN }}" \
151+
-H "X-GitHub-Api-Version: 2022-11-28" \
152+
https://api.github.com/repos/keaz/homebrew-homebrew/dispatches \
153+
-d "$JSON_PAYLOAD"
154+

.zfunc/_duplicate-checker

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#compdef duplicate-checker
2+
3+
autoload -U is-at-least
4+
5+
_duplicate-checker() {
6+
typeset -A opt_args
7+
typeset -a _arguments_options
8+
local ret=1
9+
10+
if is-at-least 5.2; then
11+
_arguments_options=(-s -S -C)
12+
else
13+
_arguments_options=(-s -C)
14+
fi
15+
16+
local context curcontext="$curcontext" state line
17+
_arguments "${_arguments_options[@]}" : \
18+
'-r+[Root folder to search duplicate]:ROOT_FOLDER:_default' \
19+
'--root-folder=[Root folder to search duplicate]:ROOT_FOLDER:_default' \
20+
'-h[Print help]' \
21+
'--help[Print help]' \
22+
'-V[Print version]' \
23+
'--version[Print version]' \
24+
&& ret=0
25+
}
26+
27+
(( $+functions[_duplicate-checker_commands] )) ||
28+
_duplicate-checker_commands() {
29+
local commands; commands=()
30+
_describe -t commands 'duplicate-checker commands' commands "$@"
31+
}
32+
33+
if [ "$funcstack[1]" = "_duplicate-checker" ]; then
34+
_duplicate-checker "$@"
35+
else
36+
compdef _duplicate-checker duplicate-checker
37+
fi

Cargo.lock

+18-8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

+6
Original file line numberDiff line numberDiff line change
@@ -26,3 +26,9 @@ tokio = { version = "1.39.2", features = [
2626
"fs",
2727
] }
2828
tabled = "0.16.0"
29+
clap_complete = "4.5.38"
30+
31+
32+
[build-dependencies]
33+
clap = { version = "4.5.21", features = ["derive"] }
34+
clap_complete = "4.5.38"

build.rs

+57
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
use std::{
2+
fs::{self, File},
3+
io,
4+
path::Path,
5+
};
6+
7+
use clap::{CommandFactory, Parser, ValueEnum};
8+
9+
fn main() {
10+
generate_completion().unwrap();
11+
}
12+
13+
/// CLI application that search duplicate files in a folder
14+
#[derive(Parser, Debug)]
15+
#[command(author, version, about, long_about = None)]
16+
pub struct CmdArgs {
17+
/// Root folder to search duplicate
18+
#[arg(short, long)]
19+
pub root_folder: String,
20+
}
21+
22+
#[derive(ValueEnum, Debug, Clone)]
23+
pub enum Shell {
24+
Bash,
25+
Zsh,
26+
}
27+
28+
pub fn generate_completion() -> Result<(), io::Error> {
29+
let mut cmd = CmdArgs::command();
30+
31+
// Create the directory if it doesn't exist
32+
let bash_dir = ".bash_completion.d";
33+
let zsh_dir = ".zfunc";
34+
if !Path::new(bash_dir).exists() {
35+
fs::create_dir_all(bash_dir)?;
36+
}
37+
if !Path::new(zsh_dir).exists() {
38+
fs::create_dir_all(zsh_dir)?;
39+
}
40+
41+
let mut bash_file = File::create(format!("{}/duplicate-checker.bash", bash_dir))?;
42+
let mut zsh_file = File::create(format!("{}/_duplicate-checker", zsh_dir))?;
43+
44+
clap_complete::generate(
45+
clap_complete::shells::Bash,
46+
&mut cmd,
47+
"duplicate-checker",
48+
&mut bash_file,
49+
);
50+
clap_complete::generate(
51+
clap_complete::shells::Zsh,
52+
&mut cmd,
53+
"duplicate-checker",
54+
&mut zsh_file,
55+
);
56+
Ok(())
57+
}

0 commit comments

Comments
 (0)