Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions deployment/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@
},
"newLineKind": {
"$ref": "#/definitions/newLineKind"
},
"healthcheckCmdNewLine": {
"description": "Whether to always break a HEALTHCHECK command onto its own continuation line when the instruction has options, even if it would fit on one line.",
"default": false,
"type": "boolean"
}
}
}
14 changes: 12 additions & 2 deletions src/configuration/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@ impl ConfigurationBuilder {
self.insert("newLineKind", value.to_string().into())
}

/// Whether to always break a `HEALTHCHECK` command onto its own continuation
/// line when the instruction has options, even if it would fit on one line.
/// Default: `false`
pub fn healthcheck_cmd_new_line(&mut self, value: bool) -> &mut Self {
self.insert("healthcheckCmdNewLine", value.into())
}

#[cfg(test)]
pub(super) fn get_inner_config(&self) -> ConfigKeyMap {
self.config.clone()
Expand All @@ -85,10 +92,13 @@ mod tests {
#[test]
fn check_all_values_set() {
let mut config = ConfigurationBuilder::new();
config.new_line_kind(NewLineKind::CarriageReturnLineFeed).line_width(90);
config
.new_line_kind(NewLineKind::CarriageReturnLineFeed)
.line_width(90)
.healthcheck_cmd_new_line(true);

let inner_config = config.get_inner_config();
assert_eq!(inner_config.len(), 2);
assert_eq!(inner_config.len(), 3);
let diagnostics = resolve_config(inner_config, &Default::default()).diagnostics;
assert_eq!(diagnostics.len(), 0);
}
Expand Down
3 changes: 3 additions & 0 deletions src/configuration/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,7 @@ use serde::Serialize;
pub struct Configuration {
pub line_width: u32,
pub new_line_kind: NewLineKind,
/// Whether to always break a `HEALTHCHECK` command onto its own continuation
/// line when the instruction has options, even if it would fit on one line.
pub healthcheck_cmd_new_line: bool,
}
1 change: 1 addition & 0 deletions src/configuration/resolve_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ pub fn resolve_config(config: ConfigKeyMap, global_config: &GlobalConfiguration)
global_config.new_line_kind.unwrap_or(RECOMMENDED_GLOBAL_CONFIGURATION.new_line_kind),
&mut diagnostics,
),
healthcheck_cmd_new_line: get_value(&mut config, "healthcheckCmdNewLine", false, &mut diagnostics),
};

diagnostics.extend(get_unknown_property_diagnostics(config));
Expand Down
4 changes: 2 additions & 2 deletions src/generation/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use super::helpers::parse_comments;
use crate::configuration::Configuration;

pub struct Context<'a> {
pub _config: &'a Configuration,
pub config: &'a Configuration,
pub dockerfile: &'a Dockerfile,
pub text: &'a str,
pub handled_comments: HashSet<usize>,
Expand All @@ -27,7 +27,7 @@ pub struct Context<'a> {
impl<'a> Context<'a> {
pub fn new(text: &'a str, dockerfile: &'a Dockerfile, config: &'a Configuration) -> Self {
Self {
_config: config,
config,
text,
dockerfile,
handled_comments: HashSet::new(),
Expand Down
6 changes: 4 additions & 2 deletions src/generation/generate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -323,11 +323,13 @@ fn gen_healthcheck_instruction<'a>(node: &'a HealthcheckInstruction, context: &m

// group the options and the nested command so they sit on one line when they
// fit under the line width and otherwise break onto an aligned continuation
// line (#29). a break the author already wrote forces the multi-line form.
// line (#29). a break the author already wrote forces the multi-line form, as
// does `healthcheckCmdNewLine` when there's a command preceded by options.
let first_line = node.span.relative_span(context.dockerfile).0;
let command_span = node.cmd.as_ref().map(|c| c.span()).unwrap_or(node.span);
let command_line = command_span.relative_span(context.dockerfile).0;
let force_use_new_lines = command_line > first_line;
let proactive_split = context.config.healthcheck_cmd_new_line && node.cmd.is_some() && !node.flags.is_empty();
let force_use_new_lines = command_line > first_line || proactive_split;
items.extend(gen_grouped_values(
vec![(flags_items, first_line), (command_items, command_line)],
HEALTHCHECK_CONTINUATION_INDENT,
Expand Down
33 changes: 33 additions & 0 deletions tests/specs/Healthcheck/Healthcheck_CmdNewLine.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
~~ healthcheckCmdNewLine: true ~~
== should split CMD onto its own line when there are options ==
HEALTHCHECK --interval=30s CMD curl -f http://localhost/

[expect]
HEALTHCHECK --interval=30s \
CMD curl -f http://localhost/

== should split before an exec-form command ==
HEALTHCHECK --retries=3 CMD ["curl", "-f", "http://localhost/"]

[expect]
HEALTHCHECK --retries=3 \
CMD ["curl", "-f", "http://localhost/"]

== should not split when there are no options ==
HEALTHCHECK CMD curl -f http://localhost/

[expect]
HEALTHCHECK CMD curl -f http://localhost/

== should not split NONE ==
HEALTHCHECK --interval=30s NONE

[expect]
HEALTHCHECK --interval=30s NONE

== should collapse a continuation before NONE ==
HEALTHCHECK --interval=30s \
NONE

[expect]
HEALTHCHECK --interval=30s NONE