Skip to content

Commit b9d042f

Browse files
committed
Initial commit
0 parents  commit b9d042f

File tree

5 files changed

+176
-0
lines changed

5 files changed

+176
-0
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
2+
/target
3+
**/*.rs.bk

Cargo.lock

Lines changed: 38 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
[package]
2+
name = "rs-git-fsmonitor"
3+
version = "0.1.0"
4+
authors = ["Jason Gavris <[email protected]>"]
5+
6+
[dependencies]
7+
serde = "1.0"
8+
serde_json = "1.0"
9+

rs-git-fsmonitor.iml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<module type="RUST_MODULE" version="4">
3+
<component name="NewModuleRootManager" inherit-compiler-output="true">
4+
<exclude-output />
5+
<content url="file://$MODULE_DIR$">
6+
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
7+
<sourceFolder url="file://$MODULE_DIR$/examples" isTestSource="false" />
8+
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" />
9+
<sourceFolder url="file://$MODULE_DIR$/benches" isTestSource="true" />
10+
<excludeFolder url="file://$MODULE_DIR$/target" />
11+
</content>
12+
<orderEntry type="inheritedJdk" />
13+
<orderEntry type="sourceFolder" forTests="false" />
14+
</component>
15+
</module>

src/main.rs

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
use std::env;
2+
use std::io::{self, Error, ErrorKind, Write};
3+
use std::process::{exit, Command, Stdio};
4+
5+
extern crate serde;
6+
7+
#[macro_use]
8+
extern crate serde_json;
9+
10+
use serde_json::{Value};
11+
12+
fn main() {
13+
query_watchman().unwrap_or_else( |e| {
14+
eprintln!("{}", e);
15+
exit(1);
16+
})
17+
}
18+
19+
fn query_watchman() -> io::Result<()> {
20+
let git_work_tree = env::current_dir().unwrap();
21+
22+
let mut watchman =
23+
Command::new("watchman")
24+
.args(&["-j", "--no-pretty"])
25+
.stdin(Stdio::piped())
26+
.stdout(Stdio::piped())
27+
.spawn()?;
28+
29+
{
30+
let args: Vec<String> = env::args().collect();
31+
let time = &args[2];
32+
let time_nanoseconds: u64 = time.parse::<u64>().unwrap();
33+
let time_seconds = time_nanoseconds / 1000000000;
34+
35+
let watchman_query = json!(
36+
[
37+
"query",
38+
git_work_tree,
39+
{
40+
"since": time_seconds,
41+
"fields": ["name"],
42+
"expression": [
43+
"not", [
44+
"allof",[
45+
"since",
46+
time_seconds,
47+
"cclock"
48+
],
49+
[
50+
"not",
51+
"exists"
52+
]
53+
]
54+
]
55+
}
56+
]
57+
);
58+
59+
watchman
60+
.stdin
61+
.as_mut()
62+
.unwrap()
63+
.write_all(watchman_query.to_string().as_bytes())?;
64+
}
65+
66+
let output =
67+
watchman
68+
.wait_with_output()?
69+
.stdout;
70+
71+
let response: Value =
72+
serde_json::from_str(String::from_utf8(output).unwrap().as_str())?;
73+
74+
match response["error"].as_str() {
75+
Some(_) => return add_to_watchman(git_work_tree),
76+
None => {},
77+
}
78+
79+
match response["files"].as_array() {
80+
Some(files) => {
81+
for file in files {
82+
match file.as_str() {
83+
Some(filename) => print!("{}\0", filename),
84+
None => {},
85+
}
86+
}
87+
88+
return Ok(())
89+
},
90+
None => return Err(Error::new(ErrorKind::Other, "missing file data")),
91+
}
92+
}
93+
94+
fn add_to_watchman(worktree: std::path::PathBuf) -> io::Result<()> {
95+
let watchman =
96+
Command::new("watchman")
97+
.args(&["watch", worktree.to_str().unwrap()])
98+
.stdin(Stdio::piped())
99+
.stdout(Stdio::piped())
100+
.spawn()?;
101+
102+
match watchman.wait_with_output() {
103+
Ok(_) => {
104+
print!("\0");
105+
return Ok(())
106+
},
107+
Err(e) => {
108+
return Err(e)
109+
}
110+
}
111+
}

0 commit comments

Comments
 (0)