gitlab_time_report_cli/
fetch_projects.rs

1//! Handles fetching of repositories
2
3#![cfg(not(tarpaulin_include))]
4
5use gitlab_time_report::model::Project;
6use gitlab_time_report::{FetchOptions, QueryError};
7
8/// Fetches the time logs and related data for a single GitLab repository.
9pub(super) fn fetch_project(
10    url: &str,
11    token: Option<&String>,
12) -> Result<Project, Box<dyn std::error::Error>> {
13    let fetch_options = FetchOptions::new(url, token.cloned())?;
14
15    let project_result = gitlab_time_report::fetch_project_time_logs(&fetch_options);
16    match project_result {
17        Ok(project) => Ok(project),
18        Err(QueryError::ProjectNotFound(url)) => {
19            print_project_not_found(&url);
20            Err(QueryError::ProjectNotFound(url).into())
21        }
22        Err(error) => Err(error.into()),
23    }
24}
25
26/// Fetch time logs for multiple GitLab repositories and merges them into a single project.
27pub(super) fn fetch_projects(
28    urls: Vec<String>,
29    token: Option<&String>,
30) -> Result<Project, Box<dyn std::error::Error>> {
31    // Fetch the data for the first URL
32    let mut url_iter = urls.into_iter();
33    let first_url = url_iter.next().expect("Should be at least one URL");
34    println!("Fetching time logs from '{first_url}'...");
35    let mut project = fetch_project(&first_url, token)?;
36
37    // Fetch the data for all other URLs and merge them into the first project
38    for url in url_iter {
39        println!("Fetching time logs from '{url}'...");
40        let current_project = fetch_project(&url, token)?;
41        project.merge(current_project);
42    }
43    Ok(project)
44}
45
46/// Prints a message regarding access token. URL passed to this function should be without a
47/// protocol prefix (`https://`)
48fn print_project_not_found(url: &str) {
49    let (host, path) = url.split_once('/').expect("Should be a URL with one `/`");
50    eprintln!("\
51Project \"{url}\" could not be found. If the project visibility is set to 'internal' or 'private', \
52you need to provide a GitLab access token with the 'read_api' permission and \
53specify it with the --token option.
54
55You can use a personal, group or project access token. Create a new one with one of the following URLs:
56Personal: https://{host}/-/user_settings/personal_access_tokens?name=GitLab+Time-Report&scopes=read_api
57Project:  https://{host}/{path}/-/settings/access_tokens
58Group:    Navigate to your group settings => Access Tokens => Generate new token\n");
59}