1 /* cmd-sync-tree.c:
2  *
3  ****************************************************************
4  * Copyright (C) 2003 Tom Lord
5  *
6  * See the file "COPYING" for further information about
7  * the copyright and warranty status of this work.
8  */
9 
10 
11 
12 
13 #include "config-options.h"
14 #include "hackerlab/cmd/main.h"
15 #include "hackerlab/fs/file-names.h"
16 #include "hackerlab/fs/cwd.h"
17 #include "hackerlab/vu/vu-dash.h"
18 #include "tla/libfsutils/tmp-files.h"
19 #include "tla/libfsutils/rmrf.h"
20 #include "tla/libfsutils/copy-file.h"
21 #include "tla/libfsutils/dir-as-cwd.h"
22 #include "tla/libarch/namespace.h"
23 #include "tla/libarch/project-tree.h"
24 #include "tla/libarch/my.h"
25 #include "tla/libarch/copy-project-tree.h"
26 #include "tla/libarch/sync-tree.h"
27 #include "tla/libarch/chatter.h"
28 #include "tla/libarch/cmd.h"
29 #include "tla/libarch/cmdutils.h"
30 #include "tla/libarch/cmd-sync-tree.h"
31 
32 
33 
34 static t_uchar * usage = "[options] revision";
35 static t_uchar * version_string = (cfg__std__package " from regexps.com\n"
36                                    "\n"
37                                    "Copyright 2003 Tom Lord\n"
38                                    "\n"
39                                    "This is free software; see the source for copying conditions.\n"
40                                    "There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A\n"
41                                    "PARTICULAR PURPOSE.\n"
42                                    "\n"
43                                    "Report bugs to " cfg__tla_bug_mail ".\n"
44                                    "\n"
45                                    cfg__std__release_id_string
46                                    "\n");
47 
48 #define OPTS(OP) \
49   OP (opt_help_msg, "h", "help", 0, \
50       "Display a help message and exit.") \
51   OP (opt_long_help, "H", 0, 0, \
52       "Display a verbose help message and exit.") \
53   OP (opt_version, "V", "version", 0, \
54       "Display a release identifier string\n" \
55       "and exit.") \
56   OP (opt_archive, "A", "archive", 1, \
57       "Override `my-default-archive'") \
58   OP (opt_dir, "d", "dir DIR", 1, \
59       "Operate on project tree in DIR (default `.')") \
60   OP (opt_dest, 0, "dest DEST", 1, \
61       "Instead of modifying the project tree in-place,\n" \
62       "make a copy of it to DEST and apply the result to that") \
63   OP (opt_unescaped, 0, "unescaped", 0, \
64       "show filenames in unescaped form")
65 
66 
67 t_uchar arch_cmd_sync_tree_help[] = ("unify a project tree's patch-log with a given revision\n"
68 
69                                      "The new project tree is formed by getting the REVISION and adding all\n"
70                                      "patch-log entries from REVISION.  No actual merging is performed --\n"
71                                      "only the patch-log is changed.\n");
72 
73 enum options
74 {
75   OPTS (OPT_ENUM)
76 };
77 
78 static struct opt_desc opts[] =
79 {
80   OPTS (OPT_DESC)
81     {-1, 0, 0, 0, 0}
82 };
83 
84 
85 
86 int
arch_cmd_sync_tree(t_uchar * program_name,int argc,char * argv[])87 arch_cmd_sync_tree (t_uchar * program_name, int argc, char * argv[])
88 {
89   int o;
90   struct opt_parsed * option;
91   t_uchar * default_archive = 0;
92   t_uchar * upon = 0;
93   t_uchar * dest = 0;
94   int escape_classes = arch_escape_classes;
95 
96   safe_buffer_fd (1, 0, O_WRONLY, 0);
97 
98   option = 0;
99 
100   while (1)
101     {
102       o = opt_standard (lim_use_must_malloc, &option, opts, &argc, argv, program_name, usage, version_string, arch_cmd_sync_tree_help, opt_help_msg, opt_long_help, opt_version);
103       if (o == opt_none)
104         break;
105       switch (o)
106         {
107         default:
108           safe_printfmt (2, "unhandled option `%s'\n", option->opt_string);
109           panic ("internal error parsing arguments");
110 
111         usage_error:
112           opt_usage (2, argv[0], program_name, usage, 1);
113           exit (1);
114 
115           /* bogus_arg: */
116           safe_printfmt (2, "ill-formed argument for `%s' (`%s')\n", option->opt_string, option->arg_string);
117           goto usage_error;
118 
119         case opt_archive:
120           {
121             lim_free (0, default_archive);
122             default_archive = str_save (0, option->arg_string);
123             break;
124           }
125 
126         case opt_dir:
127           {
128             lim_free (0, upon);
129             upon = str_save (0, option->arg_string);
130             break;
131           }
132 
133         case opt_dest:
134           {
135             lim_free (0, dest);
136             dest = str_save (0, option->arg_string);
137             break;
138           }
139 
140 	case opt_unescaped:
141 	  {
142 	    escape_classes = 0;
143 	    break;
144 	  }
145         }
146     }
147 
148   if (argc != 2)
149     goto usage_error;
150 
151   if (default_archive && !arch_valid_archive_name (default_archive))
152     {
153       safe_printfmt (2, "%s: invalid archive name (%s)\n",
154                      argv[0], default_archive);
155       exit (1);
156     }
157 
158   {
159     t_uchar * revspec = 0;
160     t_uchar * upon_root = 0;
161     t_uchar * archive = 0;
162     struct arch_archive * arch = 0;
163     t_uchar * revision = 0;
164 
165     revspec = argv[1];
166 
167     upon_root = arch_tree_root (0, upon, 0);
168 
169     if (!upon_root)
170       {
171         safe_printfmt (2, "%s: dir not in a project tree (%s)\n",
172                        argv[0], upon);
173         exit (1);
174       }
175 
176     revision = arch_determine_revision (&arch, default_archive, revspec, argv[0]);
177     archive = str_save (0, arch->name);
178 
179     arch_chatter (1, "* making sync tree with %s\n", revision);
180     if (dest)
181       arch_chatter (1, "** source %s\n** dest %s\n", upon_root, dest);
182     else
183       arch_chatter (1, "** directory %s\n", upon_root);
184 
185     if (dest)
186       {
187         safe_printfmt (1, "* copying %s to %s\n", upon_root, dest);
188         safe_flush (1);
189         arch_copy_project_tree (upon_root, dest, 1, 1);
190       }
191     else
192       dest = str_save (0, upon_root);
193 
194     arch_sync_tree (1, dest, arch, archive, revision);
195 
196     lim_free (0, upon_root);
197     lim_free (0, archive);
198     arch_archive_close (arch);
199     lim_free (0, revision);
200   }
201 
202   lim_free (0, upon);
203   lim_free (0, dest);
204   lim_free (0, default_archive);
205 
206   return 0;
207 }
208 
209 
210 
211 
212 /* tag: Tom Lord Tue Jun 17 16:02:09 2003 (cmd-sync-tree.c)
213  */
214