public function testIgnore() { $table1 = harness_Native::table($this->data1); $table2 = harness_Native::table($this->data2); $flags = new coopy_CompareFlags(); $flags->columns_to_ignore = new _hx_array(array("key", "version")); $alignment = coopy_Coopy::compareTables3($table2, $table1, $table2, $flags)->align(); $data_diff = new _hx_array(array()); $table_diff = harness_Native::table($data_diff); $highlighter = new coopy_TableDiff($alignment, $flags); $highlighter->hilite($table_diff); $this->assertEquals($table_diff->get_height(), 1, _hx_anonymous(array("fileName" => "SmallTableTest.hx", "lineNumber" => 68, "className" => "harness.SmallTableTest", "methodName" => "testIgnore"))); $this->assertEquals($table_diff->get_width(), 3, _hx_anonymous(array("fileName" => "SmallTableTest.hx", "lineNumber" => 69, "className" => "harness.SmallTableTest", "methodName" => "testIgnore"))); $v = $table1->getCellView(); $this->assertEquals($v->toString($table_diff->getCell(0, 0)), "@@", _hx_anonymous(array("fileName" => "SmallTableTest.hx", "lineNumber" => 71, "className" => "harness.SmallTableTest", "methodName" => "testIgnore"))); $this->assertEquals($v->toString($table_diff->getCell(1, 0)), "NAME", _hx_anonymous(array("fileName" => "SmallTableTest.hx", "lineNumber" => 72, "className" => "harness.SmallTableTest", "methodName" => "testIgnore"))); $this->assertEquals($v->toString($table_diff->getCell(2, 0)), "AGE", _hx_anonymous(array("fileName" => "SmallTableTest.hx", "lineNumber" => 73, "className" => "harness.SmallTableTest", "methodName" => "testIgnore"))); }
public function addMeta($output) { $a_meta = null; $b_meta = null; $p_meta = null; $a_meta = $this->getMetaTable($this->a); $b_meta = $this->getMetaTable($this->b); $p_meta = $this->getMetaTable($this->p); if ($a_meta === null || $b_meta === null || $p_meta === null) { return false; } if (!$this->checkMeta($this->a, $a_meta)) { return false; } if (!$this->checkMeta($this->b, $b_meta)) { return false; } if (!$this->checkMeta($this->p, $p_meta)) { return false; } if (!$this->flags->show_meta) { return false; } $meta_diff = new coopy_SimpleTable(0, 0); $meta_flags = new coopy_CompareFlags(); $meta_flags->addPrimaryKey("@@"); $meta_flags->addPrimaryKey("@"); $meta_flags->unchanged_column_context = 65536; $meta_flags->unchanged_context = 0; $meta_align = coopy_Coopy::compareTables3($a_meta === $p_meta ? null : $p_meta, $a_meta, $b_meta, $meta_flags)->align(); $td = new coopy_TableDiff($meta_align, $meta_flags); $td->preserve_columns = true; $td->hilite($meta_diff); if ($td->hasDifference()) { $h = $output->get_height(); $dh = $meta_diff->get_height(); $offset = null; if ($td->hasSchemaDifference()) { $offset = 2; } else { $offset = 1; } $output->resize($output->get_width(), $h + $dh - $offset); $v = $meta_diff->getCellView(); $_g = $offset; while ($_g < $dh) { $y = $_g++; $_g2 = 1; $_g1 = $meta_diff->get_width(); while ($_g2 < $_g1) { $x = $_g2++; $c = $meta_diff->getCell($x, $y); if ($x === 1) { $c = "@" . _hx_string_or_null($v->toString($c)) . "@" . _hx_string_or_null($v->toString($meta_diff->getCell(0, $y))); } $output->setCell($x - 1, $h + $y - $offset, $c); unset($x, $c); } unset($_g2, $_g1); unset($y); } if ($this->active_column !== null) { if ($td->active_column->length === $meta_diff->get_width()) { $_g11 = 1; $_g3 = $meta_diff->get_width(); while ($_g11 < $_g3) { $i = $_g11++; if ($td->active_column->a[$i] >= 0) { $this->active_column[$i - 1] = 1; } unset($i); } } } } return false; }
public function apply() { $this->conflicts = 0; $ct = coopy_Coopy::compareTables3($this->parent, $this->local, $this->remote, null); $align = $ct->align(); $this->order = $align->toOrder(); $this->units = $this->order->getList(); $this->column_order = $align->meta->toOrder(); $this->column_units = $this->column_order->getList(); $allow_insert = $this->flags->allowInsert(); $allow_delete = $this->flags->allowDelete(); $allow_update = $this->flags->allowUpdate(); $view = $this->parent->getCellView(); $_g = 0; $_g1 = $this->units; while ($_g < $_g1->length) { $row = $_g1[$_g]; ++$_g; if ($row->l >= 0 && $row->r >= 0 && $row->p >= 0) { $_g2 = 0; $_g3 = $this->column_units; while ($_g2 < $_g3->length) { $col = $_g3[$_g2]; ++$_g2; if ($col->l >= 0 && $col->r >= 0 && $col->p >= 0) { $pcell = $this->parent->getCell($col->p, $row->p); $rcell = $this->remote->getCell($col->r, $row->r); if (!$view->equals($pcell, $rcell)) { $lcell = $this->local->getCell($col->l, $row->l); if ($view->equals($pcell, $lcell)) { $this->local->setCell($col->l, $row->l, $rcell); } else { $this->local->setCell($col->l, $row->l, coopy_Merger::makeConflictedCell($view, $pcell, $lcell, $rcell)); $this->conflicts++; } unset($lcell); } unset($rcell, $pcell); } unset($col); } unset($_g3, $_g2); } unset($row); } $this->shuffleColumns(); $this->shuffleRows(); if (null == $this->column_mix_remote) { throw new HException('null iterable'); } $__hx__it = $this->column_mix_remote->keys(); while ($__hx__it->hasNext()) { unset($x); $x = $__hx__it->next(); $x2 = $this->column_mix_remote->get($x); $_g4 = 0; $_g11 = $this->units; while ($_g4 < $_g11->length) { $unit = $_g11[$_g4]; ++$_g4; if ($unit->l >= 0 && $unit->r >= 0) { $this->local->setCell($x2, $this->row_mix_local->get($unit->l), $this->remote->getCell($x, $unit->r)); } else { if ($unit->p < 0 && $unit->r >= 0) { $this->local->setCell($x2, $this->row_mix_remote->get($unit->r), $this->remote->getCell($x, $unit->r)); } } unset($unit); } unset($_g4, $_g11); unset($x2); } if (null == $this->row_mix_remote) { throw new HException('null iterable'); } $__hx__it = $this->row_mix_remote->keys(); while ($__hx__it->hasNext()) { unset($y); $y = $__hx__it->next(); $y2 = $this->row_mix_remote->get($y); $_g5 = 0; $_g12 = $this->column_units; while ($_g5 < $_g12->length) { $unit1 = $_g12[$_g5]; ++$_g5; if ($unit1->l >= 0 && $unit1->r >= 0) { $this->local->setCell($this->column_mix_local->get($unit1->l), $y2, $this->remote->getCell($unit1->r, $y)); } unset($unit1); } unset($_g5, $_g12); unset($y2); } return $this->conflicts; }
public function runDiff($parent, $a, $b, $flags, $output) { $ct = coopy_Coopy::compareTables3($parent, $a, $b, $flags); $align = $ct->align(); $td = new coopy_TableDiff($align, $flags); $o = new coopy_SimpleTable(0, 0); $os = new coopy_Tables($o); $td->hiliteWithNesting($os); $use_color = $flags->terminal_format === "ansi"; if ($flags->terminal_format === null) { if (($output === null || $output === "-") && ($this->output_format === "copy" || $this->output_format === "csv")) { if ($this->io !== null) { if ($this->io->isTtyKnown()) { $use_color = $this->io->isTty(); } } } } $this->saveTables($output, $os, $use_color); }
public function coopyhx($io) { $this->init(); $args = $io->args(); if ($args[0] === "--keep") { return coopy_Coopy::keepAround(); } $more = true; $output = null; $inplace = false; $git = false; $color = false; $no_color = 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; $color = true; $args->splice($i, 1); break; } else { if ($tag === "--no-color") { $more = true; $no_color = true; $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; } } } } } } } } } } } } } } } } } } } } } } } 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(" --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("\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); } $tool = $this; $tool->io = $io; $parent = null; if ($args->length - $offset >= 3) { $parent = $tool->loadTable($args[$offset]); $offset++; } $aname = $args[$offset]; $a = $tool->loadTable($aname); $b = null; if ($args->length - $offset >= 2) { if ($cmd1 !== "copy") { $b = $tool->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; $ct1 = coopy_Coopy::compareTables3($parent, $a, $b, $this->flags); $align = $ct1->align(); $td = new coopy_TableDiff($align, $this->flags); $o = new coopy_SimpleTable(0, 0); $td->hilite($o); $use_color = $color; if (!($color || $no_color)) { if ($output === "-" && $this->output_format === "copy") { if ($io->isTtyKnown()) { $use_color = $io->isTty(); } } } if ($use_color) { $render = new coopy_TerminalDiffRender(); $tool->saveText($output, $render->render($o)); } else { $tool->saveTable($output, $o); } } else { if ($cmd1 === "patch") { $patcher = new coopy_HighlightPatch($a, $b, null); $patcher->apply(); $tool->saveTable($output, $a); } 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"); } $tool->saveTable($output, $a); } else { if ($cmd1 === "trim") { $tool->saveTable($output, $a); } else { if ($cmd1 === "render") { $this->renderTable($output, $a); } else { if ($cmd1 === "copy") { $tool->saveTable($output, $a); } } } } } } if ($ok) { return 0; } else { return 1; } }