public function testConflicted() { $table1 = harness_Native::table($this->data1); $table2 = harness_Native::table($this->data2); $table3 = harness_Native::table($this->data3b); $table4 = harness_Native::table($this->data4b); $flags = new coopy_CompareFlags(); $merger = new coopy_Merger($table1, $table2, $table3, $flags); $conflicts = $merger->apply(); $this->assertEquals($conflicts, 1, _hx_anonymous(array("fileName" => "MergeTest.hx", "lineNumber" => 64, "className" => "harness.MergeTest", "methodName" => "testConflicted"))); $this->assertEquals(coopy_SimpleTable::tableToString($table2), coopy_SimpleTable::tableToString($table4), _hx_anonymous(array("fileName" => "MergeTest.hx", "lineNumber" => 65, "className" => "harness.MergeTest", "methodName" => "testConflicted"))); }
public function run($args, $io = null) { if ($io === null) { $io = new coopy_TableIO(); } if ($io === null) { haxe_Log::trace("No system interface available", _hx_anonymous(array("fileName" => "Coopy.hx", "lineNumber" => 693, "className" => "coopy.Coopy", "methodName" => "run"))); return 1; } $this->init(); $this->io = $io; $more = true; $output = null; $inplace = false; $git = false; $this->flags = new coopy_CompareFlags(); $this->flags->always_show_header = true; while ($more) { $more = false; $_g1 = 0; $_g = $args->length; while ($_g1 < $_g) { $i = $_g1++; $tag = $args[$i]; if ($tag === "--output") { $more = true; $output = $args[$i + 1]; $args->splice($i, 2); break; } else { if ($tag === "--css") { $more = true; $this->fragment = true; $this->css_output = $args[$i + 1]; $args->splice($i, 2); break; } else { if ($tag === "--fragment") { $more = true; $this->fragment = true; $args->splice($i, 1); break; } else { if ($tag === "--plain") { $more = true; $this->pretty = false; $args->splice($i, 1); break; } else { if ($tag === "--all") { $more = true; $this->flags->show_unchanged = true; $this->flags->show_unchanged_columns = true; $args->splice($i, 1); break; } else { if ($tag === "--all-rows") { $more = true; $this->flags->show_unchanged = true; $args->splice($i, 1); break; } else { if ($tag === "--all-columns") { $more = true; $this->flags->show_unchanged_columns = true; $args->splice($i, 1); break; } else { if ($tag === "--act") { $more = true; if ($this->flags->acts === null) { $this->flags->acts = new haxe_ds_StringMap(); } $this->flags->acts->set($args[$i + 1], true); true; $args->splice($i, 2); break; } else { if ($tag === "--context") { $more = true; $context = Std::parseInt($args[$i + 1]); if ($context >= 0) { $this->flags->unchanged_context = $context; } $args->splice($i, 2); break; unset($context); } else { if ($tag === "--inplace") { $more = true; $inplace = true; $args->splice($i, 1); break; } else { if ($tag === "--git") { $more = true; $git = true; $args->splice($i, 1); break; } else { if ($tag === "--unordered") { $more = true; $this->flags->ordered = false; $this->flags->unchanged_context = 0; $this->order_set = true; $args->splice($i, 1); break; } else { if ($tag === "--ordered") { $more = true; $this->flags->ordered = true; $this->order_set = true; $args->splice($i, 1); break; } else { if ($tag === "--color") { $more = true; $this->flags->terminal_format = "ansi"; $args->splice($i, 1); break; } else { if ($tag === "--no-color") { $more = true; $this->flags->terminal_format = "plain"; $args->splice($i, 1); break; } else { if ($tag === "--input-format") { $more = true; $this->setFormat($args[$i + 1]); $args->splice($i, 2); break; } else { if ($tag === "--output-format") { $more = true; $this->output_format = $args[$i + 1]; $this->output_format_set = true; $args->splice($i, 2); break; } else { if ($tag === "--id") { $more = true; if ($this->flags->ids === null) { $this->flags->ids = new _hx_array(array()); } $this->flags->ids->push($args[$i + 1]); $args->splice($i, 2); break; } else { if ($tag === "--ignore") { $more = true; $this->flags->ignoreColumn($args[$i + 1]); $args->splice($i, 2); break; } else { if ($tag === "--index") { $more = true; $this->flags->always_show_order = true; $this->flags->never_show_order = false; $args->splice($i, 1); break; } else { if ($tag === "--www") { $more = true; $this->output_format = "www"; $this->output_format_set = true; $args->splice($i, 1); } else { if ($tag === "--table") { $more = true; $this->flags->addTable($args[$i + 1]); $args->splice($i, 2); break; } else { if ($tag === "-w" || $tag === "--ignore-whitespace") { $more = true; $this->flags->ignore_whitespace = true; $args->splice($i, 1); break; } else { if ($tag === "-i" || $tag === "--ignore-case") { $more = true; $this->flags->ignore_case = true; $args->splice($i, 1); break; } else { if ($tag === "--padding") { $more = true; $this->flags->padding_strategy = $args[$i + 1]; $args->splice($i, 2); break; } } } } } } } } } } } } } } } } } } } } } } } } } unset($tag, $i); } unset($_g1, $_g); } $cmd = $args[0]; if ($args->length < 2) { if ($cmd === "version") { $io->writeStdout(_hx_string_or_null(coopy_Coopy::$VERSION) . "\n"); return 0; } if ($cmd === "git") { $io->writeStdout("You can use daff to improve git's handling of csv files, by using it as a\ndiff driver (for showing what has changed) and as a merge driver (for merging\nchanges between multiple versions).\n"); $io->writeStdout("\n"); $io->writeStdout("Automatic setup\n"); $io->writeStdout("---------------\n\n"); $io->writeStdout("Run:\n"); $io->writeStdout(" daff git csv\n"); $io->writeStdout("\n"); $io->writeStdout("Manual setup\n"); $io->writeStdout("------------\n\n"); $io->writeStdout("Create and add a file called .gitattributes in the root directory of your\nrepository, containing:\n\n"); $io->writeStdout(" *.csv diff=daff-csv\n"); $io->writeStdout(" *.csv merge=daff-csv\n"); $io->writeStdout("\nCreate a file called .gitconfig in your home directory (or alternatively\nopen .git/config for a particular repository) and add:\n\n"); $io->writeStdout(" [diff \"daff-csv\"]\n"); $io->writeStdout(" command = daff diff --git\n"); $io->writeStderr("\n"); $io->writeStdout(" [merge \"daff-csv\"]\n"); $io->writeStdout(" name = daff tabular merge\n"); $io->writeStdout(" driver = daff merge --output %A %O %A %B\n\n"); $io->writeStderr("Make sure you can run daff from the command-line as just \"daff\" - if not,\nreplace \"daff\" in the driver and command lines above with the correct way\nto call it. Add --no-color if your terminal does not support ANSI colors."); $io->writeStderr("\n"); return 0; } $io->writeStderr("daff can produce and apply tabular diffs.\n"); $io->writeStderr("Call as:\n"); $io->writeStderr(" daff [--color] [--no-color] [--output OUTPUT.csv] a.csv b.csv\n"); $io->writeStderr(" daff [--output OUTPUT.html] a.csv b.csv\n"); $io->writeStderr(" daff [--output OUTPUT.csv] parent.csv a.csv b.csv\n"); $io->writeStderr(" daff [--output OUTPUT.ndjson] a.ndjson b.ndjson\n"); $io->writeStderr(" daff [--www] a.csv b.csv\n"); $io->writeStderr(" daff patch [--inplace] [--output OUTPUT.csv] a.csv patch.csv\n"); $io->writeStderr(" daff merge [--inplace] [--output OUTPUT.csv] parent.csv a.csv b.csv\n"); $io->writeStderr(" daff trim [--output OUTPUT.csv] source.csv\n"); $io->writeStderr(" daff render [--output OUTPUT.html] diff.csv\n"); $io->writeStderr(" daff copy in.csv out.tsv\n"); $io->writeStderr(" daff git\n"); $io->writeStderr(" daff version\n"); $io->writeStderr("\n"); $io->writeStderr("The --inplace option to patch and merge will result in modification of a.csv.\n"); $io->writeStderr("\n"); $io->writeStderr("If you need more control, here is the full list of flags:\n"); $io->writeStderr(" daff diff [--output OUTPUT.csv] [--context NUM] [--all] [--act ACT] a.csv b.csv\n"); $io->writeStderr(" --act ACT: show only a certain kind of change (update, insert, delete)\n"); $io->writeStderr(" --all: do not prune unchanged rows or columns\n"); $io->writeStderr(" --all-rows: do not prune unchanged rows\n"); $io->writeStderr(" --all-columns: do not prune unchanged columns\n"); $io->writeStderr(" --color: highlight changes with terminal colors (default in terminals)\n"); $io->writeStderr(" --context NUM: show NUM rows of context\n"); $io->writeStderr(" --id: specify column to use as primary key (repeat for multi-column key)\n"); $io->writeStderr(" --ignore: specify column to ignore completely (can repeat)\n"); $io->writeStderr(" --index: include row/columns numbers from original tables\n"); $io->writeStderr(" --input-format [csv|tsv|ssv|json]: set format to expect for input\n"); $io->writeStderr(" --no-color: make sure terminal colors are not used\n"); $io->writeStderr(" --ordered: assume row order is meaningful (default for CSV)\n"); $io->writeStderr(" --output-format [csv|tsv|ssv|json|copy|html]: set format for output\n"); $io->writeStderr(" --padding [dense|sparse|smart]: set padding method for aligning columns\n"); $io->writeStderr(" --table NAME: compare the named table, used with SQL sources\n"); $io->writeStderr(" --unordered: assume row order is meaningless (default for json formats)\n"); $io->writeStderr(" -w / --ignore-whitespace: ignore changes in leading/trailing whitespace\n"); $io->writeStderr(" -i / --ignore-case: ignore differences in case\n"); $io->writeStderr("\n"); $io->writeStderr(" daff render [--output OUTPUT.html] [--css CSS.css] [--fragment] [--plain] diff.csv\n"); $io->writeStderr(" --css CSS.css: generate a suitable css file to go with the html\n"); $io->writeStderr(" --fragment: generate just a html fragment rather than a page\n"); $io->writeStderr(" --plain: do not use fancy utf8 characters to make arrows prettier\n"); $io->writeStderr(" --www: send output to a browser\n"); return 1; } $cmd1 = $args[0]; $offset = 1; if (!Lambda::has(new _hx_array(array("diff", "patch", "merge", "trim", "render", "git", "version", "copy")), $cmd1)) { if (_hx_index_of($cmd1, ".", null) !== -1 || _hx_index_of($cmd1, "--", null) === 0) { $cmd1 = "diff"; $offset = 0; } } if ($cmd1 === "git") { $types = $args->splice($offset, $args->length - $offset); return $this->installGitDriver($io, $types); } if ($git) { $ct = $args->length - $offset; if ($ct !== 7 && $ct !== 9) { $io->writeStderr("Expected 7 or 9 parameters from git, but got " . _hx_string_rec($ct, "") . "\n"); return 1; } $git_args = $args->splice($offset, $ct); $args->splice(0, $args->length); $offset = 0; $old_display_path = $git_args[0]; $new_display_path = $git_args[0]; $old_file = $git_args[1]; $new_file = $git_args[4]; if ($ct === 9) { $io->writeStdout($git_args[8]); $new_display_path = $git_args[7]; } $io->writeStdout("--- a/" . _hx_string_or_null($old_display_path) . "\n"); $io->writeStdout("+++ b/" . _hx_string_or_null($new_display_path) . "\n"); $args->push($old_file); $args->push($new_file); } $parent = null; if ($args->length - $offset >= 3) { $parent = $this->loadTable($args[$offset]); $offset++; } $aname = $args[$offset]; $a = $this->loadTable($aname); $b = null; if ($args->length - $offset >= 2) { if ($cmd1 !== "copy") { $b = $this->loadTable($args[1 + $offset]); } else { $output = $args[1 + $offset]; } } $this->flags->diff_strategy = $this->strategy; if ($inplace) { if ($output !== null) { $io->writeStderr("Please do not use --inplace when specifying an output.\n"); } $output = $aname; return 1; } if ($output === null) { $output = "-"; } $ok = true; if ($cmd1 === "diff") { if (!$this->order_set) { $this->flags->ordered = $this->order_preference; if (!$this->flags->ordered) { $this->flags->unchanged_context = 0; } } $this->flags->allow_nested_cells = $this->nested_output; $this->runDiff($parent, $a, $b, $this->flags, $output); } else { if ($cmd1 === "patch") { $patcher = new coopy_HighlightPatch($a, $b, null); $patcher->apply(); $this->saveTable($output, $a, null); } else { if ($cmd1 === "merge") { $merger = new coopy_Merger($parent, $a, $b, $this->flags); $conflicts = $merger->apply(); $ok = $conflicts === 0; if ($conflicts > 0) { $io->writeStderr(_hx_string_rec($conflicts, "") . " conflict" . _hx_string_or_null($conflicts > 1 ? "s" : "") . "\n"); } $this->saveTable($output, $a, null); } else { if ($cmd1 === "trim") { $this->saveTable($output, $a, null); } else { if ($cmd1 === "render") { $this->renderTable($output, $a); } else { if ($cmd1 === "copy") { $this->saveTable($output, $a, null); } } } } } } if ($ok) { return 0; } else { return 1; } }