Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

support include directive #32 #43

Merged
merged 34 commits into from
Aug 7, 2023
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
16bd51e
make extract_command_from_makefile private
kyu08 Jul 27, 2023
7f53d7e
fix bat command
kyu08 Jul 27, 2023
32b3e6f
原因判明
kyu08 Jul 27, 2023
a2c30b2
read Makefile and *.mk
kyu08 Jul 29, 2023
2e69608
passed concat_file_contents_test
kyu08 Jul 29, 2023
22aba19
refactor
kyu08 Jul 30, 2023
82fc764
rename misc -> handler
kyu08 Jul 30, 2023
0aae95c
to TDD
kyu08 Jul 30, 2023
8c50bb8
impl and UT of specify_makefile_name
kyu08 Jul 30, 2023
8586ad7
add line_to_including_files impl and UT
kyu08 Jul 31, 2023
9957f73
add UT for extract_including_file_names
kyu08 Aug 1, 2023
077a961
1階層includeまでは対応
kyu08 Aug 4, 2023
32e539b
add uuid license
kyu08 Aug 4, 2023
f7f868a
handler.rsから各moduleに処理を移動
kyu08 Aug 4, 2023
492320f
struct makefile
kyu08 Aug 4, 2023
798e446
mod fuzzy_finder
kyu08 Aug 6, 2023
179f3d9
refactor
kyu08 Aug 6, 2023
8ba330f
add testfiles
kyu08 Aug 7, 2023
206b6f1
fix
kyu08 Aug 7, 2023
bd5f925
make makefile#new does not return result but just makefile
kyu08 Aug 7, 2023
6e5d015
path_to_contentをfile.rsに移動
kyu08 Aug 7, 2023
f882fa3
refactor
kyu08 Aug 7, 2023
dbefc53
include::content_to_include_file_paths が Vec<PathBuf>を返すように修正
kyu08 Aug 7, 2023
28449d8
fix
kyu08 Aug 7, 2023
24efc1c
pub(super)
kyu08 Aug 7, 2023
89ec3bd
add comment
kyu08 Aug 7, 2023
2bfd9ed
change import stmt
kyu08 Aug 7, 2023
6293d1e
rename
kyu08 Aug 7, 2023
8b84427
delete unused lines
kyu08 Aug 7, 2023
89b4c11
line_to_including_file_pathsがOptionを返すように変更
kyu08 Aug 7, 2023
412b154
rename
kyu08 Aug 7, 2023
cd2bb52
delete unused derive
kyu08 Aug 7, 2023
d4edc69
refactor
kyu08 Aug 7, 2023
0603042
fix
kyu08 Aug 7, 2023
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
31 changes: 31 additions & 0 deletions CREDITS
Original file line number Diff line number Diff line change
Expand Up @@ -254,3 +254,34 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
================================================================

uuid-rs/uuid
https://github.com/uuid-rs/uuid
----------------------------------------------------------------

Copyright (c) 2014 The Rust Project Developers
Copyright (c) 2018 Ashley Mannix, Christopher Armstrong, Dylan DPC, Hunar Roop Kahlon

Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
Software without restriction, including without
limitation the rights to use, copy, modify, merge,
publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software
is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice
shall be included in all copies or substantial portions
of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.
37 changes: 22 additions & 15 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ edition = "2021"
[dependencies]
regex = "1.7.1"
skim = "0.10.4"
uuid = { version = "1.4.1", features = ["serde", "v4"] }
20 changes: 14 additions & 6 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,26 +1,34 @@
.PHONY: test build run check echo-test build-release echo-greeting cmd
include ./makefiles/test.mk

.PHONY: echo-test
echo-test:
@echo good

.PHONY: test
test : # run test
cargo test
cargo nextest run

.PHONY: run
run:
@cargo run
@cargo run

.PHONY: build
build:
@cargo build
@cargo build

.PHONY: check
check:
@cargo check
@cargo check

.PHONY: build-release
build-release:
@cargo build --verbose --release
@cargo build --verbose --release

.PHONY: echo-greeting
echo-greeting:
@echo hello fzf-make!

.PHONY: cmd
cmd:
@read -p "Do something? y/n:" ans; \
if [ "$$ans" = y ]; then \
Expand Down
3 changes: 3 additions & 0 deletions c.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.PHONY: c
c:
@echo hello c.mk!2
6 changes: 6 additions & 0 deletions makefiles/test.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
include ./makefiles/test2.mk

.PHONY: echo-test2
echo-test2:
@echo "test2"

3 changes: 3 additions & 0 deletions makefiles/test2.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.PHONY: test2
test2:
echo "test2"
1 change: 1 addition & 0 deletions src/file.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod file;
94 changes: 94 additions & 0 deletions src/file/file.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// module for file manipulation
use std::path::Path;

use crate::parser::{self, makefile};

// get_makefile_file_names returns filenames of Makefile and the files included by Makefile
pub fn create_makefile() -> Result<makefile::Makefile, &'static str> {
kyu08 marked this conversation as resolved.
Show resolved Hide resolved
let Some(makefile_name) = specify_makefile_name(".".to_string()) else { return Err("makefile not found") };

Ok(parser::makefile::Makefile::new(
Path::new(&makefile_name).to_path_buf(),
))
}

