1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
//! Logging utilities for GitHub Actions
use env_logger::Builder;
use std::env;
use std::io::Write;

/// Initialise and create a `env_logger::Builder` which follows the
/// GitHub Actions logging syntax.
///
pub fn init_logger() -> Builder {
    let mut builder = Builder::from_default_env();

    // Make sure the target is STDOUT
    builder.target(env_logger::Target::Stdout);

    // Find and setup the correct log level
    builder.filter(None, get_log_level());
    builder.write_style(env_logger::WriteStyle::Always);

    // Custom Formatter for Actions
    builder.format(|buf, record| match record.level().as_str() {
        "DEBUG" => writeln!(buf, "::debug :: {}", record.args()),
        "WARN" => writeln!(buf, "::warning :: {}", record.args()),
        "ERROR" => {
            writeln!(buf, "::error :: {}", record.args())
        }
        _ => writeln!(buf, "{}", record.args()),
    });

    builder
}

/// Get the Log Level for the logger
fn get_log_level() -> log::LevelFilter {
    // DEBUG
    match env::var("DEBUG") {
        Ok(_value) => return log::LevelFilter::Debug,
        Err(_err) => (),
    }
    // ACTIONS_RUNNER_DEBUG
    match env::var("ACTIONS_RUNNER_DEBUG") {
        Ok(_value) => return log::LevelFilter::Debug,
        Err(_err) => (),
    };

    log::LevelFilter::Info
}

/// Error for files (including line and column numbers)
///
/// # Examples
///
/// ```
/// use ghactions::errorf;
///
/// # fn foo() {
/// errorf!(
///     file: "src/main.rs",
///     line: 0,
///     column: 0,
///     "Error checking file"
/// );
/// # }
/// ```
#[macro_export(local_inner_macros)]
macro_rules! errorf {
    // errorf!(file: "./lib.rs", line: 0, column: 0, "Sample Error")
    (file: $file:expr, line: $line:expr, column: $column:expr, $msg:tt) => {
        ::log::log!(::log::Level::Info, "::error file={},line={},col={} :: {}", $file, $line, $column, $msg)
    };
    // errorf!("a {} event", "log")
    ($($arg:tt)+) => (::log::log!($crate::Level::Error, $($arg)+))
}

/// Group Macros
///
/// # Examples
///
/// ```
/// use ghactions::group;
///
/// # fn foo() {
/// group!("working group");
/// # }
/// ```
#[macro_export(local_inner_macros)]
macro_rules! group {
    // group!("Group name")
    ($dst:expr $(,)?) => {
        ::log::log!(log::Level::Info, "::group::{}", $dst)
    };
}

/// End Group Macros
///
/// # Examples
///
/// ```
/// use ghactions::groupend;
///
/// # fn foo() {
/// groupend!();
/// # }

/// ```
#[macro_export(local_inner_macros)]
macro_rules! groupend {
    // group_end!()
    () => {
        ::log::log!(log::Level::Info, "::endgroup::")
    };
}

/// Sets the output of the Actions which can be used in subsequent Actions.
///
/// # Examples
///
/// ```
/// use ghactions::setoutput;
///
/// # fn foo() {
/// setoutput!("hello", "world");
/// # }
/// ```
#[macro_export(local_inner_macros)]
macro_rules! setoutput {
    // setoutput!("name", "value")
    ($($arg:tt)+) => (::log::log!(::log::Level::Info, "::set-output name={}::{}", $($arg)+))
}