Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
ed828ab
chore: add permissions for write access in GitHub Actions workflow
tamada Jan 26, 2026
067c2b0
fix: reorder badge display in README for better visibility.
tamada Jan 26, 2026
c6fdc85
update version to 2.0.5, ready to publish v2.0.5
actions-user Jan 26, 2026
ad9b45e
add logo
tamada Feb 7, 2026
772aebb
publish www page in the new template
tamada Feb 8, 2026
3b1bdb0
add icon materials and hugo config
tamada Feb 9, 2026
81348c2
refactor: reorganize code structure and update dependencies for impro…
tamada Feb 11, 2026
61c4b3a
refactor: enhance directory handling and update CLI options for impro…
tamada Feb 12, 2026
40997eb
refactor: enhance CLI options and logging initialization for improved…
tamada Feb 12, 2026
c5cece2
refactor: improve argument validation in RawOpts parser for better er…
tamada Feb 12, 2026
2612c24
refactor: streamline error logging and simplify path handling in CLI …
tamada Feb 12, 2026
2158f22
refactor: improve code formatting and organization across multiple fi…
tamada Feb 12, 2026
07efe2a
refactor: simplify current directory handling in CliOpts initialization
tamada Feb 12, 2026
9db6d8f
refactor: improve directory change handling and error logging in path…
tamada Feb 12, 2026
e567d38
refactor: enhance error handling for current directory retrieval and …
tamada Feb 12, 2026
ab31e40
refactor: rename pathbuf_to_string to path_to_string for consistency …
tamada Feb 12, 2026
14652bd
refactor: update test assertions for path_to_string to reflect correc…
tamada Feb 12, 2026
8541b60
refactor: improve error handling in current directory initialization …
tamada Feb 12, 2026
537c8d0
refactor: add unit tests for error display in sibling operations
tamada Feb 12, 2026
6222914
Merge pull request #44 from tamada/reorganize_structure
tamada Feb 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions .bin/update_version.sh
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ fi

echo "$PREV_VERSION -> $VERSION (${PREV_VERSION//-/--} -> ${VERSION//-/--})"

sed -e "s#Version-v${PREV_VERSION//-/--}-information#Version-v${VERSION//-/--}-information#g" \
-e "s#tag/v${PREV_VERSION}#tag/v${VERSION}#g" \
-e "s#crates.io-v${PREV_VERSION}#crates.io-v${VERSION}#g" \
README.md > a; mv a README.md
for i in README.md docs/content/_index.md ; do
sed -e "s#Version-v${PREV_VERSION//-/--}-information#Version-v${VERSION//-/--}-information#g" \
-e "s#tag/v${PREV_VERSION}#tag/v${VERSION}#g" \
-e "s#crates.io-v${PREV_VERSION}#crates.io-v${VERSION}#g" \
$i > a; mv a $i
done
sed -e "s#version = \".*\"#version = \"${VERSION}\"#g" docs/config.toml > a ; mv a docs/config.toml
sed "s/^version = \".*\"/version = \"${VERSION}\"/g" Cargo.toml > a && mv a Cargo.toml

Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/publish.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ on:
- main
types: [closed]

permissions:
contents: write

jobs:
setup:
runs-on: ubuntu-latest
Expand Down
3 changes: 0 additions & 3 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
[submodule "themes/cayman-hugo-theme"]
path = themes/cayman-hugo-theme
url = https://github.com/zwbetz-gh/cayman-hugo-theme.git
[submodule "docs/themes/cayman-hugo-theme"]
path = docs/themes/cayman-hugo-theme
url = https://github.com/zwbetz-gh/cayman-hugo-theme.git
31 changes: 2 additions & 29 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ members = [ "lib", "cli" ]
resolver = "3"

[workspace.package]
version = "2.0.4"
version = "2.0.5"
repository = "https://github.com/tamada/sibling"
homepage = "https://tamada.github.io/sibling"
readme = "README.md"
Expand All @@ -13,31 +13,4 @@ authors = [
]
license-file = "LICENSE"
categories = ["command-line-utilities"]
edition = "2021"

# Config for 'cargo dist'
[workspace.metadata.dist]
# The preferred cargo-dist version to use in CI (Cargo.toml SemVer syntax)
cargo-dist-version = "0.19.1"
# CI backends to support
ci = "github"
# The installers to generate for each app
installers = ["shell", "powershell", "npm", "homebrew", "msi"]
# A GitHub repo to push Homebrew formulas to
tap = "tamada/homebrew-tap"
# Target platforms to build apps for (Rust target-triple syntax)
targets = ["aarch64-apple-darwin", "x86_64-apple-darwin", "x86_64-unknown-linux-gnu", "x86_64-pc-windows-msvc"]
# The archive format to use for windows builds (defaults .zip)
windows-archive = ".tar.gz"
# The archive format to use for non-windows builds (defaults .tar.xz)
unix-archive = ".tar.gz"
# A namespace to use when publishing this package to the npm registry
npm-scope = "@htamada"
# Path that installers should place binaries in
install-path = "CARGO_HOME"
# Publish jobs to run in CI
publish-jobs = ["homebrew"]
# Publish jobs to run in CI
pr-run-mode = "plan"
# Whether to install an updater program
install-updater = false
edition = "2024"
9 changes: 4 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
# sibling

