webdiff 0.16.0__tar.gz → 1.0.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- webdiff-1.0.1/PKG-INFO +210 -0
- webdiff-1.0.1/README.md +186 -0
- {webdiff-0.16.0 → webdiff-1.0.1}/setup.py +4 -2
- {webdiff-0.16.0 → webdiff-1.0.1}/webdiff/app.py +58 -16
- {webdiff-0.16.0 → webdiff-1.0.1}/webdiff/argparser.py +20 -7
- {webdiff-0.16.0 → webdiff-1.0.1}/webdiff/diff.py +43 -1
- webdiff-1.0.1/webdiff/dirdiff.py +69 -0
- {webdiff-0.16.0 → webdiff-1.0.1}/webdiff/githubdiff.py +1 -1
- {webdiff-0.16.0 → webdiff-1.0.1}/webdiff/gitwebdiff.py +5 -1
- webdiff-1.0.1/webdiff/localfilediff.py +57 -0
- webdiff-1.0.1/webdiff/options.py +64 -0
- {webdiff-0.16.0 → webdiff-1.0.1}/webdiff/static/codediff.js/codediff.css +1 -1
- webdiff-1.0.1/webdiff/static/codediff.js/codediff.js +534 -0
- {webdiff-0.16.0 → webdiff-1.0.1}/webdiff/static/css/style.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/a11y-dark.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/a11y-light.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/agate.css +20 -0
- webdiff-1.0.1/webdiff/static/css/themes/an-old-hope.css +9 -0
- webdiff-1.0.1/webdiff/static/css/themes/androidstudio.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/arduino-light.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/arta.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/ascetic.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/atom-one-dark-reasonable.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/atom-one-dark.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/atom-one-light.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/3024.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/apathy.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/apprentice.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/ashes.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/atelier-cave-light.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/atelier-cave.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/atelier-dune-light.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/atelier-dune.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/atelier-estuary-light.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/atelier-estuary.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/atelier-forest-light.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/atelier-forest.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/atelier-heath-light.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/atelier-heath.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/atelier-lakeside-light.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/atelier-lakeside.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/atelier-plateau-light.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/atelier-plateau.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/atelier-savanna-light.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/atelier-savanna.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/atelier-seaside-light.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/atelier-seaside.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/atelier-sulphurpool-light.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/atelier-sulphurpool.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/atlas.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/bespin.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/black-metal-bathory.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/black-metal-burzum.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/black-metal-dark-funeral.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/black-metal-gorgoroth.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/black-metal-immortal.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/black-metal-khold.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/black-metal-marduk.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/black-metal-mayhem.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/black-metal-nile.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/black-metal-venom.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/black-metal.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/brewer.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/bright.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/brogrammer.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/brush-trees-dark.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/brush-trees.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/chalk.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/circus.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/classic-dark.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/classic-light.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/codeschool.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/colors.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/cupcake.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/cupertino.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/danqing.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/darcula.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/dark-violet.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/darkmoss.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/darktooth.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/decaf.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/default-dark.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/default-light.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/dirtysea.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/dracula.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/edge-dark.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/edge-light.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/eighties.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/embers.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/equilibrium-dark.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/equilibrium-gray-dark.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/equilibrium-gray-light.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/equilibrium-light.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/espresso.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/eva-dim.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/eva.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/flat.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/framer.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/fruit-soda.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/gigavolt.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/github.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/google-dark.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/google-light.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/grayscale-dark.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/grayscale-light.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/green-screen.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/gruvbox-dark-hard.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/gruvbox-dark-medium.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/gruvbox-dark-pale.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/gruvbox-dark-soft.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/gruvbox-light-hard.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/gruvbox-light-medium.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/gruvbox-light-soft.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/hardcore.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/harmonic16-dark.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/harmonic16-light.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/heetch-dark.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/heetch-light.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/helios.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/hopscotch.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/horizon-dark.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/horizon-light.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/humanoid-dark.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/humanoid-light.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/ia-dark.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/ia-light.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/icy-dark.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/ir-black.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/isotope.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/kimber.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/london-tube.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/macintosh.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/marrakesh.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/materia.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/material-darker.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/material-lighter.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/material-palenight.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/material-vivid.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/material.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/mellow-purple.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/mexico-light.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/mocha.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/monokai.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/nebula.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/nord.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/nova.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/ocean.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/oceanicnext.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/one-light.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/onedark.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/outrun-dark.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/papercolor-dark.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/papercolor-light.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/paraiso.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/pasque.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/phd.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/pico.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/pop.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/porple.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/qualia.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/railscasts.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/rebecca.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/ros-pine-dawn.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/ros-pine-moon.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/ros-pine.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/sagelight.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/sandcastle.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/seti-ui.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/shapeshifter.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/silk-dark.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/silk-light.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/snazzy.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/solar-flare-light.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/solar-flare.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/solarized-dark.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/solarized-light.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/spacemacs.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/summercamp.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/summerfruit-dark.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/summerfruit-light.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/synth-midnight-terminal-dark.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/synth-midnight-terminal-light.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/tango.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/tender.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/tomorrow-night.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/tomorrow.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/twilight.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/unikitty-dark.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/unikitty-light.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/vulcan.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/windows-10-light.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/windows-10.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/windows-95-light.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/windows-95.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/windows-high-contrast-light.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/windows-high-contrast.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/windows-nt-light.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/windows-nt.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/woodland.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/xcode-dusk.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/base16/zenburn.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/brown-paper.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/brown-papersq.png +0 -0
- webdiff-1.0.1/webdiff/static/css/themes/codepen-embed.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/color-brewer.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/dark.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/default.css +9 -0
- webdiff-1.0.1/webdiff/static/css/themes/devibeans.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/docco.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/far.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/felipec.css +7 -0
- webdiff-1.0.1/webdiff/static/css/themes/foundation.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/github-dark-dimmed.css +9 -0
- webdiff-1.0.1/webdiff/static/css/themes/github-dark.css +10 -0
- webdiff-1.0.1/webdiff/static/css/themes/github.css +10 -0
- webdiff-1.0.1/webdiff/static/css/themes/gml.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/googlecode.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/gradient-dark.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/gradient-light.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/grayscale.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/hybrid.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/idea.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/intellij-light.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/ir-black.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/isbl-editor-dark.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/isbl-editor-light.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/kimbie-dark.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/kimbie-light.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/lightfair.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/lioshi.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/magula.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/mono-blue.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/monokai-sublime.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/monokai.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/night-owl.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/nnfx-dark.css +10 -0
- webdiff-1.0.1/webdiff/static/css/themes/nnfx-light.css +10 -0
- webdiff-1.0.1/webdiff/static/css/themes/nord.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/obsidian.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/panda-syntax-dark.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/panda-syntax-light.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/paraiso-dark.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/paraiso-light.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/pojoaque.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/pojoaque.jpg +0 -0
- webdiff-1.0.1/webdiff/static/css/themes/purebasic.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/qtcreator-dark.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/qtcreator-light.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/rainbow.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/routeros.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/school-book.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/shades-of-purple.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/srcery.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/stackoverflow-dark.css +13 -0
- webdiff-1.0.1/webdiff/static/css/themes/stackoverflow-light.css +13 -0
- webdiff-1.0.1/webdiff/static/css/themes/sunburst.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/tokyo-night-dark.css +8 -0
- webdiff-1.0.1/webdiff/static/css/themes/tokyo-night-light.css +8 -0
- webdiff-1.0.1/webdiff/static/css/themes/tomorrow-night-blue.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/tomorrow-night-bright.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/vs.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/vs2015.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/xcode.css +1 -0
- webdiff-1.0.1/webdiff/static/css/themes/xt256.css +1 -0
- webdiff-1.0.1/webdiff/static/js/file_diff.js +52 -0
- webdiff-1.0.1/webdiff/static/js/highlight.min.js +3403 -0
- {webdiff-0.16.0 → webdiff-1.0.1}/webdiff/templates/base.html +2 -2
- {webdiff-0.16.0 → webdiff-1.0.1}/webdiff/templates/file_diff.html +1 -0
- webdiff-1.0.1/webdiff/unified_diff.py +179 -0
- webdiff-1.0.1/webdiff.egg-info/PKG-INFO +210 -0
- webdiff-1.0.1/webdiff.egg-info/SOURCES.txt +293 -0
- {webdiff-0.16.0 → webdiff-1.0.1}/webdiff.egg-info/requires.txt +2 -0
- webdiff-0.16.0/PKG-INFO +0 -135
- webdiff-0.16.0/README +0 -23
- webdiff-0.16.0/README.md +0 -118
- webdiff-0.16.0/webdiff/dirdiff.py +0 -95
- webdiff-0.16.0/webdiff/localfilediff.py +0 -46
- webdiff-0.16.0/webdiff/static/codediff.js/codediff.js +0 -683
- webdiff-0.16.0/webdiff/static/js/file_diff.js +0 -52
- webdiff-0.16.0/webdiff.egg-info/PKG-INFO +0 -135
- webdiff-0.16.0/webdiff.egg-info/SOURCES.txt +0 -41
- {webdiff-0.16.0 → webdiff-1.0.1}/LICENSE +0 -0
- {webdiff-0.16.0 → webdiff-1.0.1}/MANIFEST.in +0 -0
- {webdiff-0.16.0 → webdiff-1.0.1}/setup.cfg +0 -0
- {webdiff-0.16.0 → webdiff-1.0.1}/webdiff/__init__.py +0 -0
- {webdiff-0.16.0 → webdiff-1.0.1}/webdiff/github_fetcher.py +0 -0
- {webdiff-0.16.0 → webdiff-1.0.1}/webdiff/static/__init__.py +0 -0
- {webdiff-0.16.0 → webdiff-1.0.1}/webdiff/static/codediff.js/difflib.js +0 -0
- {webdiff-0.16.0 → webdiff-1.0.1}/webdiff/static/codediff.js/googlecode.css +0 -0
- {webdiff-0.16.0 → webdiff-1.0.1}/webdiff/static/css/Inconsolata/Inconsolata-Bold.ttf +0 -0
- {webdiff-0.16.0 → webdiff-1.0.1}/webdiff/static/css/Inconsolata/Inconsolata-Regular.ttf +0 -0
- {webdiff-0.16.0 → webdiff-1.0.1}/webdiff/static/css/Inconsolata/OFL.txt +0 -0
- {webdiff-0.16.0 → webdiff-1.0.1}/webdiff/static/css/googlecode.css +0 -0
- {webdiff-0.16.0 → webdiff-1.0.1}/webdiff/static/css/inconsolata.css +0 -0
- {webdiff-0.16.0 → webdiff-1.0.1}/webdiff/static/img/favicon.ico +0 -0
- {webdiff-0.16.0 → webdiff-1.0.1}/webdiff/static/img/sprites.png +0 -0
- {webdiff-0.16.0 → webdiff-1.0.1}/webdiff/static/img/trans_bg.gif +0 -0
- {webdiff-0.16.0 → webdiff-1.0.1}/webdiff/static/js/highlight.pack.min.js +0 -0
- {webdiff-0.16.0 → webdiff-1.0.1}/webdiff/static/js/jquery-2.1.1.min.js +0 -0
- {webdiff-0.16.0 → webdiff-1.0.1}/webdiff/templates/__init__.py +0 -0
- {webdiff-0.16.0 → webdiff-1.0.1}/webdiff/util.py +0 -0
- {webdiff-0.16.0 → webdiff-1.0.1}/webdiff.egg-info/dependency_links.txt +0 -0
- {webdiff-0.16.0 → webdiff-1.0.1}/webdiff.egg-info/entry_points.txt +0 -0
- {webdiff-0.16.0 → webdiff-1.0.1}/webdiff.egg-info/top_level.txt +0 -0
webdiff-1.0.1/PKG-INFO
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: webdiff
|
|
3
|
+
Version: 1.0.1
|
|
4
|
+
Summary: Two-column web-based git difftool
|
|
5
|
+
Home-page: https://github.com/danvk/webdiff/
|
|
6
|
+
Author: Dan Vanderkam
|
|
7
|
+
Author-email: danvdk@gmail.com
|
|
8
|
+
Classifier: Environment :: Console
|
|
9
|
+
Classifier: Environment :: Web Environment
|
|
10
|
+
Classifier: Framework :: Flask
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
14
|
+
Classifier: Topic :: Software Development :: Version Control
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
License-File: LICENSE
|
|
17
|
+
Requires-Dist: binaryornot
|
|
18
|
+
Requires-Dist: flask==2.2.2
|
|
19
|
+
Requires-Dist: pillow
|
|
20
|
+
Requires-Dist: requests
|
|
21
|
+
Requires-Dist: PyGithub==1.55
|
|
22
|
+
Requires-Dist: unidiff==0.7.4
|
|
23
|
+
Requires-Dist: Werkzeug==2.2.2
|
|
24
|
+
|
|
25
|
+
# git webdiff
|
|
26
|
+
|
|
27
|
+
Two-column web-based git difftool.
|
|
28
|
+
|
|
29
|
+
<p align="center">
|
|
30
|
+
<a href="https://pypi.org/project/webdiff/" target="_blank"><img alt="PyPI - Version" src="https://img.shields.io/pypi/v/webdiff" /></a>
|
|
31
|
+
<a href="https://dl.circleci.com/status-badge/redirect/gh/danvk/webdiff/tree/master" target="_blank"><img alt="CircleCI 📝" src="https://dl.circleci.com/status-badge/img/gh/danvk/webdiff/tree/master.svg?style=svg" /></a>
|
|
32
|
+
<a href="https://github.com/danvk/webdiff/blob/master/LICENSE" target="_blank"><img alt="License: Apache2 📝" src="https://img.shields.io/github/license/danvk/webdiff" /></a>
|
|
33
|
+
<a href="https://github.com/sponsors/danvk" target="_blank"><img alt="Sponsor: On GitHub 💸" src="https://img.shields.io/badge/sponsor-on_github_💸-21bb42.svg" /></a>
|
|
34
|
+
</p>
|
|
35
|
+
|
|
36
|
+
Features include:
|
|
37
|
+
|
|
38
|
+
* Side-by-side (two column) diff view
|
|
39
|
+
* Runs in the browser of your choice on any platform.
|
|
40
|
+
* Syntax highlighting via highlight.js
|
|
41
|
+
* Step back and forth through multiple files in a single diff
|
|
42
|
+
* Rich support for image diffs
|
|
43
|
+
|
|
44
|
+
<!-- These are absolute URLs so that they display on pypi.org -->
|
|
45
|
+
<!-- This is `git webdiff 05157bba^..05157bba`, in this repo -->
|
|
46
|
+

