pipedash-plugin-api 0.14.0

Plugin API for Pipedash - CI/CD pipeline dashboard
Documentation
#[macro_export]
macro_rules! plugin_struct {
    ($name:ident, $client:ty, $meta:expr $(; $($field:ident: $fty:ty = $init:expr),+ $(,)?)?) => {
        $crate::plugin_struct!(@define $name, $meta;
            client: Option<$client> = None,
            config: ::std::collections::HashMap<String, String> = ::std::collections::HashMap::new()
            $(, $($field: $fty = $init),+)?
        );

        impl $name {
            fn client(&self) -> $crate::PluginResult<&$client> {
                self.client.as_ref().ok_or_else(|| {
                    $crate::PluginError::Internal("Plugin not initialized".to_string())
                })
            }
        }
    };
    (custom $name:ident, $meta:expr; $($field:ident: $fty:ty = $init:expr),+ $(,)?) => {
        $crate::plugin_struct!(@define $name, $meta; $($field: $fty = $init),+);
    };
    (@define $name:ident, $meta:expr; $($field:ident: $fty:ty = $init:expr),*) => {
        pub struct $name {
            metadata: $crate::PluginMetadata,
            $($field: $fty,)*
        }

        impl Default for $name {
            fn default() -> Self {
                Self::new()
            }
        }

        impl $name {
            pub fn new() -> Self {
                Self {
                    metadata: $meta,
                    $($field: $init,)*
                }
            }
        }
    };
}