fn specify_makefile_name(target_path: String) -> Option<String> {
kyu08 marked this conversation as resolved.
Show resolved Hide resolved
// By default, when make looks for the makefile, it tries the following names, in order: GNUmakefile, makefile and Makefile.
// https://www.gnu.org/software/make/manual/make.html#Makefile-Names
// enumerate `Makefile` too not only `makefile` to make it work on case insensitive file system
let makefile_name_options = vec!["GNUmakefile", "makefile", "Makefile"];

for file_name in makefile_name_options {
let path = Path::new(&target_path).join(file_name);
if path.is_file() {
return Some(file_name.to_string());
}
continue;
}

None
}

#[cfg(test)]
mod test {
use super::*;
use std::fs::{self, File};
use uuid::Uuid;

#[test]
fn specify_makefile_name_test() {
struct Case {
title: &'static str,
files: Vec<&'static str>,
expect: Option<String>,
}
let cases = vec![
Case {
title: "no makefile",
files: vec!["README.md"],
expect: None,
},
Case {
title: "GNUmakefile",
files: vec!["makefile", "GNUmakefile", "README.md", "Makefile"],
expect: Some("GNUmakefile".to_string()),
},
Case {
title: "makefile",
files: vec!["makefile", "Makefile", "README.md"],
expect: Some("makefile".to_string()),
},
// NOTE: not use this test case because there is a difference in handling case sensitivity between macOS and linux.
// to use this test case, you need to determine whether the file system is
// case-sensitive or not when test execute.
// Case {
// title: "Makefile",
// files: vec!["Makefile", "README.md"],
// expect: Some("makefile".to_string()),
// },
];

for case in cases {
let random_dir_name = Uuid::new_v4().to_string();
let tmp_dir = std::env::temp_dir().join(random_dir_name);
match fs::create_dir(tmp_dir.as_path()) {
Err(e) => panic!("fail to create dir: {:?}", e),
Ok(_) => {}
}

for file in case.files {
match File::create(tmp_dir.join(file)) {
Err(e) => panic!("fail to create file: {:?}", e),
Ok(_) => {}
}
}

assert_eq!(
case.expect,
specify_makefile_name(tmp_dir.to_string_lossy().to_string()),
"\nFailed in the 🚨{:?}🚨",
case.title,
);
}
}
}
1 change: 1 addition & 0 deletions src/fuzzy_finder.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod fuzzy_finder;
63 changes: 63 additions & 0 deletions src/fuzzy_finder/fuzzy_finder.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
use skim::prelude::{Receiver, Skim, SkimItem, SkimItemReader, SkimOptions, SkimOptionsBuilder};
use std::{io::Cursor, process, sync::Arc};

use crate::parser::makefile;

pub fn run(makefile: makefile::Makefile) {
let preview_command = get_preview_command(makefile.to_include_path_string());
let options = get_skimoptions(&preview_command);
let items = get_skimitem(makefile.to_target_string());

if let output @ Some(_) = Skim::run_with(&options, items) {
if output.as_ref().unwrap().is_abort {
process::exit(0)
}

let selected_items = output
.map(|out| out.selected_items)
.unwrap_or_else(Vec::new);

for item in selected_items.iter() {
println!("executing `make {}`...", item.output().to_string());
process::Command::new("make")
.stdin(process::Stdio::inherit())
.arg(item.output().to_string())
.spawn()
.expect("Failed to execute process")
.wait()
.expect("Failed to execute process");
}
}
}

fn get_preview_command(file_paths: Vec<String>) -> String {
// MEMO: result has format like `test.mk:2:echo-mk`
let preview_command = format!(
r#"
files="{}" \
result=$(grep -rnE '^{}\s*:' $(echo $files)); \
IFS=':' read -r filename lineno _ <<< $result; \
bat --style=numbers --color=always --line-range $lineno: \
--highlight-line $lineno $filename;"#,
file_paths.join(" "),
"{}",
);

preview_command
}

fn get_skimoptions(preview_command: &str) -> SkimOptions {
SkimOptionsBuilder::default()
.preview(Some(preview_command))
.reverse(true)
.build()
.unwrap()
}

fn get_skimitem(targets: Vec<String>) -> Option<Receiver<Arc<dyn SkimItem>>> {
let targets = targets.join("\n");
let item_reader = SkimItemReader::default();
let items = item_reader.of_bufread(Cursor::new(targets));

Some(items)
}
14 changes: 14 additions & 0 deletions src/handler.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
use crate::{file::file, fuzzy_finder::fuzzy_finder};
use std::process;

pub fn run() {
let makefile = match file::create_makefile() {
Err(e) => {
println!("[ERR] {}", e.to_string());
process::exit(1)
}
Ok(f) => f,
};

fuzzy_finder::run(makefile);
}
31 changes: 6 additions & 25 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,9 @@
use skim::prelude::Skim;
use std::process;

mod misc;
mod file;
mod fuzzy_finder;
mod handler;
mod parser;

fn main() {
let (options, items) = misc::get_params();
if let output @ Some(_) = Skim::run_with(&options, items) {
if output.as_ref().unwrap().is_abort {
process::exit(0)
}

let selected_items = output
.map(|out| out.selected_items)
.unwrap_or_else(Vec::new);

for item in selected_items.iter() {
println!("make {}", item.output().to_string());
process::Command::new("make")
.stdin(process::Stdio::inherit())
.arg(item.output().to_string())
.spawn()
.expect("Failed to execute process")
.wait()
.expect("Failed to execute process");
}
}
// TODO: catch panic
handler::run();
}
3 changes: 3 additions & 0 deletions src/parser.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub mod include;
pub mod makefile;
pub mod target;
Loading