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
96 changes: 94 additions & 2 deletions dag/extdeps/tools/gnu_coreutils.dag
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module extdeps.tools.gnu_coreutils

import std.types { NonEmptyStr, FilePath }
import std.types { NonEmptyStr, FilePath, String, List }
import extdeps.version { VersionConstraint }
import extdeps.external_authority { ExternalAuthority }
import extdeps.uri { Uri, Https }
Expand All @@ -19,9 +19,101 @@ data grep_recursive_quiet_flags: NonEmptyStr = "-rqE"
// with the operands they apply to. Re-adding a flags literal here would re-fork it.
data grep_recursive_numbered_flags: NonEmptyStr = "-rnE"

data rm_force_recursive_flags: NonEmptyStr = "-rf"

data coreutils_docs: NonEmptyStr = "https://www.gnu.org/software/coreutils/manual/coreutils.html"

data min_coreutils_version: VersionConstraint = ">= 8.0"

// install(1) — GNU coreutils, "Setting file attributes" / install invocation. The flags used
// here are the ones that manual defines: -d creates each named directory, -m sets the mode,
// -o and -g set owner and group at creation. Owner-at-creation is why this repository installs
// rather than copying and fixing up: the wrongly-owned intermediate state has no moment in
// which to exist. install does NOT create missing parents — that is upstream behaviour, stated
// here so a caller does not assume otherwise (emit's serve_binary_parent_was_a_literal_note is
// the receipt for what assuming it costs).
data coreutils_install_directory_flag: NonEmptyStr = "-d"
data coreutils_install_mode_flag: NonEmptyStr = "-m"
data coreutils_install_owner_flag: NonEmptyStr = "-o"
data coreutils_install_group_flag: NonEmptyStr = "-g"
data coreutils_install_binary_name: NonEmptyStr = "install"

fn coreutils_install_directory_argv(mode: NonEmptyStr, path: String) -> List<String> {
[
coreutils_install_binary_name as String,
coreutils_install_directory_flag as String,
coreutils_install_mode_flag as String,
mode as String,
path,
]
}

fn coreutils_install_file_owned_argv(
mode: NonEmptyStr,
owner: NonEmptyStr,
group: NonEmptyStr,
source: String,
dest: String,
) -> List<String> {
[
coreutils_install_binary_name as String,
coreutils_install_mode_flag as String,
mode as String,
coreutils_install_owner_flag as String,
owner as String,
coreutils_install_group_flag as String,
group as String,
source,
dest,
]
}

fn coreutils_install_directory_owned_argv(
mode: NonEmptyStr,
owner: NonEmptyStr,
group: NonEmptyStr,
path: String,
) -> List<String> {
[
coreutils_install_binary_name as String,
coreutils_install_directory_flag as String,
coreutils_install_mode_flag as String,
mode as String,
coreutils_install_owner_flag as String,
owner as String,
coreutils_install_group_flag as String,
group as String,
path,
]
}

// rm(1) — GNU coreutils, "Removing files or directories". Three shapes are used in this
// repository and the distinction between them is load-bearing, not stylistic: -f removes a file
// and does not fail when it is already absent (idempotent teardown); -d removes an EMPTY
// directory and REFUSES a non-empty one, which is a fail-closed precondition rather than a
// weaker rm -r; -rf removes a tree. Choosing -rf where -d was meant turns a loud refusal into
// silent destruction, so the three carry separate names rather than a flags parameter a caller
// fills in.
data coreutils_rm_binary_name: NonEmptyStr = "rm"
data coreutils_rm_force_flag: NonEmptyStr = "-f"
data coreutils_rm_empty_directory_flag: NonEmptyStr = "-d"
data coreutils_rm_force_recursive_flags: NonEmptyStr = "-rf"

fn coreutils_rm_force_argv(paths: List<String>) -> List<String> {
concat([coreutils_rm_binary_name as String, coreutils_rm_force_flag as String], paths)
}

fn coreutils_rm_empty_directory_argv(path: String) -> List<String> {
[
coreutils_rm_binary_name as String,
coreutils_rm_empty_directory_flag as String,
path,
]
}

fn coreutils_rm_force_recursive_argv(path: String) -> List<String> {
[
coreutils_rm_binary_name as String,
coreutils_rm_force_recursive_flags as String,
path,
]
}
18 changes: 3 additions & 15 deletions dag/gunbc/host_axis_caps.dag
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,10 @@ import std.measure { byte_size_count }
import v2.extdeps.languages.bash_build {
bash_build_command_with_words,
bash_build_with_redir_to_file,
bash_build_word_concat_from_nodes,
bash_build_word_lit,
bash_build_word_var,
}
import v2.std.node { Node }
import gunbc.live_deploy.operations { deploy_stage_path_word }
import gunbc.shell_command_text {
shell_command_intent,
shell_literal_words,
Expand Down Expand Up @@ -292,27 +291,16 @@ fn runner_slot_service_units_for_host(host: HostIdentity) -> List<NonEmptyStr> {
)
}

// The staged path is a WORD, not a spelled-out quotation: variable reference and literal
// suffix are two parts of one concat word, so nothing here decides how "$_gunbc_stage" is
// quoted — the grammar does, at both the redirection target and the install argument, from
// the same word.
fn deploy_cap_stage_path_word(stage_name: String) -> Node {
bash_build_word_concat_from_nodes(parts: [
bash_build_word_var(name: "_gunbc_stage"),
bash_build_word_lit(text: concat("/", stage_name)),
])
}

fn deploy_cap_upsert_staged_stmts(m: CapMember, stage_name: String) -> List<Node> {
[
cap_write_content_intent(
content: m.content,
path: deploy_cap_stage_path_word(stage_name: stage_name),
path: deploy_stage_path_word(stage_name: stage_name),
),
bash_build_command_with_words(words: concat(
shell_literal_words(words: ["sudo", "-n", "install", "-m", "0644"]),
[
deploy_cap_stage_path_word(stage_name: stage_name),
deploy_stage_path_word(stage_name: stage_name),
bash_build_word_lit(text: m.dropin_path as String),
],
)),
Expand Down
Loading
Loading