#[macro_export]
macro_rules! plugin_impl {
    ($ty:ident [$($methods:tt)*] { $($items:tt)* }) => {
        $crate::plugin_impl!(@munch $ty { $($items)* } [$($methods)*] []);
    };
    (@munch $ty:ident { $($items:tt)* } [] [$($out:tt)*]) => {
        #[::async_trait::async_trait]
        impl $crate::Plugin for $ty {
            $($items)*
            $($out)*
        }
    };
    (@munch $ty:ident $items:tt [metadata $(, $($rest:tt)*)?] [$($out:tt)*]) => {
        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
            fn metadata(&self) -> &$crate::PluginMetadata {
                &self.metadata
            }
        ]);
    };
    (@munch $ty:ident $items:tt [status_source $(, $($rest:tt)*)?] [$($out:tt)*]) => {
        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
            fn status_source(&self) -> Option<&$crate::StatusSource> {
                self.status_source.as_ref()
            }
        ]);
    };
    (@munch $ty:ident $items:tt [available_from_filtered $(, $($rest:tt)*)?] [$($out:tt)*]) => {
        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
            async fn fetch_available_pipelines(
                &self, params: Option<$crate::PaginationParams>,
            ) -> $crate::PluginResult<$crate::PaginatedAvailablePipelines> {
                self.fetch_available_pipelines_filtered(None, None, params).await
            }
        ]);
    };
    (@munch $ty:ident $items:tt [fetch_available_pipelines $(, $($rest:tt)*)?] [$($out:tt)*]) => {
        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
            async fn fetch_available_pipelines(
                &self, params: Option<$crate::PaginationParams>,
            ) -> $crate::PluginResult<$crate::PaginatedAvailablePipelines> {
                self.fetch_available_pipelines_impl(params).await
            }
        ]);
    };
    (@munch $ty:ident $items:tt [fetch_available_pipelines_filtered $(, $($rest:tt)*)?] [$($out:tt)*]) => {
        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
            async fn fetch_available_pipelines_filtered(
                &self, org: Option<String>, search: Option<String>,
                params: Option<$crate::PaginationParams>,
            ) -> $crate::PluginResult<$crate::PaginatedAvailablePipelines> {
                self.fetch_available_pipelines_filtered_impl(org, search, params).await
            }
        ]);
    };
    (@munch $ty:ident $items:tt [fetch_organizations $(, $($rest:tt)*)?] [$($out:tt)*]) => {
        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
            async fn fetch_organizations(&self) -> $crate::PluginResult<Vec<$crate::Organization>> {
                self.fetch_organizations_impl().await
            }
        ]);
    };
    (@munch $ty:ident $items:tt [ids_with_ci $(, $($rest:tt)*)?] [$($out:tt)*]) => {
        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
            async fn ids_with_ci(&self, ids: Vec<String>) -> $crate::PluginResult<Vec<String>> {
                self.ids_with_ci_impl(ids).await
            }
        ]);
    };
    (@munch $ty:ident $items:tt [fetch_pipelines $(, $($rest:tt)*)?] [$($out:tt)*]) => {
        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
            async fn fetch_pipelines(&self) -> $crate::PluginResult<Vec<$crate::Pipeline>> {
                self.fetch_pipelines_impl().await
            }
        ]);
    };
    (@munch $ty:ident $items:tt [fetch_run_history $(, $($rest:tt)*)?] [$($out:tt)*]) => {
        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
            async fn fetch_run_history(
                &self, pipeline_id: &str, limit: usize,
            ) -> $crate::PluginResult<Vec<$crate::PipelineRun>> {
                self.fetch_run_history_impl(pipeline_id, limit).await
            }
        ]);
    };
    (@munch $ty:ident $items:tt [fetch_run_details $(, $($rest:tt)*)?] [$($out:tt)*]) => {
        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
            async fn fetch_run_details(
                &self, pipeline_id: &str, run_number: i64,
            ) -> $crate::PluginResult<$crate::PipelineRun> {
                self.fetch_run_details_impl(pipeline_id, run_number).await
            }
        ]);
    };
    (@munch $ty:ident $items:tt [fetch_recent_runs $(, $($rest:tt)*)?] [$($out:tt)*]) => {
        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
            async fn fetch_recent_runs(
                &self, pipeline_ids: &[String], limit: usize,
            ) -> $crate::PluginResult<
                ::std::collections::HashMap<String, Vec<$crate::PipelineRun>>,
            > {
                self.fetch_recent_runs_impl(pipeline_ids, limit).await
            }
        ]);
    };
    (@munch $ty:ident $items:tt [fetch_log_nodes $(, $($rest:tt)*)?] [$($out:tt)*]) => {
        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
            async fn fetch_log_nodes(
                &self, run: $crate::RunRef<'_>,
            ) -> $crate::PluginResult<Vec<$crate::LogNode>> {
                self.fetch_log_nodes_impl(run).await
            }
        ]);
    };
    (@munch $ty:ident $items:tt [read_log $(, $($rest:tt)*)?] [$($out:tt)*]) => {
        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
            async fn read_log(
                &self, run: $crate::RunRef<'_>, node_id: &str, from: Option<&$crate::LogCursor>,
                sink: &mut $crate::LogSink,
            ) -> $crate::PluginResult<$crate::LogRead> {
                self.read_log_impl(run, node_id, from, sink).await
            }
        ]);
    };
    (@munch $ty:ident $items:tt [fetch_workflow_parameters $(, $($rest:tt)*)?] [$($out:tt)*]) => {
        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
            async fn fetch_workflow_parameters(
                &self, workflow_id: &str,
            ) -> $crate::PluginResult<Vec<$crate::WorkflowParameter>> {
                self.fetch_workflow_parameters_impl(workflow_id).await
            }
        ]);
    };
    (@munch $ty:ident $items:tt [trigger_pipeline $(, $($rest:tt)*)?] [$($out:tt)*]) => {
        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
            async fn trigger_pipeline(
                &self, params: $crate::TriggerParams,
            ) -> $crate::PluginResult<$crate::TriggerResult> {
                self.trigger_pipeline_impl(params).await
            }
        ]);
    };
    (@munch $ty:ident $items:tt [cancel_run $(, $($rest:tt)*)?] [$($out:tt)*]) => {
        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
            async fn cancel_run(
                &self, pipeline_id: &str, run_number: i64,
            ) -> $crate::PluginResult<()> {
                self.cancel_run_impl(pipeline_id, run_number).await
            }
        ]);
    };
    (@munch $ty:ident $items:tt [force_cancel_run $(, $($rest:tt)*)?] [$($out:tt)*]) => {
        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
            async fn force_cancel_run(
                &self, pipeline_id: &str, run_number: i64,
            ) -> $crate::PluginResult<()> {
                self.force_cancel_run_impl(pipeline_id, run_number).await
            }
        ]);
    };
    (@munch $ty:ident $items:tt [review_run $(, $($rest:tt)*)?] [$($out:tt)*]) => {
        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
            async fn review_run(
                &self, pipeline_id: &str, run_number: i64, decision: $crate::ReviewDecision,
            ) -> $crate::PluginResult<()> {
                self.review_run_impl(pipeline_id, run_number, decision).await
            }
        ]);
    };
    (@munch $ty:ident $items:tt [rerun_run $(, $($rest:tt)*)?] [$($out:tt)*]) => {
        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
            async fn rerun_run(
                &self, pipeline_id: &str, run_number: i64,
            ) -> $crate::PluginResult<()> {
                self.rerun(pipeline_id, run_number, false).await
            }
        ]);
    };
    (@munch $ty:ident $items:tt [rerun_failed_jobs $(, $($rest:tt)*)?] [$($out:tt)*]) => {
        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
            async fn rerun_failed_jobs(
                &self, pipeline_id: &str, run_number: i64,
            ) -> $crate::PluginResult<()> {
                self.rerun(pipeline_id, run_number, true).await
            }
        ]);
    };
    (@munch $ty:ident $items:tt [enable_pipeline $(, $($rest:tt)*)?] [$($out:tt)*]) => {
        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
            async fn enable_pipeline(&self, pipeline_id: &str) -> $crate::PluginResult<()> {
                self.enable_pipeline_impl(pipeline_id).await
            }
        ]);
    };
    (@munch $ty:ident $items:tt [check_permissions $(, $($rest:tt)*)?] [$($out:tt)*]) => {
        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
            async fn check_permissions(&self) -> $crate::PluginResult<$crate::PermissionStatus> {
                self.check_permissions_impl().await
            }
        ]);
    };
    (@munch $ty:ident $items:tt [check_health $(, $($rest:tt)*)?] [$($out:tt)*]) => {
        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
            async fn check_health(
                &self,
            ) -> $crate::PluginResult<Vec<$crate::ComponentHealth>> {
                self.check_health_impl().await
            }
        ]);
    };
    (@munch $ty:ident $items:tt [get_feature_availability $(, $($rest:tt)*)?] [$($out:tt)*]) => {
        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
            fn get_feature_availability(
                &self, status: &$crate::PermissionStatus,
            ) -> Vec<$crate::FeatureAvailability> {
                self.get_feature_availability_impl(status)
            }
        ]);
    };
    (@munch $ty:ident $items:tt [get_field_options $(, $($rest:tt)*)?] [$($out:tt)*]) => {
        $crate::plugin_impl!(@munch $ty $items [$($($rest)*)?] [$($out)*
            async fn get_field_options(
                &self, field_key: &str, config: &::std::collections::HashMap<String, String>,
            ) -> $crate::PluginResult<Vec<String>> {
                self.get_field_options_impl(field_key, config).await
            }
        ]);
    };
}

#[cfg(test)]
mod tests;