@@ -12,6 +12,7 @@ extern crate walkdir;
1212#[ macro_use]
1313extern crate spectral;
1414
15+ use git2:: { Remote , Repository , Status , StatusOptions } ;
1516use gtmpl:: Func ;
1617use gtmpl:: Value ;
1718use regex:: Regex ;
@@ -27,8 +28,9 @@ pub struct Ctx {
2728#[ derive( Clone , Gtmpl ) ]
2829pub struct GitRepo {
2930 path : Location ,
30- //repo: git2::Repository
31+ //repo: git2::Repository,
3132 remotes : Func ,
33+ working_paths : Func ,
3234}
3335
3436#[ derive( Debug , Clone , Gtmpl ) ]
@@ -45,7 +47,17 @@ pub struct RemoteData {
4547 url_path : String ,
4648}
4749
48- fn find_remotes ( args : & [ Value ] ) -> Result < Value , String > {
50+ #[ derive( Debug , Clone , Gtmpl ) ]
51+ pub struct WorkingPaths {
52+ untracked : Vec < String > ,
53+ modified : Vec < String > ,
54+ deleted : Vec < String > ,
55+ added : Vec < String > ,
56+ renamed : Vec < String > ,
57+ conflicted : Vec < String > ,
58+ }
59+
60+ fn find_repo ( args : & [ Value ] ) -> Result < Repository , String > {
4961 if let Value :: Object ( ref o) = & args[ 0 ] {
5062 let full = o. get ( "path" )
5163 . and_then ( |v| {
@@ -56,29 +68,79 @@ fn find_remotes(args: &[Value]) -> Result<Value, String> {
5668 }
5769 } )
5870 . ok_or ( "path.full not empty" ) ?;
59- let mut remotes = HashMap :: new ( ) ;
60- let repo = git2:: Repository :: open ( Path :: new ( & full) ) . unwrap ( ) ;
61- repo. remotes ( )
62- . unwrap ( )
63- . iter ( )
64- . filter_map ( |x| {
65- x. and_then ( |name| {
66- repo. find_remote ( name)
67- . map ( |remote| RemoteData :: from ( remote) )
68- . ok ( )
69- } )
70- } )
71- //.collect::<Vec<_>>()
72- //.into_iter()
73- . for_each ( |rd| {
74- remotes. insert ( rd. name . clone ( ) , rd) ;
75- } ) ;
76- Ok ( remotes. into ( ) )
71+ let repo = Repository :: open ( Path :: new ( & full) ) . unwrap ( ) ;
72+ Ok ( repo)
7773 } else {
7874 Err ( format ! ( "GitRepo required, got: {:?}" , args) )
7975 }
8076}
8177
78+ fn find_remotes ( args : & [ Value ] ) -> Result < Value , String > {
79+ let repo = find_repo ( args) ?;
80+ let mut remotes = HashMap :: new ( ) ;
81+ repo. remotes ( )
82+ . unwrap ( )
83+ . iter ( )
84+ . filter_map ( |x| {
85+ x. and_then ( |name| {
86+ repo. find_remote ( name)
87+ . map ( |remote| RemoteData :: from ( remote) )
88+ . ok ( )
89+ } )
90+ } )
91+ //.collect::<Vec<_>>()
92+ //.into_iter()
93+ . for_each ( |rd| {
94+ remotes. insert ( rd. name . clone ( ) , rd) ;
95+ } ) ;
96+ Ok ( remotes. into ( ) )
97+ }
98+
99+ fn find_working_paths ( args : & [ Value ] ) -> Result < Value , String > {
100+ let repo = find_repo ( args) ?;
101+ let mut opts = StatusOptions :: new ( ) ;
102+ opts. include_untracked ( true ) ;
103+ let statuses = repo. statuses ( Some ( & mut opts) )
104+ . map_err ( |e| format ! ( "{}" , e) ) ?;
105+ let mut untracked = vec ! [ ] ;
106+ let mut modified = vec ! [ ] ;
107+ let mut added = vec ! [ ] ;
108+ let mut deleted = vec ! [ ] ;
109+ let mut renamed = vec ! [ ] ;
110+ let mut conflicted = vec ! [ ] ;
111+ for entry in statuses. iter ( ) {
112+ if let Some ( path) = entry. path ( ) {
113+ //eprintln!("path : {} {:?}", path, entry.status());
114+ let status = entry. status ( ) ;
115+ if status. intersects ( Status :: INDEX_MODIFIED ) || status. intersects ( Status :: WT_MODIFIED ) {
116+ modified. push ( path. to_owned ( ) ) ;
117+ }
118+ if status. intersects ( Status :: INDEX_NEW ) {
119+ added. push ( path. to_owned ( ) )
120+ }
121+ if status. intersects ( Status :: WT_NEW ) {
122+ untracked. push ( path. to_owned ( ) )
123+ }
124+ if status. intersects ( Status :: INDEX_DELETED ) || status. intersects ( Status :: WT_DELETED ) {
125+ deleted. push ( path. to_owned ( ) )
126+ }
127+ if status. intersects ( Status :: INDEX_RENAMED ) || status. intersects ( Status :: WT_RENAMED ) {
128+ renamed. push ( path. to_owned ( ) )
129+ }
130+ if status. intersects ( Status :: CONFLICTED ) {
131+ conflicted. push ( path. to_owned ( ) )
132+ }
133+ }
134+ }
135+ Ok ( WorkingPaths {
136+ untracked,
137+ modified,
138+ added,
139+ deleted,
140+ renamed,
141+ conflicted,
142+ } . into ( ) )
143+ }
82144impl < ' a > From < & ' a Path > for GitRepo {
83145 //TODO manage result & error
84146 fn from ( path : & Path ) -> Self {
@@ -91,12 +153,13 @@ impl<'a> From<&'a Path> for GitRepo {
91153 . unwrap ( ) ,
92154 } ,
93155 remotes : find_remotes,
156+ working_paths : find_working_paths,
94157 }
95158 }
96159}
97160
98- impl < ' b > From < git2 :: Remote < ' b > > for RemoteData {
99- fn from ( v : git2 :: Remote ) -> Self {
161+ impl < ' b > From < Remote < ' b > > for RemoteData {
162+ fn from ( v : Remote ) -> Self {
100163 // let host = url_parsed.host_str().unwrap_or("").to_owned();
101164 // let path = url_parsed.path().to_owned();
102165 let ( host, path) = v. url ( )
0 commit comments