Skip to content

Commit

Permalink
Merge pull request #10 from frederikstroem/release-v0.4.0
Browse files Browse the repository at this point in the history
v0.4.0
  • Loading branch information
frederikstroem committed Jan 26, 2024
2 parents e9b8d21 + a4cce33 commit b85891f
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 24 deletions.
16 changes: 14 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add merge CI/CD to verify Git tags, Cargo.toml version, CHANGELOG.md version and PKGBUILD version
- Add printing of pathing relative to home directory (if applicable)
- Add printing of pathing relative to root directory
- Include only files matching a regex
- Exclude files matching a regex
- Exclude files matching a glob pattern
- Add tests
- Add `cargo test` CI/CD
- Make async
Expand All @@ -29,6 +28,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add video/gif demo to README.md
- Improve code quality and structure
## [v0.4.0] - 2024-01-26
### Added
- Support for excluding files and directories matching specified glob patterns with the new `-e` or `--exclude` option.
- Clarification on the usage of glob patterns as part of the known issues in `README.md`.
### Fixed
- Prevention of repeated prints of the same file by incorporating a HashSet to track already processed files in the `FileWalker`.
### Changed
- Updated the `psource --help` output in `README.md` to reflect the new `-e` or `--exclude` option.
- Updated the Unreleased section in `CHANGELOG.md` to reflect the new `-e` or `--exclude` option.
## [v0.3.1] - 2024-01-16
### Fixed
Expand Down
3 changes: 2 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "psource"
version = "0.3.1"
version = "0.4.0"
authors = ["Frederik Holm Strøm <crates.io@frederikstroem.com>"]
description = "CLI tool to pretty print source code to stdout or directly to the clipboard."
edition = "2021"
Expand All @@ -20,3 +20,4 @@ walkdir = "2.4.0"
arboard = "3.3.0"
file-format = "0.23.0"
git2 = "0.18"
glob = "0.3.1"
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ Options:
-c, --copy Copy the source code to the clipboard
-a, --ancestry <ANCESTRY> Display the file's ancestry in the output path by including the specified number of parent directories relative to the current working directory, or 0 to omit the ancestry [default: 1]
-g, --git-ancestry Display the file's ancestry in the output path, including parent directories from the current working directory within a Git repository to its root, unlike the fixed number specified by the 'ancestry' option
-e, --exclude <EXCLUDE> Exclude files and directories matching the specified glob pattern
-h, --help Print help
-V, --version Print version
```
Expand Down Expand Up @@ -151,7 +152,13 @@ The LLM should be able to help you complete the task.

**Tip:** A file tree structure can sometimes help the LLM to better understand the context of the code. For such a task, I recommend using [eza](https://github.com/eza-community/eza) with the `--tree` option. To pipe it to the clipboard, a tool like [xsel](https://github.com/kfish/xsel) can be used, e.g., `eza --tree | xsel -b`.


## Known issues
### Speeding up the copy to clipboard process
Due to a bug in the software supply chain, the `-c` option requires psource to wait for some time before exiting, else the clipboard will not be updated on some systems (discovered on KDE Plasma running X11).[[1]](https://github.com/1Password/arboard/issues/114)[[2]](https://github.com/sigoden/aichat/issues/160) To speed up the process, the `psource` stdout can be piped to a clipboard tool like [xsel](https://github.com/kfish/xsel), e.g., `psource src | xsel -b`.

### Exclude option not working
The exclude option has some rough edges right now and future improvements are planned.

If the `*` exclude patterns are not working as excepted, try to quote the pattern, e.g., `psource Cargo.toml README.md -e 'Cargo*'`

If you need to exclude a file within a subdirectory, consider using a glob pattern such as `psource src -e '*/main.rs'` to target `main.rs` in any immediate subdirectory, or `psource src -e '**/main.rs'` to match all `main.rs` files across all levels of subdirectories.
10 changes: 3 additions & 7 deletions src/cli/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,9 @@ pub struct Cli {
#[arg(short, long = "git-ancestry", conflicts_with = "ancestry")]
pub git_ancestry: bool,

// /// Exclude files matching the given regex
// #[arg(short, long)]
// pub exclude: Option<String>,

// /// Include only files matching the given regex
// #[arg(short, long)]
// pub include: Option<String>,
/// Exclude files and directories matching the specified glob pattern
#[arg(short, long, action = clap::ArgAction::Append)]
pub exclude: Vec<String>,

/// Input files and directories
#[arg(required = true)]
Expand Down
58 changes: 46 additions & 12 deletions src/printer/file_walker.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,58 @@
use walkdir::WalkDir;
use std::path::{Path, PathBuf};
use file_format::{FileFormat, Kind};
use glob::Pattern;
use std::collections::HashSet;

pub struct FileWalker {}
pub struct FileWalker {
exclude_patterns: Vec<Pattern>,
}

impl FileWalker {
pub fn new() -> Self {
FileWalker {}
pub fn new(exclude_patterns: Vec<String>) -> Self {
let exclude_patterns = exclude_patterns
.into_iter()
.map(|p| Pattern::new(&p).expect("Failed to create glob pattern"))
.collect();
FileWalker { exclude_patterns }
}

pub fn walk(&self, input_paths: &[String]) -> anyhow::Result<Vec<PathBuf>> {
let mut paths = Vec::new();
for input_path in input_paths {
for entry in WalkDir::new(input_path) {
let entry = entry?;
if entry.file_type().is_file() {
// TODO: Add filtering logic (exclude/include) based on regex.
if !self.is_binary(&entry.path()) {
paths.push(entry.into_path());
let mut unique_paths = HashSet::new(); // To store unique paths
let mut final_paths = Vec::new(); // Final list of paths to return

for input_str in input_paths {
let input_path = Path::new(input_str);

// Skip if this path is excluded
if self.is_excluded(input_path) {
continue;
}

// Process directories and files differently
if input_path.is_dir() {
for entry in WalkDir::new(input_path) {
let entry = entry?;
let path = entry.path();

// Skip if the path is excluded or is a directory
if self.is_excluded(path) || entry.file_type().is_dir() {
continue;
}

// If the file is not binary and not already included, add it to the list
if !self.is_binary(path) && unique_paths.insert(path.to_path_buf()) {
final_paths.push(path.to_path_buf());
}
}
} else if input_path.is_file() {
// If it's a single file, add it if it's not binary and not already included
if !self.is_binary(input_path) && unique_paths.insert(input_path.to_path_buf()) {
final_paths.push(input_path.to_path_buf());
}
}
}
Ok(paths)
Ok(final_paths)
}

fn is_binary(&self, path: &Path) -> bool {
Expand All @@ -37,4 +67,8 @@ impl FileWalker {
true
}
}

fn is_excluded(&self, path: &Path) -> bool {
self.exclude_patterns.iter().any(|pattern| pattern.matches_path(path))
}
}
2 changes: 1 addition & 1 deletion src/printer/printer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ impl<'a> Printer<'a> {
Self {
cli,
config,
file_walker: FileWalker::new(),
file_walker: FileWalker::new(cli.exclude.clone()),
}
)
}
Expand Down

0 comments on commit b85891f

Please sign in to comment.