[![crates.io](https://img.shields.io/badge/crates.io-v2.0.5-orange.svg?logo=rust)](https://crates.io/crates/sibling)
[![License](https://img.shields.io/badge/License-WTFPL-information.svg)](https://github.com/tamada/sibling/blob/master/LICENSE)
[![Version](https://img.shields.io/badge/Version-v2.0.5-information.svg)](https://github.com/tamada/sibling/releases/tag/v2.0.5)

[![build](https://github.com/tamada/sibling/actions/workflows/build.yaml/badge.svg)](https://github.com/tamada/sibling/actions/workflows/build.yaml)
[![Coverage Status](https://coveralls.io/repos/github/tamada/sibling/badge.svg?branch=main)](https://coveralls.io/github/tamada/sibling?branch=main)

[![Rust Report Card](https://rust-reportcard.xuri.me/badge/github.com/tamada/sibling)](https://rust-reportcard.xuri.me/report/github.com/tamada/sibling)

[![crates.io](https://img.shields.io/badge/crates.io-v2.0.4-orange.svg?logo=rust)](https://crates.io/crates/sibling)
[![License](https://img.shields.io/badge/License-WTFPL-information.svg)](https://github.com/tamada/sibling/blob/master/LICENSE)
[![Version](https://img.shields.io/badge/Version-v2.0.4-information.svg)](https://github.com/tamada/sibling/releases/tag/v2.0.4)

get the next/previous sibling directory name.

## :speaking_head: Description
Expand Down
47 changes: 23 additions & 24 deletions assets/init/init.bash
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
__change_directory_to_sibling() {
__change_directory_with_sibling() {
traversing_type="$1"
if [[ "$traversing_type" == "" ]]; then
traversing_type="next"
else
shift
fi
step=1
if [[ $# -eq 2 ]]; then
step=$2
fi
result=$(sibling --type $traversing_type --csv --step $step)
eval "$(sibling minisib $traversing_type $@ | {
read -r next; echo "next='$next';"
read -r length; echo "length='$length';"
read -r current; echo "current='$current';"
read -r last_flag; echo "last_flag='$last_flag';"
})"
sibling_status=$?
echo $result | while IFS=, read current next ci ni total
do
# echo "Current: $current, Next: $next, ci: $ci, ni: $ni, total: $total"
if [[ $sibling_status -eq 0 ]] ; then
# strip the first and last double quotes
cd "$(echo $next | sed -e 's/^"//' -e 's/"$//')"
echo "$PWD ($ci/$total)"
else
echo "Done ($ci/$total)"
cd ..
fi
done
# echo "Current: $current, Next: $next, ci: $ci, ni: $ni, total: $total"
if [[ $sibling_status -eq 0 ]] ; then
# strip the first and last double quotes
cd -- "$next"
echo "$PWD (${current}/${length})"
else
echo "Done (${current}/${length})"
cd ..
fi
return $sibling_status
}

Expand Down Expand Up @@ -84,22 +84,21 @@ sibling_fzf() {
}

cdfirst() {
__change_directory_to_sibling first
__change_directory_with_sibling first $@
}

cdlast() {
__change_directory_to_sibling last
__change_directory_with_sibling last $@
}

cdnext() {
__change_directory_to_sibling next $@
__change_directory_with_sibling next $@
}

cdprev() {
__change_directory_to_sibling previous $@
__change_directory_with_sibling previous $@
}

cdrand() {
__change_directory_to_sibling random
__change_directory_with_sibling random $@
}

107 changes: 93 additions & 14 deletions cli/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,67 @@ use std::path::PathBuf;

use clap::{Parser, ValueEnum};

use crate::LogLevel;
use crate::{LogLevel, minisib};

#[derive(Debug, Parser)]
#[clap(version, author, about, arg_required_else_help = true)]
pub struct CliOpts {
#[clap(flatten)]
pub(crate) p_opts: PrintingOpts,

#[clap(flatten)]
pub(crate) nexter_opts: NexterOpts,

#[clap(flatten)]
pub(crate) init_script: InitOpts,

#[clap(flatten)]
pub(crate) log_opts: LogOpts,

#[arg(
short,
long,
help = "specify the number of times to execute sibling",
value_name = "COUNT",
default_value_t = 1
short = 'w',
long = "working-dir",
help = "set the current working directory.",
hide = true,
value_name = "DIR",
long_help = "This option is applied before any other processing. Therefore, other options that specify paths should use the relative path from this option value. If this option is not specified, the current directory is used."
)]
pub step: usize,
pub(crate) cwd: Option<PathBuf>,

#[arg(index = 1, help = "the target directory", value_name = "DIR")]
pub dirs: Vec<PathBuf>,

#[cfg(debug_assertions)]
#[clap(flatten)]
pub(crate) compopts: CompletionOpts,

#[clap(subcommand)]
pub(crate) minisib: Option<minisib::MiniSibCommand>,
}

impl CliOpts {
pub fn init(&mut self) {
self.log_opts.init();
if let Some(cwd) = &self.cwd
&& let Err(e) = std::env::set_current_dir(cwd)
{
log::error!("Failed to set current directory to {cwd:?}: {e}, use \".\"");
}
if self.dirs.is_empty() {
match std::env::current_dir() {
Ok(cwd) => self.dirs.push(cwd),
Err(e) => {
log::error!("Failed to get current directory: {e}");
eprintln!("Error: failed to determine current working directory: {e}");
std::process::exit(1);
}
}
}
}
}

#[derive(Parser, Debug)]
pub(crate) struct LogOpts {
#[arg(
long,
help = "set the log level",
Expand All @@ -28,7 +72,29 @@ pub struct CliOpts {
ignore_case = true
)]
pub log: LogLevel,
}

impl LogOpts {
pub fn init(&self) {
use LogLevel::{Debug, Error, Info, Trace, Warn};
if std::env::var_os("RUST_LOG").is_none() {
unsafe {
match self.log {
Error => std::env::set_var("RUST_LOG", "error"),
Warn => std::env::set_var("RUST_LOG", "warn"),
Info => std::env::set_var("RUST_LOG", "info"),
Debug => std::env::set_var("RUST_LOG", "debug"),
Trace => std::env::set_var("RUST_LOG", "trace"),
};
}
}
env_logger::init();
log::info!("Log level set to {:?}", self.log);
}
}

#[derive(Parser, Debug)]
pub(crate) struct InitOpts {
#[arg(
long,
help = "generate the initialize script for the shell",
Expand All @@ -37,6 +103,18 @@ pub struct CliOpts {
default_missing_value = "bash"
)]
pub init: Option<String>,
}

#[derive(Parser, Debug)]
pub(crate) struct NexterOpts {
#[arg(
short,
long,
help = "specify the number of times to execute sibling",
value_name = "COUNT",
default_value_t = 1
)]
pub step: i32,

#[arg(short = 't', long = "type", help = "specify the nexter type", value_enum, default_value_t = sibling::NexterType::Next, value_name = "TYPE", ignore_case = true)]
pub nexter: sibling::NexterType,
Expand All @@ -49,12 +127,13 @@ pub struct CliOpts {
)]
pub input: Option<String>,

#[arg(index = 1, help = "the target directory", value_name = "DIR")]
pub dirs: Vec<PathBuf>,

#[cfg(debug_assertions)]
#[clap(flatten)]
pub(crate) compopts: CompletionOpts,
#[arg(
short = 'a',
long,
help = "Set the targets to all directories from the given list. By default, the sibling skips non-existent directories.",
default_value_t = false
)]
pub all: bool,
}

#[cfg(debug_assertions)]
Expand Down Expand Up @@ -96,7 +175,7 @@ pub(crate) struct PrintingOpts {
pub format: Format,

#[arg(
short,
short = 'A',
long,
help = "print the directory name in the absolute path",
default_value_t = false
Expand Down
16 changes: 14 additions & 2 deletions cli/src/gencomp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,21 @@ mod generator {
app.set_bin_name(appname);

generate_impl(Bash, &mut app, appname, outdir, format!("bash/{appname}"));
generate_impl(Elvish, &mut app, appname, outdir, format!("elvish/{appname}"));
generate_impl(
Elvish,
&mut app,
appname,
outdir,
format!("elvish/{appname}"),
);
generate_impl(Fish, &mut app, appname, outdir, format!("fish/{appname}"));
generate_impl(PowerShell, &mut app, appname, outdir, format!("powershell/{appname}"));
generate_impl(
PowerShell,
&mut app,
appname,
outdir,
format!("powershell/{appname}"),
);
generate_impl(Zsh, &mut app, appname, outdir, format!("zsh/_{appname}"));
}
}
Expand Down
15 changes: 15 additions & 0 deletions cli/src/init.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,18 @@ pub(crate) fn generate_init_script(shell_name: &str) -> Result<String> {
None => Err(Error::NotFound(script_file.into())),
}
}

#[cfg(test)]
mod tests {
#[test]
fn test_generate_init_script_with_bash() {
let script = super::generate_init_script("bash");
assert!(script.is_ok());
}

#[test]
fn test_generate_init_script_with_unsupported_shell() {
let script = super::generate_init_script("fish");
assert!(script.is_err());
}
}
Loading
Loading