///|
pub let version : String = "0.1.2"
///|
pub(all) enum InstructionKind {
From
Run
Cmd
Entrypoint
Copy
Add
Workdir
Env
Expose
User
Arg
Label
Volume
Healthcheck
Shell
Maintainer
Stopsignal
Onbuild
Unknown
} derive(Eq, Debug)
///|
pub extend InstructionKind with Eq::{not_equal, equal}
///|
pub extend InstructionKind with @moonbitlang/core/debug.Debug::{to_repr}
///|
pub(all) enum InstructionForm {
Shell
Json
Other
} derive(Eq, Debug)
///|
pub extend InstructionForm with Eq::{not_equal, equal}
///|
pub extend InstructionForm with @moonbitlang/core/debug.Debug::{to_repr}
///|
pub(all) struct Instruction {
kind : InstructionKind
name : String
arguments : String
line : Int
form : InstructionForm
stage : String?
copy_from : String?
ignored_codes : Array[String]
node : Node
} derive(Debug)
///|
pub extend Instruction with @moonbitlang/core/debug.Debug::{to_repr}
///|
pub(all) struct LintOptions {
ignored : Array[String]
trusted_registries : Array[String]
required_labels : Array[String]
} derive(Debug)
///|
pub extend LintOptions with @moonbitlang/core/debug.Debug::{to_repr}
///|
pub fn default_options() -> LintOptions {
{ ignored: [], trusted_registries: [], required_labels: [], }
}
///|
pub(all) struct Dockerfile {
instructions : Array[Instruction]
} derive(Debug)
///|
pub extend Dockerfile with @moonbitlang/core/debug.Debug::{to_repr}
///|
pub(all) struct Diagnostic {
code : String
level : String
line : Int
message : String
stage : String?
} derive(Eq, Debug)
///|
pub extend Diagnostic with Eq::{not_equal, equal}
///|
pub extend Diagnostic with @moonbitlang/core/debug.Debug::{to_repr}
///|
pub(all) struct LintResult {
diagnostics : Array[Diagnostic]
instruction_count : Int
} derive(Debug)
///|
pub extend LintResult with @moonbitlang/core/debug.Debug::{to_repr}
///|
pub(all) struct ParseError {
line : Int
message : String
}
///|
pub impl Show for ParseError with fn output(self, logger) {
logger.write_string("parse error at line \{self.line}: \{self.message}")
}
///|
pub extend ParseError with Show::{to_string, output}
///|
pub fn LintResult::error_count(self : LintResult) -> Int {
let mut count = 0
for item in self.diagnostics {
if item.level == "error" {
count += 1
}
}
count
}
///|
pub fn LintResult::warning_count(self : LintResult) -> Int {
let mut count = 0
for item in self.diagnostics {
if item.level == "warning" {
count += 1
}
}
count
}
///|
pub fn LintResult::has_errors(self : LintResult) -> Bool {
self.error_count() > 0
}
///|
pub fn LintResult::should_fail(self : LintResult, threshold : String) -> Bool {
match threshold {
"never" => false
"warning" => self.diagnostics.length() > 0
_ => self.has_errors()
}
}
///|
pub fn LintResult::has_code(self : LintResult, code : String) -> Bool {
for item in self.diagnostics {
if item.code == code {
return true
}
}
false
}
///|
fn kind_of(name : String) -> InstructionKind {
match name.to_upper() {
"FROM" => From
"RUN" => Run
"CMD" => Cmd
"ENTRYPOINT" => Entrypoint
"COPY" => Copy
"ADD" => Add
"WORKDIR" => Workdir
"ENV" => Env
"EXPOSE" => Expose
"USER" => User
"ARG" => Arg
"LABEL" => Label
"VOLUME" => Volume
"HEALTHCHECK" => Healthcheck
"SHELL" => Shell
"MAINTAINER" => Maintainer
"STOPSIGNAL" => Stopsignal
"ONBUILD" => Onbuild
_ => Unknown
}
}
///|
fn form_of(arguments : String) -> InstructionForm {
let trimmed = arguments.trim().to_owned()
if trimmed.has_prefix("[") {
Json
} else if trimmed.is_empty() {
Other
} else {
Shell
}
}