@@ -179,7 +179,6 @@ fn build_login_client() -> WpLoginClient {
179
179
#[ derive( Debug , Parser ) ]
180
180
#[ command( group(
181
181
ArgGroup :: new( "target" )
182
- . required( true )
183
182
. args( [ "wpcom_site" , "api_root" ] ) ,
184
183
) , group(
185
184
ArgGroup :: new( "post_ref" )
@@ -240,20 +239,47 @@ enum TargetSiteResolver {
240
239
WpOrg { api_root : Arc < ParsedUrl > } ,
241
240
}
242
241
243
- fn build_api_client ( args : & FetchPostArgs ) -> Result < WpApiClient > {
242
+ async fn build_api_client ( args : & FetchPostArgs ) -> Result < WpApiClient > {
243
+ let request_executor = Arc :: new ( ReqwestRequestExecutor :: new ( false , Duration :: from_secs ( 60 ) ) ) ;
244
+ let middleware_pipeline = Arc :: new ( WpApiMiddlewarePipeline :: default ( ) ) ;
244
245
// Determine target and auth
245
246
let target = if let Some ( site) = & args. wpcom_site {
247
+ // Explicit WordPress.com site takes priority
246
248
TargetSiteResolver :: WpCom { site : site. clone ( ) }
247
249
} else if let Some ( api_root) = & args. api_root {
248
- let parsed = ParsedUrl :: try_from ( api_root. as_str ( ) ) . map_err ( |_| {
249
- anyhow ! ( "Invalid api_root URL: must be a valid URL ending with /wp-json" )
250
- } ) ?;
251
- TargetSiteResolver :: WpOrg {
252
- api_root : Arc :: new ( parsed) ,
250
+ // Explicit api_root takes priority for wp.org/Jetpack
251
+ let parsed = ParsedUrl :: try_from ( api_root. as_str ( ) )
252
+ . map_err ( |_| anyhow ! ( "Invalid api_root URL: must be a valid URL ending with /wp-json" ) ) ?;
253
+ TargetSiteResolver :: WpOrg { api_root : Arc :: new ( parsed) }
254
+ } else if let Some ( post_url) = & args. post_url {
255
+ // Derive from post_url if possible
256
+ if let Ok ( u) = Url :: parse ( post_url) {
257
+ let host = u. host_str ( ) . unwrap_or ( "" ) ;
258
+ if host. ends_with ( ".wordpress.com" ) {
259
+ TargetSiteResolver :: WpCom { site : host. to_string ( ) }
260
+ } else {
261
+ // Attempt autodiscovery of API root from post URL
262
+ let login_client = WpLoginClient :: new_with_default_middleware_pipeline ( request_executor. clone ( ) ) ;
263
+ match login_client
264
+ . api_discovery ( post_url. clone ( ) )
265
+ . await
266
+ . combined_result ( )
267
+ . cloned ( )
268
+ {
269
+ Ok ( success) => TargetSiteResolver :: WpOrg { api_root : success. api_root_url } ,
270
+ Err ( _) => {
271
+ return Err ( anyhow ! (
272
+ "Could not autodiscover API root from --post-url. Please provide --api-root explicitly."
273
+ ) ) ;
274
+ }
275
+ }
276
+ }
277
+ } else {
278
+ return Err ( anyhow ! ( "Invalid --post-url; could not parse URL" ) ) ;
253
279
}
254
280
} else {
255
281
return Err ( anyhow ! (
256
- "Either --wpcom-site or --api-root must be provided "
282
+ "Provide either --wpcom-site, or --api-root, or a wordpress.com --post-url "
257
283
) ) ;
258
284
} ;
259
285
@@ -294,9 +320,6 @@ fn build_api_client(args: &FetchPostArgs) -> Result<WpApiClient> {
294
320
}
295
321
} ;
296
322
297
- let request_executor = Arc :: new ( ReqwestRequestExecutor :: new ( false , Duration :: from_secs ( 60 ) ) ) ;
298
- let middleware_pipeline = Arc :: new ( WpApiMiddlewarePipeline :: default ( ) ) ;
299
-
300
323
#[ derive( Debug ) ]
301
324
struct NoopNotifier ;
302
325
#[ async_trait:: async_trait]
@@ -316,7 +339,7 @@ fn build_api_client(args: &FetchPostArgs) -> Result<WpApiClient> {
316
339
}
317
340
318
341
async fn fetch_post_and_comments ( args : FetchPostArgs ) -> Result < ( ) > {
319
- let client = build_api_client ( & args) ?;
342
+ let client = build_api_client ( & args) . await ?;
320
343
321
344
let post_id = resolve_post_id ( & client, & args) . await ?;
322
345
0 commit comments