updated mig export to use xml and mig import supports libraries and preferences
[migration-tools.git] / kmig
1 #!/usr/bin/perl -w
2 ###############################################################################
3 =pod
4
5 =head1 NAME
6
7 mig - git-like program for tracking and manipulating legacy data files for
8 migrations. This variant of <mig> and is geared toward the Koha ILS and
9 MySql/MariaDB.
10
11 =head1 SYNOPSIS
12
13 B<mig> <command> [argument] [...]
14
15 =head1 DESCRIPTION
16
17 B<mig> is used to track and manipulate CSV or CSV-like text files exported from
18 legacy systems for migration into Evergreen.  It can be a wrapper for some
19 other migration tools and tracks state using a MySQL table for a given
20 database.
21
22 For most commands, if the current working directory falls outside of the
23 directory specified by MIGWORKDIR, then mig will assume that environment is
24 also incorrect and bail before doing any actual work.
25
26 Only the B<env> and B<help> commands work without the MIGDATABASE environment
27 variable being set.
28
29 =head1 OVERVIEW
30
31 Using B<mig> should go something like this:
32
33 =over 15
34
35 =item mig env create m_foo # Sets up the environment
36
37 =item mig env use m_foo # Spawns a shell using the configured environment
38
39 =item mig init # creates any needed auxilary tables
40
41 =item mig add patrons.tsv # tracks an incoming data file; repeat for additional files
42
43 =item mig iconv patrons.tsv # convert it to UTF8, creating patrons.tsv.utf8
44
45 =item mig clean patrons.tsv # cleans the file, creating patrons.tsv.utf8.clean
46
47 =item mig link patrons.tsv borrowers # models the soon-to-be staging table after table 'borrowers'
48
49 =item mig convert patrons.tsv # creates a .sql file for staging the data
50
51 =item mig export foo # exports koha setup elements for importing elsewhere 
52
53 =item mig stage patrons.tsv # load said .sql file
54
55 =item mig mapper patrons.tsv # interactive tool for analyzing/mapping the staging table
56
57 =item mig analysis patrons.tsv # writes a summary .tsv file of mapped/flagged fields from the staging table
58
59 =item mig map patrons.tsv # apply configured mappings
60
61 =item mig write_prod patrons.tsv # creates a .sql file for pushing the staging data into production
62
63 =item mig reporter --analyst "Foo Fooer" --report_title "Foo Load Analysis" #creates an asciidoc report
64
65 =item mig gsheet --pull foo_tab_name OR --push foo_pg_table_name 
66
67 =item mig stagebibs --file foo.xml 
68
69 =back
70
71 =head1 COMMANDS
72
73 =over 15
74
75 =item B<help> [command]
76
77 Display this very same documentation, or specific documentation for one of the
78 commands listed here.
79
80 =item B<env> <create|use|show> <schema>
81
82 Invokes B<mig-env> with the same arguments.  I<mig-env> can set important
83 environment variables and spawn a shell with those variables, and it also does
84 some directory creation and symlinking.
85
86 =item B<init>
87
88 Create or re-create the PostgreSQL tracking table for the schema specified by
89 the MIGDATABASE environment variable.  If needed, create the migration schema
90 itself and run migration_tools.init() and build() if the migration_tools schema
91 exists.
92
93 =item B<status> [file] [...]
94
95 Show status information for either the specified files or all tracked files if
96 no argument is given.
97
98 =item B<add> [--no-headers|--headers] <file> [file|--no-headers|--headers] [...]
99
100 Add the specified files to the migration tracker.  Until --no-headers is
101 specified, the tracker will assume the files have headers.
102
103 You can do crazy stuff like
104 B<mig add file1 --no-headers file2 file3 --headers file4>
105
106 =item B<remove> <file> [file] [...]
107
108 Remove the specified files from the migration tracker.
109
110 =item B<iconv> <file> [other arguments...]
111
112 Attempts to invoke B<iconv> on the specified tracked file, placing the output in
113 <file>.utf8
114
115 If given no other arguments, the invocation will lool like
116
117 =over 5
118
119 iconv -f ISO-8859-1 -t UTF-8 -o <file>.utf8 <file>
120
121 =back
122
123 otherwise, the arguments will be passed through like so
124
125 =over 5
126
127 iconv [other arguments...] -o <file>.utf8 <file>
128
129 =back
130
131 =item B<skip-iconv> <file>
132
133 If this is used instead of B<iconv>, then B<mig> will look for an existing
134 <file>.utf8 and use it instead of attempting to create one.
135
136 =item B<clean> <file> [other arguments...]
137
138 Attempts to invoke B<clean_csv> on the iconv-converted specified tracked file,
139 placing the output in <file>.utf8.clean
140
141 If given no other arguments, the invocation will lool like
142
143 =over 5
144
145 clean_csv --config scripts/clean.conf --fix --apply <--create-headers> <file>
146
147 =back
148
149 otherwise, the arguments will be passed through like so
150
151 =over 5
152
153 clean_csv [other arguments...] <file>
154
155 =back
156
157 =item B<skip-clean> <file>
158
159 If this is used instead of B<clean>, then B<mig> will look for an existing
160 <file>.utf8.clean and use it instead of attempting to create one.
161
162 =item B<link> <file> <parent table>
163
164 Associate the specified file with a parent table within the migration schema.
165
166 Linking multiple files to the same parent table is not allowed currently.
167
168 =item B<unlink> <file>
169
170 Removes any association between the specified file and a parent table within
171 the migration schema.
172
173 =item B<convert> <file>
174
175 Attempts to invoke B<csv2sql> on the .utf8.clean version of the specified
176 tracked file, creating either [file].utf8.clean.stage.sql or
177 <parent table>_stage.sql depending on whether the file has been linked to a
178 parent table within the migration schema or not.
179
180 If given no other arguments, the invocation will lool like
181
182 =over 5
183
184 csv2sql --config scripts/clean.conf --add-x-migrate --schema <MIGDATABASE> [--parent <PARENT TABLE>] -o <[<file>.utf8.clean.stage.sql]|[parent_table_stage.sql]> <FILE>.utf8.clean
185
186 =back
187
188 otherwise, the arguments will be passed through like so
189
190 =over 5
191
192 csv2sql [other arguments...] -o <[<file>.utf8.clean.stage.sql]|[parent_table_stage.sql]> <file>.utf8.clean
193
194 =back
195
196 =item B<stage> <file> [other arguments...]
197
198 Load the SQL-converted version of the specified file into the migration schema.
199
200 Extra arguments are passed to the underlying call to psql
201
202 =item B<mapper> <file>
203
204 Interactive session for analyzing, flagging, and mapping legacy field data to
205 Evergreen fields.
206
207 Upon exit, generate either [file].clean.map.sql or <parent table>_map.sql. The
208 SQL generated will be UPDATE's for setting the Evergreen-specific columns for a
209 given file's staging tables, and TRUNCATE's and INSERT's for auxilary tables.
210 The files will have \include hooks for pulling in additional mapping files
211 (for example, end-user mappings for circ modifiers, etc.)
212
213 =item B<analysis> [file]
214
215 Writes a MIGDATABASE.tsv file containing a break-down of mapped and flagged
216 fields from the specified file, or all staged files if no file is specified.
217
218 The main goal of the tsv file is to present end-user mappable data for circ
219 modifiers, shelving locations, patron profiles, etc.  We use spreadsheets for
220 this now but may move to a dedicated UI in the future.
221
222 =item B<map> [file]
223
224 Applies the mapping sql to the migration schema for the specified mapped file,
225 or for all mapped files if no file is specified.
226
227 =item B<write_prod> [file]
228
229 Generates <parent table>_prod.sql for the specified linked and mapped file, or
230 all such files if no file is specified.
231
232 =item B<sql> [arguments...]
233
234 A wrapper around the psql command.  At some point the plan is to shove mig-tracked variables into psql sessions.
235
236 =item B<reporter> --analyst "Analyst Name" --report_title "Report Title"
237
238 Generates an asciidoc file in the git working directory that can be converted to 
239 any appropriate format.  The analyst and report parameters are required.
240
241 Optional parameters are : 
242
243 --added_page_title and --added_page_file 
244
245 If one is used both must be.  The added page file can be plain text or asciidoc.  This
246 adds an extra arbitrary page of notes to the report.  KMig assumes the page file is in the mig git directory.
247
248 --tags
249
250 This will define a set of tags to use, if not set it will default to Circs, 
251 Holds, Actors, Bibs, Assets & Money. 
252
253 --debug
254
255 Gives more information about what is happening.
256
257 --reports_xml 
258
259 Allows you to override the default evergreen_staged_report.xml in the mig-xml folder.
260
261 =item B<gsheet> --pull or --push spreadsheet_tab
262
263 This uses the gsheet_tracked_table and gsheet_tracked column tables to map a Google Docs Spreadsheet tabs
264 with Postgres tables in the mig schema.  The spreadsheet is assumed to share the name as the mig schema. 
265 Tab names must be unique.  Each spreadsheet column needs a header that matches the column name in the matching 
266 table.  An oauth session key is also needed for your Google account and mig gsheet will look for it in the 
267 .mig directory.
268
269 =back
270
271 =cut
272
273 ###############################################################################
274
275 use strict;
276 use Switch;
277 use Env qw(
278     HOME PGHOST PGPORT PGUSER PGDATABASE MIGDATABASE
279     MIGBASEWORKDIR MIGBASEGITDIR MIGGITDIR MIGWORKDIR
280 );
281 use Pod::Usage;
282 use FindBin;
283 my $mig_bin = "$FindBin::Bin/kmig.d/bin/";
284 use lib "$FindBin::Bin/kmig.d/bin";
285 use KMig;
286
287 pod2usage(-verbose => 2) if ! $ARGV[0];
288 switch($ARGV[0]) {
289     case "help" {
290         if (defined $ARGV[1]) {
291             my $cmd = $mig_bin . "mig-$ARGV[1]";
292             if (-e $cmd) {
293                 system( $mig_bin . "mig-$ARGV[1]", '--help' );
294             } else {
295                 pod2usage(-verbose => 2);
296             }
297         } else {
298             pod2usage(-verbose => 2);
299         }
300     }
301     case "map" {
302     }
303     case "load" {
304     }
305     case "wdir" {
306         print "$MIGWORKDIR\n";
307     }
308     case "gdir" {
309         print "$MIGBASEGITDIR\n";
310     }
311     case "sdir" {
312         print "$MIGGITDIR\n";
313     }
314     else {
315         standard_invocation(@ARGV);
316     }
317 }
318
319 sub standard_invocation {
320     my $cmd = shift;
321
322     if ($cmd ne 'env') { KMig::die_if_no_env_migschema(); }
323     if (-e $mig_bin . "mig-$cmd") {
324         system( $mig_bin . "mig-$cmd", @_ );
325     } else {
326         system( "mig-$cmd", @_ ) == 0 or die pod2usage(1);
327     }
328 }
329
330