11use anyhow:: Context ;
22use clap:: Parser ;
33
4- use josh_core:: filter:: tree;
5- use josh_core:: git:: { normalize_repo_path, spawn_git_command} ;
6- use josh_link:: make_signature;
7-
8- use std:: collections:: BTreeMap ;
4+ use josh_core:: git:: normalize_repo_path;
95
106#[ derive( Parser ) ]
117#[ command( about = "Josh Commit Queue" ) ]
@@ -18,6 +14,8 @@ struct Cli {
1814enum Commands {
1915 /// Initialize metarepo
2016 Init ,
17+ /// Start HTTP server
18+ Serve ( ServeArgs ) ,
2119 #[ command( flatten) ]
2220 Action ( ActionCommands ) ,
2321}
@@ -45,119 +43,18 @@ struct TrackArgs {
4543 mode : String ,
4644}
4745
48- fn handle_track (
49- args : & TrackArgs ,
50- transaction : & josh_core:: cache:: Transaction ,
51- ) -> anyhow:: Result < ( ) > {
52- let repo = transaction. repo ( ) ;
53-
54- // Fetch refs from remote
55- let refs = josh_cq:: remote:: list_refs ( & args. url ) ?;
56-
57- // Fetch HEAD from remote
58- spawn_git_command ( repo. path ( ) , & [ "fetch" , & args. url , "HEAD" ] , & [ ] ) ?;
59-
60- // Get commit from FETCH_HEAD
61- let fetch_head_ref = repo
62- . find_reference ( "FETCH_HEAD" )
63- . context ( "Failed to find FETCH_HEAD" ) ?;
64- let fetched_commit = fetch_head_ref
65- . peel_to_commit ( )
66- . context ( "Failed to peel FETCH_HEAD to commit" ) ?
67- . id ( ) ;
68-
69- // Get HEAD commit
70- let head_ref = repo. head ( ) . context ( "Failed to get HEAD" ) ?;
71- let head_commit = head_ref
72- . peel_to_commit ( )
73- . context ( "Failed to peel HEAD to commit" ) ?;
74- let head_tree = head_commit. tree ( ) . context ( "Failed to get HEAD tree" ) ?;
75-
76- let signature = make_signature ( repo) ?;
77-
78- let mode = josh_core:: filter:: LinkMode :: parse ( & args. mode )
79- . with_context ( || format ! ( "Invalid link mode: '{}'" , args. mode) ) ?;
80-
81- let link_path = std:: path:: Path :: new ( "remotes" ) . join ( & args. id ) . join ( "link" ) ;
82- let tree_with_link_oid = josh_link:: prepare_link_add (
83- & transaction,
84- & link_path,
85- & args. url ,
86- None , // filter (default :/)
87- "HEAD" , // target
88- fetched_commit,
89- & head_tree,
90- mode,
91- ) ?
92- . into_tree_oid ( ) ;
93-
94- let tree_with_link = repo
95- . find_tree ( tree_with_link_oid)
96- . context ( "Failed to find tree with link" ) ?;
97-
98- // Create refs.json blob
99- let refs_blob = {
100- let refs_map: BTreeMap < String , String > = refs
101- . iter ( )
102- . map ( |( k, v) | ( k. clone ( ) , v. to_string ( ) ) )
103- . collect ( ) ;
104-
105- let refs_json =
106- serde_json:: to_string_pretty ( & refs_map) . context ( "Failed to serialize refs to JSON" ) ?;
107-
108- repo. blob ( refs_json. as_bytes ( ) )
109- . context ( "Failed to create refs.json blob" ) ?
110- } ;
111-
112- // Insert refs.json into the tree
113- let refs_path = std:: path:: Path :: new ( "remotes" )
114- . join ( & args. id )
115- . join ( "refs.json" ) ;
116-
117- let final_tree = tree:: insert (
118- repo,
119- & tree_with_link,
120- & refs_path,
121- refs_blob,
122- git2:: FileMode :: Blob . into ( ) ,
123- )
124- . context ( "Failed to insert refs.json into tree" ) ?;
125-
126- // Create final commit with both files
127- let final_commit = repo
128- . commit (
129- None ,
130- & signature,
131- & signature,
132- & format ! ( "Track remote: {}" , args. id) ,
133- & final_tree,
134- & [ & head_commit] ,
135- )
136- . context ( "Failed to create final commit" ) ?;
137-
138- // Update HEAD to point to the new commit
139- repo. head ( ) ?
140- . set_target ( final_commit, "josh-cq track" )
141- . context ( "Failed to update HEAD" ) ?;
142-
143- println ! ( "Tracked remote '{}' at {}" , args. id, args. url) ;
144- println ! ( "Found {} refs" , refs. len( ) ) ;
145-
146- Ok ( ( ) )
46+ #[ derive( clap:: Parser ) ]
47+ struct ServeArgs {
48+ /// Port to listen on
49+ #[ arg( long, default_value = "8080" ) ]
50+ port : u16 ,
14751}
14852
149- #[ tokio:: main]
150- async fn main ( ) -> anyhow:: Result < ( ) > {
151- let cli = Cli :: parse ( ) ;
152-
153- let action = match cli. command {
154- Commands :: Init => {
155- // TODO
156- return Ok ( ( ) ) ;
157- }
158- Commands :: Action ( action) => action,
159- } ;
160-
53+ fn open_repo ( ) -> anyhow:: Result < (
54+ std:: path:: PathBuf ,
55+ std:: sync:: Arc < josh_core:: cache:: CacheStack > ,
56+ josh_core:: cache:: Transaction ,
57+ ) > {
16158 let repo = git2:: Repository :: open_from_env ( ) . context ( "Not in a git repository" ) ?;
16259 let repo_path = normalize_repo_path ( repo. path ( ) ) ;
16360
@@ -172,16 +69,51 @@ async fn main() -> anyhow::Result<()> {
17269 . open ( None )
17370 . context ( "Failed TransactionContext::open" ) ?;
17471
175- match action {
176- ActionCommands :: Track ( ref args) => handle_track ( args, & transaction) ,
177- ActionCommands :: Fetch => {
178- todo ! ( )
72+ Ok ( ( repo_path, cache, transaction) )
73+ }
74+
75+ #[ tokio:: main]
76+ async fn main ( ) -> anyhow:: Result < ( ) > {
77+ let cli = Cli :: parse ( ) ;
78+
79+ match cli. command {
80+ Commands :: Init => {
81+ // TODO
82+ return Ok ( ( ) ) ;
17983 }
180- ActionCommands :: Step => {
181- todo ! ( )
84+ Commands :: Serve ( args) => {
85+ let ( repo_path, cache, _transaction) = open_repo ( ) ?;
86+
87+ let state = josh_cq:: cq:: AppState { repo_path, cache } ;
88+ let app = josh_cq:: cq:: make_router ( state) ;
89+
90+ let addr = std:: net:: SocketAddr :: from ( ( [ 0 , 0 , 0 , 0 ] , args. port ) ) ;
91+ println ! ( "Listening on {}" , addr) ;
92+
93+ let listener = tokio:: net:: TcpListener :: bind ( addr) . await ?;
94+ axum:: serve ( listener, app) . await ?;
18295 }
183- ActionCommands :: Push => {
184- todo ! ( )
96+ Commands :: Action ( action) => {
97+ let ( _repo_path, _cache, transaction) = open_repo ( ) ?;
98+
99+ match action {
100+ ActionCommands :: Track ( ref args) => {
101+ let msg =
102+ josh_cq:: cq:: handle_track ( & args. url , & args. id , & args. mode , & transaction) ?;
103+ println ! ( "{}" , msg) ;
104+ }
105+ ActionCommands :: Fetch => {
106+ todo ! ( )
107+ }
108+ ActionCommands :: Step => {
109+ todo ! ( )
110+ }
111+ ActionCommands :: Push => {
112+ todo ! ( )
113+ }
114+ }
185115 }
186116 }
117+
118+ Ok ( ( ) )
187119}
0 commit comments