From 0fc39391cd7b5a5f0b362bed6c21e4c642a0accc Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Fri, 22 Mar 2013 11:11:02 +0200 Subject: Add --changelog{,-in,-out,-dir} options --- odb/generator.cxx | 63 +++++++++++++++++++++++++++++++++++--------- odb/options.cli | 38 ++++++++++++++++++++++++++ odb/relational/changelog.cxx | 21 ++++++++------- odb/relational/generate.hxx | 3 ++- odb/validator.cxx | 9 +++++++ 5 files changed, 110 insertions(+), 24 deletions(-) diff --git a/odb/generator.cxx b/odb/generator.cxx index a2254e0..dfc5ba6 100644 --- a/odb/generator.cxx +++ b/odb/generator.cxx @@ -129,15 +129,12 @@ generate (options const& ops, string cxx_name (base + ops.odb_file_suffix ()[db] + ops.cxx_suffix ()); string sch_name (base + ops.schema_file_suffix ()[db] + ops.cxx_suffix ()); string sql_name (base + ops.sql_file_suffix ()[db] + ops.sql_suffix ()); - string log_name (base + ops.changelog_file_suffix ()[db] + - ops.changelog_suffix ()); path hxx_path (hxx_name); path ixx_path (ixx_name); path cxx_path (cxx_name); path sch_path (sch_name); path sql_path (sql_name); - path log_path (p.directory () / path (log_name)); // Input directory. if (!ops.output_dir ().empty ()) { @@ -149,6 +146,45 @@ generate (options const& ops, sql_path = dir / sql_path; } + path in_log_path, out_log_path; + path log_dir (ops.changelog_dir ().empty () ? "" : ops.changelog_dir ()); + if (ops.changelog_in_specified ()) + { + in_log_path = path (ops.changelog_in ()); + out_log_path = path (ops.changelog_out ()); + + if (!log_dir.empty ()) + { + if (!in_log_path.absolute ()) + in_log_path = log_dir / in_log_path; + + if (!out_log_path.absolute ()) + out_log_path = log_dir / out_log_path; + } + } + else if (ops.changelog_specified ()) + { + in_log_path = path (ops.changelog ()); + + if (!in_log_path.absolute () && !log_dir.empty ()) + in_log_path = log_dir / in_log_path; + + out_log_path = in_log_path; + } + else + { + string log_name (base + ops.changelog_file_suffix ()[db] + + ops.changelog_suffix ()); + in_log_path = path (log_name); + + if (!log_dir.empty ()) + in_log_path = log_dir / in_log_path; + else + in_log_path = p.directory () / in_log_path; // Use input directory. + + out_log_path = in_log_path; + } + // Load the old changelog and generate a new one. // bool gen_log (gen_schema && unit.count ("model-version") != 0); @@ -158,7 +194,7 @@ generate (options const& ops, if (gen_log) { - ifstream log (log_path.string ().c_str (), + ifstream log (in_log_path.string ().c_str (), ios_base::in | ios_base::binary); if (log.is_open ()) @@ -187,13 +223,13 @@ generate (options const& ops, istringstream is (old_changelog_xml); is.exceptions (ios_base::badbit | ios_base::failbit); - xml::parser p (is, log_path.string ()); + xml::parser p (is, in_log_path.string ()); old_changelog.reset ( new (shared) semantics::relational::changelog (p)); } catch (const ios_base::failure& e) { - cerr << log_path << ": read failure" << endl; + cerr << in_log_path << ": read failure" << endl; throw failed (); } catch (const xml::parsing& e) @@ -207,7 +243,8 @@ generate (options const& ops, *model, unit.get ("model-version"), old_changelog.get (), - log_path.string ()); + in_log_path.string (), + out_log_path.string ()); } // @@ -841,24 +878,24 @@ generate (options const& ops, { ostringstream os; os.exceptions (ifstream::badbit | ifstream::failbit); - xml::serializer s (os, log_path.string ()); + xml::serializer s (os, out_log_path.string ()); changelog->serialize (s); string const& changelog_xml (os.str ()); if (changelog_xml != old_changelog_xml) { - ofstream log (log_path.string ().c_str (), + ofstream log (out_log_path.string ().c_str (), ios_base::out | ios_base::binary); if (!log.is_open ()) { - cerr << "error: unable to open '" << log_path << "' in write mode" - << endl; + cerr << "error: unable to open '" << out_log_path << "' in " << + "write mode" << endl; throw failed (); } if (old_changelog == 0) - auto_rm.add (log_path); + auto_rm.add (out_log_path); log.exceptions (ifstream::badbit | ifstream::failbit); log << changelog_xml; @@ -866,7 +903,7 @@ generate (options const& ops, } catch (const ios_base::failure& e) { - cerr << log_path << ": write failure" << endl; + cerr << out_log_path << ": write failure" << endl; throw failed (); } catch (const xml::serialization& e) diff --git a/odb/options.cli b/odb/options.cli index 45d2305..fcacbd3 100644 --- a/odb/options.cli +++ b/odb/options.cli @@ -283,6 +283,44 @@ class options generated files." }; + std::string --changelog + { + "", + "Read/write changelog from/to instead of the default changelog + file. The default changelog file name is derived from the input file + name and it is placed into the same directory as the input file. Note + that the \cb{--output-name} option does not affect the changelog file + location. In other words, by default, the changelog file is treated + as another input rather than output even though the ODB compiler may + modify it. Use the \cb{--changelog-in} and \cb{--changelog-out} + options to specify different input and output chaneglog files." + }; + + std::string --changelog-in + { + "", + "Read changelog from instead of the default changelog file. If + this option is specified, then you must also specify the output + chanegelog file with \cb{--changelog-out}." + }; + + std::string --changelog-out + { + "", + "Write changelog to instead of the default changelog file. If + this option is specified, then you must also specify the input + chanegelog file with \cb{--changelog-in}." + }; + + std::string --changelog-dir + { + "", + "Use instead of the input file directory as the changelog file + directory. This directory is also added to changelog files specified + with the \cb{--changelog}, \cb{--changelog-in}, and \cb{--changelog-in} + options unless they are absolute paths." + }; + database_map --odb-file-suffix { "", diff --git a/odb/relational/changelog.cxx b/odb/relational/changelog.cxx index de5e6f7..7435f05 100644 --- a/odb/relational/changelog.cxx +++ b/odb/relational/changelog.cxx @@ -142,7 +142,8 @@ namespace relational generate (model& m, model_version const& mv, changelog* old, - string const& name) + std::string const& in_name, + std::string const& out_name) { cutl::shared_ptr cl (new (shared) changelog); graph& g (*cl); @@ -151,13 +152,13 @@ namespace relational { if (!mv.open) { - cerr << name << ": error: unable to initialize changelog because " << - "current version is closed" << endl; + cerr << out_name << ": error: unable to initialize changelog " << + "because current version is closed" << endl; throw operation_failed (); } - cerr << name << ": info: initializing changelog with base version " << - m.version () << endl; + cerr << out_name << ": info: initializing changelog with base " << + "version " << m.version () << endl; g.new_edge (*cl, g.new_node (m, g)); return cl; @@ -174,7 +175,7 @@ namespace relational if (mv.current < cver) { - cerr << name << ": error: latest changelog version is greater " << + cerr << in_name << ": error: latest changelog version is greater " << "than current version" << endl; throw operation_failed (); } @@ -199,8 +200,8 @@ namespace relational { qnames& n (*cs.names_begin ()); - cerr << name << ": error: current version is closed" << endl; - cerr << name << ": info: first new change is " << + cerr << out_name << ": error: current version is closed" << endl; + cerr << out_name << ": info: first new change is " << n.nameable ().kind () << " '" << n.name () << "'" << endl; throw operation_failed (); @@ -242,8 +243,8 @@ namespace relational { qnames& n (*cs.names_begin ()); - cerr << name << ": error: current version is closed" << endl; - cerr << name << ": info: first new change is " << + cerr << out_name << ": error: current version is closed" << endl; + cerr << out_name << ": info: first new change is " << n.nameable ().kind () << " '" << n.name () << "'" << endl; throw operation_failed (); diff --git a/odb/relational/generate.hxx b/odb/relational/generate.hxx index e5dc376..a50b999 100644 --- a/odb/relational/generate.hxx +++ b/odb/relational/generate.hxx @@ -52,7 +52,8 @@ namespace relational generate (semantics::relational::model&, model_version const&, semantics::relational::changelog* old, // Can be NULL. - std::string const& name); + std::string const& in_name, + std::string const& out_name); } namespace schema diff --git a/odb/validator.cxx b/odb/validator.cxx index 77ad874..57cca4a 100644 --- a/odb/validator.cxx +++ b/odb/validator.cxx @@ -994,6 +994,15 @@ validate (options const& ops, valid = false; } + // Changelog options. + // + if (ops.changelog_in_specified () != ops.changelog_out_specified ()) + { + cerr << "error: both --changelog-in and --changelog-out must be " << + "specified" << endl; + valid = false; + } + if (!valid) throw failed (); -- cgit v1.1