From f7f6a31c63a60b7fda17326b69a5d0b647abc053 Mon Sep 17 00:00:00 2001 From: Jan Pedersen Date: Mon, 2 Feb 2026 12:19:19 +0100 Subject: [PATCH 1/2] cleanup nested auto generated variant directories --- src/tup/db.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tup/db.c b/src/tup/db.c index 4c99b2ce4..7ebd2ce5c 100644 --- a/src/tup/db.c +++ b/src/tup/db.c @@ -1732,7 +1732,7 @@ static int delete_variant_dir(struct tup_entry *tent, void *arg, int (*callback) if(tup_entry_add(he->tupid, &subtent) < 0) return -1; - if(he->type == TUP_NODE_DIR) { + if(he->type == TUP_NODE_DIR || he->type == TUP_NODE_GENERATED_DIR) { flags = AT_REMOVEDIR; if(delete_variant_dir(subtent, arg, callback) < 0) return -1; From 96241e58f9c14cf871e4f1412e470191bf8ebdd7 Mon Sep 17 00:00:00 2001 From: Jan Pedersen Date: Fri, 9 Oct 2026 09:14:34 +0200 Subject: [PATCH 2/2] Fix excluded writes beneath ghost directories. Add tests --- src/tup/create_name_file.c | 9 +++ test/t5123-ignore-output-ghost-dir.sh | 55 ++++++++++++++++++ ...t5124-ignore-output-ghost-dir-signalled.sh | 56 +++++++++++++++++++ test/t8120-variant-remove-generated-dirs.sh | 44 +++++++++++++++ 4 files changed, 164 insertions(+) create mode 100755 test/t5123-ignore-output-ghost-dir.sh create mode 100755 test/t5124-ignore-output-ghost-dir-signalled.sh create mode 100755 test/t8120-variant-remove-generated-dirs.sh diff --git a/src/tup/create_name_file.c b/src/tup/create_name_file.c index 9260bf141..937afb118 100644 --- a/src/tup/create_name_file.c +++ b/src/tup/create_name_file.c @@ -632,6 +632,15 @@ tupid_t find_dir_tupid_dt_pg(tupid_t dt, struct pel_group *pg, fprintf(stderr, "' is a %s\n", tup_db_type(tent->type)); return -1; } + } else if(sotgv == SOTGV_IGNORE_DIRS && !(pg->pg_flags & PG_OUTSIDE_TUP) && + tent->type == TUP_NODE_GHOST) { + /* Ignored files inside the project are normal files, + * so their ancestors must be normal directories even + * when a previous missing-path read created ghosts. + */ + if(tup_db_set_type(tent, TUP_NODE_DIR) < 0) + return -1; + tup_db_del_ghost_tree(tent); } } else { int type = TUP_NODE_GHOST; diff --git a/test/t5123-ignore-output-ghost-dir.sh b/test/t5123-ignore-output-ghost-dir.sh new file mode 100755 index 000000000..632edc840 --- /dev/null +++ b/test/t5123-ignore-output-ghost-dir.sh @@ -0,0 +1,55 @@ +#! /bin/sh -e +# tup - A file-based build system +# +# Copyright (C) 2026 Mike Shal +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +# An excluded write must convert existing ghost ancestors to normal directories, +# just as it does when those directory entries do not already exist. +. ./tup.sh + +cat > Tupfile << HERE +: |> sh run.sh |> stamp ^/temp_files/temporary.txt +HERE +cat > run.sh << HERE +cat temp_files/test 2>/dev/null || echo missing +touch stamp +HERE +update +tup_object_exist . temp_files + +cat > Tupfile << 'HERE' +: |> sh run.sh |> stamp ^/temp_files(/(?!.*test$).*)?$ +HERE +cat > run.sh << HERE +mkdir -p temp_files/nested +echo ignored > temp_files/temporary.txt +echo ignored > temp_files/nested/temporary.txt +touch stamp +HERE +update +check_exist temp_files/temporary.txt +check_exist temp_files/nested/temporary.txt + +# The next scan used to load the normal file without its ghost parent and fail +# with "Unable to find parent entry". Check repeated scans and deletion too. +tup scan +update +rm -rf temp_files +tup scan +update +tup_object_no_exist . temp_files + +eotup diff --git a/test/t5124-ignore-output-ghost-dir-signalled.sh b/test/t5124-ignore-output-ghost-dir-signalled.sh new file mode 100755 index 000000000..eb50161f5 --- /dev/null +++ b/test/t5124-ignore-output-ghost-dir-signalled.sh @@ -0,0 +1,56 @@ +#! /bin/sh -e +# tup - A file-based build system +# +# Copyright (C) 2026 Mike Shal +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +# Interrupted commands also process excluded writes. They must not leave normal +# files beneath ghost directories and prevent the next scan from running. +. ./tup.sh +check_no_windows process + +cat > Tupfile << HERE +: |> exec sh run.sh |> stamp ^/temp_files/temporary.txt +HERE +cat > run.sh << HERE +cat temp_files/test 2>/dev/null || echo missing +touch stamp +HERE +update +tup_object_exist . temp_files + +cat > Tupfile << 'HERE' +: |> exec sh run.sh |> stamp ^/temp_files(/(?!test$).*)?$ +HERE +cat > run.sh << 'HERE' +mkdir -p temp_files +echo ignored > temp_files/temporary.txt +kill -TERM $$ +HERE +update_fail_msg 'killed by signal 15' +tup scan + +# The interrupted command must remain pending, and a subsequent successful +# update must be able to complete without rebuilding the database. +cat > run.sh << HERE +mkdir -p temp_files +echo ignored > temp_files/temporary.txt +touch stamp +HERE +update +tup scan +update + +eotup diff --git a/test/t8120-variant-remove-generated-dirs.sh b/test/t8120-variant-remove-generated-dirs.sh new file mode 100755 index 000000000..599a85d37 --- /dev/null +++ b/test/t8120-variant-remove-generated-dirs.sh @@ -0,0 +1,44 @@ +#! /bin/sh -e +# tup - A file-based build system +# +# Copyright (C) 2026 Mike Shal +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as +# published by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program; if not, write to the Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +# Regression for 698ff025: removing a variant must recursively clean generated +# directories, not just directories copied from the source tree. +. ./tup.sh + +mkdir build +echo CONFIG_BUILD=y > build/tup.config +cat > Tupfile << HERE +ifeq (@(BUILD),y) +: |> echo generated > %o |> generated/nested/output.txt +endif +HERE +update +check_exist build/generated/nested/output.txt +tup_object_exist build/generated nested +tup_object_exist build/generated/nested output.txt + +# Leave the physical directories in place so delete_variant_dir() has to recurse +# into them. Removing the entire variant beforehand would miss this regression. +rm build/tup.config +update +check_not_exist build/generated +tup_object_no_exist build generated +tup scan +update + +eotup