|
|
47
|
+
|
|
48
|
+
<!-- This is `git webdiff c80f969^..c80f969` in the dygraphs-dpxdt repo -->
|
|
49
|
+

|
|
50
|
+
|
|
51
|
+
## Installation
|
|
52
|
+
|
|
53
|
+
pip install webdiff
|
|
54
|
+
|
|
55
|
+
or, if you prefer [Homebrew]:
|
|
56
|
+
|
|
57
|
+
brew install danvk/webdiff/webdiff
|
|
58
|
+
|
|
59
|
+
(the latter will also install [ImageMagick] as a recommended dependency.)
|
|
60
|
+
|
|
61
|
+
## Usage
|
|
62
|
+
|
|
63
|
+
Instead of running "git diff", run:
|
|
64
|
+
|
|
65
|
+
git webdiff
|
|
66
|
+
|
|
67
|
+
You can also start webdiff via:
|
|
68
|
+
|
|
69
|
+
git webdiff [args]
|
|
70
|
+
|
|
71
|
+
You can pass all the same arguments that you would to `git diff`, e.g.
|
|
72
|
+
`1234..5678` or `HEAD`.
|
|
73
|
+
|
|
74
|
+
`webdiff` can also be invoked directly to diff two directories or files:
|
|
75
|
+
|
|
76
|
+
webdiff <left_dir> <right_dir>
|
|
77
|
+
webdiff <left_file> <right_file>
|
|
78
|
+
|
|
79
|
+
You can also use `webdiff` to view GitHub pull requests:
|
|
80
|
+
|
|
81
|
+
webdiff https://github.com/owner/repo/pull/123
|
|
82
|
+
webdiff '#123' # if you're in a git repo with a github remote
|
|
83
|
+
|
|
84
|
+
This will download the files relevant to the Pull Request and run `webdiff`.
|
|
85
|
+
|
|
86
|
+
If you run into GitHub API quota limits or you'd like to use webdiff with
|
|
87
|
+
private repos, you can set your credentials in a `.githubrc` file:
|
|
88
|
+
|
|
89
|
+
user.login: yourusername
|
|
90
|
+
user.token: your-personal-access-tokens
|
|
91
|
+
|
|
92
|
+
Make sure you chmod this file to only be readable by yourself. You can generate
|
|
93
|
+
a personal access token for webdiff via github.com → profile → Settings →
|
|
94
|
+
Personal access tokens. Make sure to grant all the "repo" privileges.
|
|
95
|
+
|
|
96
|
+
## Configuration
|
|
97
|
+
|
|
98
|
+
webdiff can be configured via [`git config`][git config]. To change the syntax highlighting theme, for example:
|
|
99
|
+
|
|
100
|
+
git config webdiff.theme rainbow
|
|
101
|
+
|
|
102
|
+
(You can find a list of supported themes in the [themes] directory.)
|
|
103
|
+
|
|
104
|
+
As with any git configuration setting, these can be set globally or per-repo.
|
|
105
|
+
|
|
106
|
+
Options are:
|
|
107
|
+
|
|
108
|
+
| Setting | Default | Notes |
|
|
109
|
+
| -------------- | ------------- | ------ |
|
|
110
|
+
| webdiff.theme | googlecode | Syntax highlighting theme (see [themes] directory). |
|
|
111
|
+
| webdiff.port | -1 | Port on which to serve webdiff. Default is random open port. This can be overridden with the `--port` command line flag or the `WEBDIFF_PORT` environment variable. |
|
|
112
|
+
| webdiff.host | localhost | Host name on which to serve the webdiff UI. Use `0.0.0.0` to serve publicly. The special value `<hostname>` uses your computer's network name. This can be overridden with the `--host` command line flag or the `WEBDIFF_HOST` environment variable. |
|
|
113
|
+
| webdiff.maxDiffWidth | 100 | Maximum length of lines in the diff display. After this width, lines will wrap. |
|
|
114
|
+
| webdiff.unified | 8 | Lines of context to display by default (`git diff -U`) |
|
|
115
|
+
| webdiff.extraDirDiffArgs | "" | Any extra arguments to pass to `git diff` when diffing directories. |
|
|
116
|
+
| webdiff.extraFileDiffArgs | "" | Any extra arguments to pass to `git diff` when diffing files. |
|
|
117
|
+
| webdiff.openBrowser | true | Whether to automatically open the browser UI when you run webdiff. |
|
|
118
|
+
| webdiff.maxLinesForSyntax | 10000 | Maximum lines in file to do syntax highlighting. |
|
|
119
|
+
| webdiff.colors.delete | #fee | CSS background color for delete (left) lines |
|
|
120
|
+
| webdiff.colors.insert | #efe | CSS background color for insert (right) lines |
|
|
121
|
+
| webdiff.colors.charDelete | #fcc | CSS background color for deleted characters in a delete (left) line |
|
|
122
|
+
| webdiff.colors.charInsert | #cfc | CSS background color for inserted characters in an insert (right) line |
|
|
123
|
+
|
|
124
|
+
## Development
|
|
125
|
+
|
|
126
|
+
python3 -m venv venv
|
|
127
|
+
source venv/bin/activate
|
|
128
|
+
pip install -r requirements.txt
|
|
129
|
+
cd ts
|
|
130
|
+
yarn
|
|
131
|
+
# see https://github.com/webpack/webpack/issues/14532
|
|
132
|
+
NODE_OPTIONS=--openssl-legacy-provider webpack
|
|
133
|
+
|
|
134
|
+
Then from the root directory:
|
|
135
|
+
|
|
136
|
+
PYTHONPATH=. ./webdiff/app.py testdata/dygraphsjs/{left,right}
|
|
137
|
+
|
|
138
|
+
or to launch in debug mode:
|
|
139
|
+
|
|
140
|
+
./test.sh $(pwd)/testdata/manyfiles/{left,right}
|
|
141
|
+
|
|
142
|
+
(or any other directory in testdata)
|
|
143
|
+
|
|
144
|
+
To run the Python tests:
|
|
145
|
+
|
|
146
|
+
pytest
|
|
147
|
+
|
|
148
|
+
To format the code, run:
|
|
149
|
+
|
|
150
|
+
./scripts/black.sh
|
|
151
|
+
cd ts
|
|
152
|
+
yarn prettier
|
|
153
|
+
|
|
154
|
+
To debug `git webdiff`, run:
|
|
155
|
+
|
|
156
|
+
WEBDIFF_CONFIG=$(pwd)/testing.cfg ./webdiff/gitwebdiff.py
|
|
157
|
+
|
|
158
|
+
To iterate on the PyPI package, run:
|
|
159
|
+
|
|
160
|
+
# from outside the webdiff virtualenv:
|
|
161
|
+
pip3 uninstall webdiff
|
|
162
|
+
|
|
163
|
+
# from inside the webdiff virtualenv, adjust for current version
|
|
164
|
+
python setup.py sdist
|
|
165
|
+
mkdir /tmp/webdiff-test
|
|
166
|
+
cp dist/webdiff-?.?.?.tar.gz /tmp/webdiff-test
|
|
167
|
+
|
|
168
|
+
deactivate
|
|
169
|
+
cd /tmp/webdiff-test
|
|
170
|
+
pip3 install webdiff-?.?.?.tar.gz
|
|
171
|
+
|
|
172
|
+
To publish to pypitest:
|
|
173
|
+
|
|
174
|
+
pip install --upgrade wheel setuptools twine
|
|
175
|
+
python setup.py sdist bdist_wheel
|
|
176
|
+
twine upload -r testpypi dist/*
|
|
177
|
+
|
|
178
|
+
And to the real pypi:
|
|
179
|
+
|
|
180
|
+
twine upload dist/*
|
|
181
|
+
|
|
182
|
+
See [pypirc][] docs for details on setting up `~/.pypirc`.
|
|
183
|
+
|
|
184
|
+
## Implementation notes
|
|
185
|
+
|
|
186
|
+
webdiff doesn't calculate any diffs itself. Instead, it relies on `git diff`. This is possible because `git diff` has a `--no-index` mode that allows it to operate outside of a git repository. Of course, this means that you need to have `git` installed to use webdiff!
|
|
187
|
+
|
|
188
|
+
When you run `webdiff dir1 dir2`, webdiff runs:
|
|
189
|
+
|
|
190
|
+
git diff --raw --no-index dir1 dir2
|
|
191
|
+
|
|
192
|
+
To ask `git` which files are adds, removes, renames and changes. Then, when it's serving the web UI for a particular diff, it runs:
|
|
193
|
+
|
|
194
|
+
git diff --no-index (diff args) file1 file2
|
|
195
|
+
|
|
196
|
+
This produces a patch, which is what the web UI renders. (It also needs both full files for syntax highlighting.)
|
|
197
|
+
|
|
198
|
+
When you run `git webdiff (args)`, it runs:
|
|
199
|
+
|
|
200
|
+
git difftool -d -x webdiff (args)
|
|
201
|
+
|
|
202
|
+
This tells `git` to set up two directories and invoke `webdiff leftdir rightdir`.
|
|
203
|
+
|
|
204
|
+
There's one complication involving symlinks. `git difftool -d` may fill one of the sides (typically the right) with symlinks. This is faster than copying files, but unfortunately `git diff --no-index` does not resolve these symlinks. To make this work, if a directory contains symlinks, webdiff makes a copy of it before diffing. For file diffs, it resolves the symlink before passing it to `git diff --no-index`. The upshot is that you can run `git webdiff`, edit a file, reload the browser window and see the changes.
|
|
205
|
+
|
|
206
|
+
[pypirc]: https://packaging.python.org/specifications/pypirc/
|
|
207
|
+
[Homebrew]: https://brew.sh/
|
|
208
|
+
[ImageMagick]: https://imagemagick.org/index.php
|
|
209
|
+
[git config]: https://git-scm.com/docs/git-config
|
|
210
|
+
[themes]: http://example.com
|
webdiff-1.0.1/README.md
ADDED
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
# git webdiff
|
|
2
|
+
|
|
3
|
+
Two-column web-based git difftool.
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<a href="https://pypi.org/project/webdiff/" target="_blank"><img alt="PyPI - Version" src="https://img.shields.io/pypi/v/webdiff" /></a>
|
|
7
|
+
<a href="https://dl.circleci.com/status-badge/redirect/gh/danvk/webdiff/tree/master" target="_blank"><img alt="CircleCI 📝" src="https://dl.circleci.com/status-badge/img/gh/danvk/webdiff/tree/master.svg?style=svg" /></a>
|
|
8
|
+
<a href="https://github.com/danvk/webdiff/blob/master/LICENSE" target="_blank"><img alt="License: Apache2 📝" src="https://img.shields.io/github/license/danvk/webdiff" /></a>
|
|
9
|
+
<a href="https://github.com/sponsors/danvk" target="_blank"><img alt="Sponsor: On GitHub 💸" src="https://img.shields.io/badge/sponsor-on_github_💸-21bb42.svg" /></a>
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
Features include:
|
|
13
|
+
|
|
14
|
+
* Side-by-side (two column) diff view
|
|
15
|
+
* Runs in the browser of your choice on any platform.
|
|
16
|
+
* Syntax highlighting via highlight.js
|
|
17
|
+
* Step back and forth through multiple files in a single diff
|
|
18
|
+
* Rich support for image diffs
|
|
19
|
+
|
|
20
|
+
<!-- These are absolute URLs so that they display on pypi.org -->
|
|
21
|
+
<!-- This is `git webdiff 05157bba^..05157bba`, in this repo -->
|
|
22
|
+

|
|
23
|
+
|
|
24
|
+
<!-- This is `git webdiff c80f969^..c80f969` in the dygraphs-dpxdt repo -->
|
|
25
|
+

|
|
26
|
+
|
|
27
|
+
## Installation
|
|
28
|
+
|
|
29
|
+
pip install webdiff
|
|
30
|
+
|
|
31
|
+
or, if you prefer [Homebrew]:
|
|
32
|
+
|
|
33
|
+
brew install danvk/webdiff/webdiff
|
|
34
|
+
|
|
35
|
+
(the latter will also install [ImageMagick] as a recommended dependency.)
|
|
36
|
+
|
|
37
|
+
## Usage
|
|
38
|
+
|
|
39
|
+
Instead of running "git diff", run:
|
|
40
|
+
|
|
41
|
+
git webdiff
|
|
42
|
+
|
|
43
|
+
You can also start webdiff via:
|
|
44
|
+
|
|
45
|
+
git webdiff [args]
|
|
46
|
+
|
|
47
|
+
You can pass all the same arguments that you would to `git diff`, e.g.
|
|
48
|
+
`1234..5678` or `HEAD`.
|
|
49
|
+
|
|
50
|
+
`webdiff` can also be invoked directly to diff two directories or files:
|
|
51
|
+
|
|
52
|
+
webdiff <left_dir> <right_dir>
|
|
53
|
+
webdiff <left_file> <right_file>
|
|
54
|
+
|
|
55
|
+
You can also use `webdiff` to view GitHub pull requests:
|
|
56
|
+
|
|
57
|
+
webdiff https://github.com/owner/repo/pull/123
|
|
58
|
+
webdiff '#123' # if you're in a git repo with a github remote
|
|
59
|
+
|
|
60
|
+
This will download the files relevant to the Pull Request and run `webdiff`.
|
|
61
|
+
|
|
62
|
+
If you run into GitHub API quota limits or you'd like to use webdiff with
|
|
63
|
+
private repos, you can set your credentials in a `.githubrc` file:
|
|
64
|
+
|
|
65
|
+
user.login: yourusername
|
|
66
|
+
user.token: your-personal-access-tokens
|
|
67
|
+
|
|
68
|
+
Make sure you chmod this file to only be readable by yourself. You can generate
|
|
69
|
+
a personal access token for webdiff via github.com → profile → Settings →
|
|
70
|
+
Personal access tokens. Make sure to grant all the "repo" privileges.
|
|
71
|
+
|
|
72
|
+
## Configuration
|
|
73
|
+
|
|
74
|
+
webdiff can be configured via [`git config`][git config]. To change the syntax highlighting theme, for example:
|
|
75
|
+
|
|
76
|
+
git config webdiff.theme rainbow
|
|
77
|
+
|
|
78
|
+
(You can find a list of supported themes in the [themes] directory.)
|
|
79
|
+
|
|
80
|
+
As with any git configuration setting, these can be set globally or per-repo.
|
|
81
|
+
|
|
82
|
+
Options are:
|
|
83
|
+
|
|
84
|
+
| Setting | Default | Notes |
|
|
85
|
+
| -------------- | ------------- | ------ |
|
|
86
|
+
| webdiff.theme | googlecode | Syntax highlighting theme (see [themes] directory). |
|
|
87
|
+
| webdiff.port | -1 | Port on which to serve webdiff. Default is random open port. This can be overridden with the `--port` command line flag or the `WEBDIFF_PORT` environment variable. |
|
|
88
|
+
| webdiff.host | localhost | Host name on which to serve the webdiff UI. Use `0.0.0.0` to serve publicly. The special value `<hostname>` uses your computer's network name. This can be overridden with the `--host` command line flag or the `WEBDIFF_HOST` environment variable. |
|
|
89
|
+
| webdiff.maxDiffWidth | 100 | Maximum length of lines in the diff display. After this width, lines will wrap. |
|
|
90
|
+
| webdiff.unified | 8 | Lines of context to display by default (`git diff -U`) |
|
|
91
|
+
| webdiff.extraDirDiffArgs | "" | Any extra arguments to pass to `git diff` when diffing directories. |
|
|
92
|
+
| webdiff.extraFileDiffArgs | "" | Any extra arguments to pass to `git diff` when diffing files. |
|
|
93
|
+
| webdiff.openBrowser | true | Whether to automatically open the browser UI when you run webdiff. |
|
|
94
|
+
| webdiff.maxLinesForSyntax | 10000 | Maximum lines in file to do syntax highlighting. |
|
|
95
|
+
| webdiff.colors.delete | #fee | CSS background color for delete (left) lines |
|
|
96
|
+
| webdiff.colors.insert | #efe | CSS background color for insert (right) lines |
|
|
97
|
+
| webdiff.colors.charDelete | #fcc | CSS background color for deleted characters in a delete (left) line |
|
|
98
|
+
| webdiff.colors.charInsert | #cfc | CSS background color for inserted characters in an insert (right) line |
|
|
99
|
+
|
|
100
|
+
## Development
|
|
101
|
+
|
|
102
|
+
python3 -m venv venv
|
|
103
|
+
source venv/bin/activate
|
|
104
|
+
pip install -r requirements.txt
|
|
105
|
+
cd ts
|
|
106
|
+
yarn
|
|
107
|
+
# see https://github.com/webpack/webpack/issues/14532
|
|
108
|
+
NODE_OPTIONS=--openssl-legacy-provider webpack
|
|
109
|
+
|
|
110
|
+
Then from the root directory:
|
|
111
|
+
|
|
112
|
+
PYTHONPATH=. ./webdiff/app.py testdata/dygraphsjs/{left,right}
|
|
113
|
+
|
|
114
|
+
or to launch in debug mode:
|
|
115
|
+
|
|
116
|
+
./test.sh $(pwd)/testdata/manyfiles/{left,right}
|
|
117
|
+
|
|
118
|
+
(or any other directory in testdata)
|
|
119
|
+
|
|
120
|
+
To run the Python tests:
|
|
121
|
+
|
|
122
|
+
pytest
|
|
123
|
+
|
|
124
|
+
To format the code, run:
|
|
125
|
+
|
|
126
|
+
./scripts/black.sh
|
|
127
|
+
cd ts
|
|
128
|
+
yarn prettier
|
|
129
|
+
|
|
130
|
+
To debug `git webdiff`, run:
|
|
131
|
+
|
|
132
|
+
WEBDIFF_CONFIG=$(pwd)/testing.cfg ./webdiff/gitwebdiff.py
|
|
133
|
+
|
|
134
|
+
To iterate on the PyPI package, run:
|
|
135
|
+
|
|
136
|
+
# from outside the webdiff virtualenv:
|
|
137
|
+
pip3 uninstall webdiff
|
|
138
|
+
|
|
139
|
+
# from inside the webdiff virtualenv, adjust for current version
|
|
140
|
+
python setup.py sdist
|
|
141
|
+
mkdir /tmp/webdiff-test
|
|
142
|
+
cp dist/webdiff-?.?.?.tar.gz /tmp/webdiff-test
|
|
143
|
+
|
|
144
|
+
deactivate
|
|
145
|
+
cd /tmp/webdiff-test
|
|
146
|
+
pip3 install webdiff-?.?.?.tar.gz
|
|
147
|
+
|
|
148
|
+
To publish to pypitest:
|
|
149
|
+
|
|
150
|
+
pip install --upgrade wheel setuptools twine
|
|
151
|
+
python setup.py sdist bdist_wheel
|
|
152
|
+
twine upload -r testpypi dist/*
|
|
153
|
+
|
|
154
|
+
And to the real pypi:
|
|
155
|
+
|
|
156
|
+
twine upload dist/*
|
|
157
|
+
|
|
158
|
+
See [pypirc][] docs for details on setting up `~/.pypirc`.
|
|
159
|
+
|
|
160
|
+
## Implementation notes
|
|
161
|
+
|
|
162
|
+
webdiff doesn't calculate any diffs itself. Instead, it relies on `git diff`. This is possible because `git diff` has a `--no-index` mode that allows it to operate outside of a git repository. Of course, this means that you need to have `git` installed to use webdiff!
|
|
163
|
+
|
|
164
|
+
When you run `webdiff dir1 dir2`, webdiff runs:
|
|
165
|
+
|
|
166
|
+
git diff --raw --no-index dir1 dir2
|
|
167
|
+
|
|
168
|
+
To ask `git` which files are adds, removes, renames and changes. Then, when it's serving the web UI for a particular diff, it runs:
|
|
169
|
+
|
|
170
|
+
git diff --no-index (diff args) file1 file2
|
|
171
|
+
|
|
172
|
+
This produces a patch, which is what the web UI renders. (It also needs both full files for syntax highlighting.)
|
|
173
|
+
|
|
174
|
+
When you run `git webdiff (args)`, it runs:
|
|
175
|
+
|
|
176
|
+
git difftool -d -x webdiff (args)
|
|
177
|
+
|
|
178
|
+
This tells `git` to set up two directories and invoke `webdiff leftdir rightdir`.
|
|
179
|
+
|
|
180
|
+
There's one complication involving symlinks. `git difftool -d` may fill one of the sides (typically the right) with symlinks. This is faster than copying files, but unfortunately `git diff --no-index` does not resolve these symlinks. To make this work, if a directory contains symlinks, webdiff makes a copy of it before diffing. For file diffs, it resolves the symlink before passing it to `git diff --no-index`. The upshot is that you can run `git webdiff`, edit a file, reload the browser window and see the changes.
|
|
181
|
+
|
|
182
|
+
[pypirc]: https://packaging.python.org/specifications/pypirc/
|
|
183
|
+
[Homebrew]: https://brew.sh/
|
|
184
|
+
[ImageMagick]: https://imagemagick.org/index.php
|
|
185
|
+
[git config]: https://git-scm.com/docs/git-config
|
|
186
|
+
[themes]: http://example.com
|
|
@@ -6,7 +6,7 @@ with open('README.md', encoding='utf8') as fh:
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
setup(name='webdiff',
|
|
9
|
-
version='0.
|
|
9
|
+
version='1.0.1',
|
|
10
10
|
description='Two-column web-based git difftool',
|
|
11
11
|
long_description=long_description,
|
|
12
12
|
long_description_content_type='text/markdown',
|
|
@@ -25,7 +25,9 @@ setup(name='webdiff',
|
|
|
25
25
|
'flask==2.2.2',
|
|
26
26
|
'pillow',
|
|
27
27
|
'requests',
|
|
28
|
-
'PyGithub==1.55'
|
|
28
|
+
'PyGithub==1.55',
|
|
29
|
+
'unidiff==0.7.4',
|
|
30
|
+
'Werkzeug==2.2.2',
|
|
29
31
|
],
|
|
30
32
|
include_package_data=True,
|
|
31
33
|
package_data = {
|
|
@@ -4,7 +4,6 @@
|
|
|
4
4
|
For usage, see README.md.
|
|
5
5
|
'''
|
|
6
6
|
|
|
7
|
-
from __future__ import print_function
|
|
8
7
|
from binaryornot.check import is_binary
|
|
9
8
|
import logging
|
|
10
9
|
import mimetypes
|
|
@@ -30,8 +29,9 @@ from flask import (
|
|
|
30
29
|
from webdiff import diff
|
|
31
30
|
from webdiff import util
|
|
32
31
|
from webdiff import argparser
|
|
32
|
+
from webdiff import options
|
|
33
33
|
|
|
34
|
-
VERSION = '0.
|
|
34
|
+
VERSION = '1.0.1'
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
def determine_path():
|
|
@@ -61,6 +61,7 @@ app = Flask(__name__)
|
|
|
61
61
|
app.config.from_object(Config)
|
|
62
62
|
app.config.from_envvar('WEBDIFF_CONFIG', silent=True)
|
|
63
63
|
|
|
64
|
+
GIT_CONFIG = {}
|
|
64
65
|
DIFF = None
|
|
65
66
|
PORT = None
|
|
66
67
|
HOSTNAME = 'localhost'
|
|
@@ -192,7 +193,11 @@ def file_diff(idx):
|
|
|
192
193
|
idx = int(idx)
|
|
193
194
|
pairs = diff.get_thin_list(DIFF)
|
|
194
195
|
return render_template(
|
|
195
|
-
'file_diff.html',
|
|
196
|
+
'file_diff.html',
|
|
197
|
+
idx=idx,
|
|
198
|
+
has_magick=util.is_imagemagick_available(),
|
|
199
|
+
pairs=pairs,
|
|
200
|
+
git_config=GIT_CONFIG,
|
|
196
201
|
)
|
|
197
202
|
|
|
198
203
|
|
|
@@ -202,6 +207,16 @@ def thick_diff(idx):
|
|
|
202
207
|
return jsonify(diff.get_thick_dict(DIFF[idx]))
|
|
203
208
|
|
|
204
209
|
|
|
210
|
+
@app.route('/diff/<int:idx>', methods=['POST'])
|
|
211
|
+
def get_diff_ops(idx):
|
|
212
|
+
idx = int(idx)
|
|
213
|
+
options = request.json.get('options')
|
|
214
|
+
extra_args = GIT_CONFIG['webdiff']['extraFileDiffArgs']
|
|
215
|
+
if extra_args:
|
|
216
|
+
options += extra_args.split(' ')
|
|
217
|
+
return jsonify(diff.get_diff_ops(DIFF[idx], options))
|
|
218
|
+
|
|
219
|
+
|
|
205
220
|
@app.route('/favicon.ico')
|
|
206
221
|
def favicon():
|
|
207
222
|
return send_from_directory(
|
|
@@ -211,6 +226,18 @@ def favicon():
|
|
|
211
226
|
)
|
|
212
227
|
|
|
213
228
|
|
|
229
|
+
@app.route('/theme.css')
|
|
230
|
+
def theme():
|
|
231
|
+
theme = GIT_CONFIG['webdiff']['theme']
|
|
232
|
+
theme_dir = os.path.dirname(theme)
|
|
233
|
+
theme_file = os.path.basename(theme)
|
|
234
|
+
return send_from_directory(
|
|
235
|
+
os.path.join(*([app.root_path, 'static/css/themes'] + ([theme_dir] if theme_dir else []))),
|
|
236
|
+
theme_file + '.css',
|
|
237
|
+
mimetype='text/css',
|
|
238
|
+
)
|
|
239
|
+
|
|
240
|
+
|
|
214
241
|
# See https://stackoverflow.com/a/69812984/388951
|
|
215
242
|
exiting = False
|
|
216
243
|
|
|
@@ -250,7 +277,8 @@ def kill():
|
|
|
250
277
|
def open_browser():
|
|
251
278
|
global PORT
|
|
252
279
|
global HOSTNAME
|
|
253
|
-
|
|
280
|
+
global GIT_CONFIG
|
|
281
|
+
if GIT_CONFIG['webdiff']['openBrowser']:
|
|
254
282
|
if is_hot_reload():
|
|
255
283
|
log.debug('Skipping browser open on reload')
|
|
256
284
|
else:
|
|
@@ -262,12 +290,17 @@ def usage_and_die():
|
|
|
262
290
|
sys.exit(1)
|
|
263
291
|
|
|
264
292
|
|
|
265
|
-
def pick_a_port(args):
|
|
266
|
-
if 'port' in args
|
|
293
|
+
def pick_a_port(args, webdiff_config):
|
|
294
|
+
if 'port' in args:
|
|
267
295
|
return args['port']
|
|
268
296
|
|
|
269
|
-
|
|
270
|
-
|
|
297
|
+
env_port = os.environ.get('WEBDIFF_PORT')
|
|
298
|
+
if env_port:
|
|
299
|
+
return int(env_port)
|
|
300
|
+
|
|
301
|
+
# gitconfig
|
|
302
|
+
if webdiff_config['port'] != -1:
|
|
303
|
+
return webdiff_config['port']
|
|
271
304
|
|
|
272
305
|
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
273
306
|
sock.bind(('localhost', 0))
|
|
@@ -290,25 +323,34 @@ def is_webdiff_from_head():
|
|
|
290
323
|
|
|
291
324
|
|
|
292
325
|
def run():
|
|
293
|
-
global DIFF, PORT, HOSTNAME
|
|
326
|
+
global DIFF, PORT, HOSTNAME, GIT_CONFIG
|
|
294
327
|
try:
|
|
295
328
|
parsed_args = argparser.parse(sys.argv[1:], VERSION)
|
|
296
329
|
except argparser.UsageError as e:
|
|
297
330
|
sys.stderr.write('Error: %s\n\n' % e)
|
|
298
331
|
usage_and_die()
|
|
299
332
|
|
|
300
|
-
|
|
333
|
+
GIT_CONFIG = options.get_config()
|
|
334
|
+
WEBDIFF_CONFIG = GIT_CONFIG['webdiff']
|
|
335
|
+
DIFF = argparser.diff_for_args(parsed_args, WEBDIFF_CONFIG)
|
|
301
336
|
|
|
302
337
|
if app.config['TESTING'] or app.config['DEBUG']:
|
|
303
|
-
sys.stderr.write('
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
338
|
+
sys.stderr.write('Invoked as: %s\n' % sys.argv)
|
|
339
|
+
sys.stderr.write('Args: %s\n' % parsed_args)
|
|
340
|
+
sys.stderr.write('Diff: %s\n' % DIFF)
|
|
341
|
+
sys.stderr.write('GitConfig: %s\n' % GIT_CONFIG)
|
|
342
|
+
|
|
343
|
+
PORT = pick_a_port(parsed_args, WEBDIFF_CONFIG)
|
|
344
|
+
HOSTNAME = (
|
|
345
|
+
parsed_args.get('host')
|
|
346
|
+
or os.environ.get('WEBDIFF_HOST')
|
|
347
|
+
or WEBDIFF_CONFIG['host']
|
|
348
|
+
)
|
|
349
|
+
if HOSTNAME == '<hostname>':
|
|
308
350
|
_hostname = platform.node()
|
|
309
351
|
# platform.node will return empty string if it can't find the hostname
|
|
310
352
|
if not _hostname:
|
|
311
|
-
sys.stderr.write('Warning: hostname could not be determined')
|
|
353
|
+
sys.stderr.write('Warning: hostname could not be determined\n')
|
|
312
354
|
else:
|
|
313
355
|
HOSTNAME = _hostname
|
|
314
356
|
|
|
@@ -31,15 +31,23 @@ def parse(args, version=None):
|
|
|
31
31
|
"""Returns {port, dirs: [], files: [], pr: {owner, repo, number}}."""
|
|
32
32
|
parser = argparse.ArgumentParser(description='Run webdiff.', usage=USAGE)
|
|
33
33
|
parser.add_argument('--version', action='version', version='webdiff %s' % version)
|
|
34
|
+
parser.add_argument(
|
|
35
|
+
'--host', type=str,
|
|
36
|
+
help="Host name on which to serve webdiff UI. Default is localhost.",
|
|
37
|
+
default=None
|
|
38
|
+
)
|
|
34
39
|
parser.add_argument('--port', '-p', type=int, help="Port to run webdiff on.", default=-1)
|
|
35
40
|
parser.add_argument(
|
|
36
41
|
'dirs', type=str, nargs='+', help="Directories to diff, or a github pull request URL."
|
|
37
42
|
)
|
|
38
43
|
args = parser.parse_args(args=args)
|
|
39
44
|
|
|
45
|
+
# TODO: convert out to a dataclass
|
|
40
46
|
out = {}
|
|
41
47
|
if args.port != -1:
|
|
42
48
|
out['port'] = args.port
|
|
49
|
+
if args.host:
|
|
50
|
+
out['host'] = args.host
|
|
43
51
|
|
|
44
52
|
if len(args.dirs) > 2:
|
|
45
53
|
raise UsageError('You must specify two files/dirs (got %d)' % len(args.dirs))
|
|
@@ -54,8 +62,8 @@ def parse(args, version=None):
|
|
|
54
62
|
# Or perhaps something simpler like '#292'?
|
|
55
63
|
m = re.match(PULL_REQUEST_NUM_RE, args.dirs[0])
|
|
56
64
|
if m:
|
|
57
|
-
num =
|
|
58
|
-
owner, repo, num = github_fetcher.get_pr_repo(num)
|
|
65
|
+
num = m.group(1)
|
|
66
|
+
owner, repo, num = github_fetcher.get_pr_repo(int(num))
|
|
59
67
|
|
|
60
68
|
if not owner:
|
|
61
69
|
raise UsageError(
|
|
@@ -87,16 +95,21 @@ def parse(args, version=None):
|
|
|
87
95
|
|
|
88
96
|
# TODO: move into dirdiff?
|
|
89
97
|
def _shim_for_file_diff(a_file, b_file):
|
|
90
|
-
'''
|
|
98
|
+
'''Returns a LocalFileDiff object for a one-file diff.'''
|
|
91
99
|
return LocalFileDiff(
|
|
92
|
-
os.path.dirname(a_file),
|
|
93
|
-
|
|
100
|
+
a_root=os.path.dirname(a_file),
|
|
101
|
+
a_path=a_file,
|
|
102
|
+
b_root=os.path.dirname(b_file),
|
|
103
|
+
b_path=b_file,
|
|
104
|
+
is_move=False, # probably not a move
|
|
105
|
+
)
|
|
94
106
|
|
|
95
107
|
|
|
96
|
-
def diff_for_args(args):
|
|
108
|
+
def diff_for_args(args, webdiff_config):
|
|
97
109
|
'''Returns a list of Diff objects for parsed command line args.'''
|
|
98
110
|
if 'dirs' in args:
|
|
99
|
-
return dirdiff.diff(*args['dirs'])
|
|
111
|
+
# return dirdiff.diff(*args['dirs'])
|
|
112
|
+
return dirdiff.gitdiff(*args['dirs'], webdiff_config)
|
|
100
113
|
|
|
101
114
|
if 'files' in args:
|
|
102
115
|
return [_shim_for_file_diff(*args['files'])]
|