diff --git a/src/tup/create_name_file.c b/src/tup/create_name_file.c index 9260bf14..937afb11 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/src/tup/db.c b/src/tup/db.c index 4c99b2ce..7ebd2ce5 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; diff --git a/test/t5123-ignore-output-ghost-dir.sh b/test/t5123-ignore-output-ghost-dir.sh new file mode 100755 index 00000000..632edc84 --- /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 00000000..eb50161f --- /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 00000000..599a85d3 --- /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