From c35c364327c2e594935c4a0f379209e59239bbb7 Mon Sep 17 00:00:00 2001 From: Bojidar Marinov Date: Sat, 16 Mar 2024 15:45:01 +0200 Subject: [PATCH] Update gitignore when switching subdirectories between normal and generated Fixes #491. --- src/tup/create_name_file.c | 11 +++++ src/tup/parser.c | 9 ++-- src/tup/parser.h | 1 + src/tup/updater.c | 33 +++++++++----- ...4-gitignore-updated-generated-to-normal.sh | 41 +++++++++++++++++ ...5-gitignore-updated-normal-to-generated.sh | 44 +++++++++++++++++++ 6 files changed, 123 insertions(+), 16 deletions(-) create mode 100755 test/t2244-gitignore-updated-generated-to-normal.sh create mode 100755 test/t2245-gitignore-updated-normal-to-generated.sh diff --git a/src/tup/create_name_file.c b/src/tup/create_name_file.c index ca3047847..b43b2f464 100644 --- a/src/tup/create_name_file.c +++ b/src/tup/create_name_file.c @@ -80,6 +80,17 @@ int make_dirs_normal(struct tup_entry *dtent) tup_db_del_ghost_tree(dtent); dtent = dtent->parent; } + if(dtent) { + /* Mark normal parent as needing update + * to regenerate gitignore (t2244) + */ + struct tup_entry *gitignore_tent; + if(tup_db_select_tent(dtent, ".gitignore", &gitignore_tent) < 0) + return -1; + if(gitignore_tent && gitignore_tent->type == TUP_NODE_GENERATED) { + tup_db_add_create_list(gitignore_tent->dt); + } + } return 0; } diff --git a/src/tup/parser.c b/src/tup/parser.c index a185f7c95..44aeacba7 100644 --- a/src/tup/parser.c +++ b/src/tup/parser.c @@ -90,7 +90,6 @@ static int eval_eq(struct tupfile *tf, char *expr, char *eol); static int error_directive(struct tupfile *tf, char *cmdline); static int preload(struct tupfile *tf, char *cmdline); static int run_script(struct tupfile *tf, char *cmdline, int lno); -static int remove_tup_gitignore(struct tupfile *tf, struct tup_entry *tent); static int gitignore(struct tupfile *tf, struct tup_entry *dtent); static int check_toplevel_gitignore(struct tupfile *tf); static int parse_rule(struct tupfile *tf, char *p, int lno); @@ -313,7 +312,7 @@ int parse(struct node *n, struct graph *g, struct timespan *retts, int refactori fprintf(tf.f, "tup refactoring error: Attempting to remove the .gitignore file.\n"); goto out_free_bs; } - if(remove_tup_gitignore(&tf, tent) < 0) + if(remove_tup_gitignore(tf.g, tent) < 0) goto out_free_bs; } } @@ -1130,7 +1129,7 @@ int import(struct tupfile *tf, const char *cmdline, const char **retvar, const c /* If a .gitignore directive is removed, we need to either revert back to the * user's explicit .gitignore file, or remove it entirely. */ -static int remove_tup_gitignore(struct tupfile *tf, struct tup_entry *tent) +int remove_tup_gitignore(struct graph *g, struct tup_entry *tent) { int dfd; int fdold; @@ -1207,8 +1206,8 @@ static int remove_tup_gitignore(struct tupfile *tf, struct tup_entry *tent) return -1; if(tup_db_set_srcid(tent, -1) < 0) return -1; - tent_tree_remove(&tf->g->gen_delete_root, tent); - tent_tree_remove(&tf->g->save_root, tent); + tent_tree_remove(&g->gen_delete_root, tent); + tent_tree_remove(&g->save_root, tent); } else { if(unlinkat(dfd, ".gitignore.new", 0) < 0) { perror("unlinkat"); diff --git a/src/tup/parser.h b/src/tup/parser.h index 6386fe44c..26ecd2a1e 100644 --- a/src/tup/parser.h +++ b/src/tup/parser.h @@ -175,6 +175,7 @@ void init_rule(struct rule *r); int execute_rule(struct tupfile *tf, struct rule *r, struct name_list *output_nl); int parser_include_file(struct tupfile *tf, const char *file); int parser_include_rules(struct tupfile *tf, const char *tuprules); +int remove_tup_gitignore(struct graph *g, struct tup_entry *tent); // HACK struct node; struct graph; diff --git a/src/tup/updater.c b/src/tup/updater.c index 2756ee0a0..4c4417aa8 100644 --- a/src/tup/updater.c +++ b/src/tup/updater.c @@ -1529,17 +1529,6 @@ static int process_create_nodes(void) tup_lua_parser_cleanup(); if(rc == 0) { - if(g.gen_delete_root.count) { - tup_main_progress("Deleting files...\n"); - } else { - tup_main_progress("No files to delete.\n"); - } - rc = delete_files(&g); - if(rc == 0 && group_need_circ_check()) { - tup_show_message("Checking circular dependencies among groups...\n"); - if(group_circ_check() < 0) - rc = -1; - } if(rc == 0 && !RB_EMPTY(&g.normal_dir_root)) { int msg_shown = 0; while(!RB_EMPTY(&g.normal_dir_root)) { @@ -1569,9 +1558,31 @@ static int process_create_nodes(void) */ if(tent_tree_add_dup(&g.parse_gitignore_root, tent->parent) < 0) return -1; + /* And remove extra gitignore file in + * the generated folder (t2245) + */ + struct tup_entry *gitignore_tent; + if(tup_db_select_tent(tent, ".gitignore", &gitignore_tent) < 0) + return -1; + if(gitignore_tent && gitignore_tent->type == TUP_NODE_GENERATED) { + tent_tree_add(&g.gen_delete_root, gitignore_tent); + if(remove_tup_gitignore(&g, gitignore_tent) < 0) + return -1; + } } } } + if(g.gen_delete_root.count) { + tup_main_progress("Deleting files...\n"); + } else { + tup_main_progress("No files to delete.\n"); + } + rc = delete_files(&g); + if(rc == 0 && group_need_circ_check()) { + tup_show_message("Checking circular dependencies among groups...\n"); + if(group_circ_check() < 0) + rc = -1; + } if(rc == 0 && !RB_EMPTY(&g.parse_gitignore_root) && !refactoring) { tup_show_message("Generating .gitignore files...\n"); RB_FOREACH(tt, tent_entries, &g.parse_gitignore_root) { diff --git a/test/t2244-gitignore-updated-generated-to-normal.sh b/test/t2244-gitignore-updated-generated-to-normal.sh new file mode 100755 index 000000000..2b31a70f2 --- /dev/null +++ b/test/t2244-gitignore-updated-generated-to-normal.sh @@ -0,0 +1,41 @@ +#! /bin/sh -e +# tup - A file-based build system +# +# Copyright (C) 2024 Bojidar Marinov +# +# 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. + +# Make sure importing with a default value works when the environment variable +# is set the first time tup is called. + +. ./tup.sh + +cat > Tupfile < touch %o |> out/generated.txt +HERE +cat > Tupdefault < +# +# 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. + +# Make sure importing with a default value works when the environment variable +# is set the first time tup is called. + +. ./tup.sh + +cat > Tupfile < touch %o |> out/generated.txt +HERE +cat > Tupdefault <