webdiff 1.3.0b1__tar.gz → 1.4.0b2__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.3.0b1 → webdiff-1.4.0b2}/PKG-INFO +24 -9
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/README.md +19 -3
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/pyproject.toml +7 -5
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/app.py +35 -10
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/argparser.py +7 -3
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/diff.py +6 -1
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/dirdiff.py +5 -5
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/github_fetcher.py +2 -2
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/gitwebdiff.py +1 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/codediff.js/codediff.css +56 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/style.css +17 -7
- webdiff-1.4.0b2/webdiff/static/js/file_diff.js +3 -0
- webdiff-1.4.0b2/webdiff/toy.py +26 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/util.py +34 -6
- webdiff-1.3.0b1/webdiff/static/js/file_diff.js +0 -61
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/LICENSE +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/__init__.py +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/githubdiff.py +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/gitwebshow.py +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/localfilediff.py +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/options.py +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/__init__.py +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/codediff.js/googlecode.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/Inconsolata/Inconsolata-Bold.ttf +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/Inconsolata/Inconsolata-Regular.ttf +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/Inconsolata/OFL.txt +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/googlecode.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/inconsolata.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/a11y-dark.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/a11y-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/agate.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/an-old-hope.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/androidstudio.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/arduino-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/arta.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/ascetic.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/atom-one-dark-reasonable.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/atom-one-dark.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/atom-one-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/3024.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/apathy.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/apprentice.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/ashes.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/atelier-cave-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/atelier-cave.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/atelier-dune-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/atelier-dune.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/atelier-estuary-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/atelier-estuary.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/atelier-forest-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/atelier-forest.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/atelier-heath-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/atelier-heath.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/atelier-lakeside-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/atelier-lakeside.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/atelier-plateau-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/atelier-plateau.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/atelier-savanna-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/atelier-savanna.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/atelier-seaside-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/atelier-seaside.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/atelier-sulphurpool-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/atelier-sulphurpool.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/atlas.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/bespin.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/black-metal-bathory.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/black-metal-burzum.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/black-metal-dark-funeral.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/black-metal-gorgoroth.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/black-metal-immortal.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/black-metal-khold.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/black-metal-marduk.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/black-metal-mayhem.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/black-metal-nile.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/black-metal-venom.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/black-metal.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/brewer.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/bright.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/brogrammer.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/brush-trees-dark.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/brush-trees.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/chalk.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/circus.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/classic-dark.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/classic-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/codeschool.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/colors.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/cupcake.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/cupertino.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/danqing.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/darcula.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/dark-violet.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/darkmoss.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/darktooth.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/decaf.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/default-dark.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/default-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/dirtysea.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/dracula.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/edge-dark.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/edge-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/eighties.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/embers.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/equilibrium-dark.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/equilibrium-gray-dark.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/equilibrium-gray-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/equilibrium-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/espresso.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/eva-dim.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/eva.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/flat.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/framer.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/fruit-soda.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/gigavolt.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/github.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/google-dark.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/google-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/grayscale-dark.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/grayscale-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/green-screen.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/gruvbox-dark-hard.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/gruvbox-dark-medium.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/gruvbox-dark-pale.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/gruvbox-dark-soft.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/gruvbox-light-hard.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/gruvbox-light-medium.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/gruvbox-light-soft.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/hardcore.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/harmonic16-dark.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/harmonic16-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/heetch-dark.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/heetch-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/helios.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/hopscotch.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/horizon-dark.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/horizon-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/humanoid-dark.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/humanoid-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/ia-dark.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/ia-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/icy-dark.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/ir-black.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/isotope.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/kimber.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/london-tube.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/macintosh.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/marrakesh.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/materia.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/material-darker.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/material-lighter.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/material-palenight.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/material-vivid.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/material.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/mellow-purple.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/mexico-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/mocha.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/monokai.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/nebula.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/nord.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/nova.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/ocean.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/oceanicnext.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/one-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/onedark.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/outrun-dark.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/papercolor-dark.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/papercolor-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/paraiso.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/pasque.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/phd.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/pico.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/pop.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/porple.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/qualia.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/railscasts.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/rebecca.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/ros-pine-dawn.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/ros-pine-moon.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/ros-pine.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/sagelight.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/sandcastle.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/seti-ui.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/shapeshifter.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/silk-dark.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/silk-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/snazzy.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/solar-flare-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/solar-flare.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/solarized-dark.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/solarized-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/spacemacs.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/summercamp.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/summerfruit-dark.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/summerfruit-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/synth-midnight-terminal-dark.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/synth-midnight-terminal-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/tango.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/tender.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/tomorrow-night.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/tomorrow.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/twilight.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/unikitty-dark.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/unikitty-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/vulcan.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/windows-10-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/windows-10.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/windows-95-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/windows-95.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/windows-high-contrast-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/windows-high-contrast.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/windows-nt-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/windows-nt.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/woodland.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/xcode-dusk.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/base16/zenburn.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/brown-paper.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/brown-papersq.png +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/codepen-embed.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/color-brewer.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/dark.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/default.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/devibeans.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/docco.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/far.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/felipec.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/foundation.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/github-dark-dimmed.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/github-dark.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/github.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/gml.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/googlecode.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/gradient-dark.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/gradient-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/grayscale.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/hybrid.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/idea.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/intellij-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/ir-black.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/isbl-editor-dark.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/isbl-editor-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/kimbie-dark.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/kimbie-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/lightfair.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/lioshi.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/magula.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/mono-blue.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/monokai-sublime.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/monokai.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/night-owl.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/nnfx-dark.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/nnfx-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/nord.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/obsidian.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/panda-syntax-dark.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/panda-syntax-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/paraiso-dark.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/paraiso-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/pojoaque.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/pojoaque.jpg +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/purebasic.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/qtcreator-dark.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/qtcreator-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/rainbow.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/routeros.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/school-book.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/shades-of-purple.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/srcery.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/stackoverflow-dark.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/stackoverflow-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/sunburst.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/tokyo-night-dark.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/tokyo-night-light.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/tomorrow-night-blue.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/tomorrow-night-bright.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/vs.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/vs2015.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/xcode.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/css/themes/xt256.css +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/img/favicon.ico +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/img/sprites.png +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/img/trans_bg.gif +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/js/highlight.min.js +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/static/js/highlight.pack.min.js +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/templates/__init__.py +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/templates/file_diff.html +0 -0
- {webdiff-1.3.0b1 → webdiff-1.4.0b2}/webdiff/unified_diff.py +0 -0
|
@@ -1,28 +1,27 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
2
|
Name: webdiff
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.4.0b2
|
|
4
4
|
Summary: Two-column web-based git difftool
|
|
5
|
-
Home-page: https://github.com/danvk/webdiff/
|
|
6
5
|
License: Apache-2.0
|
|
7
6
|
Keywords: git,difftool,web
|
|
8
7
|
Author: Dan Vanderkam
|
|
9
8
|
Author-email: danvdk@gmail.com
|
|
10
|
-
Requires-Python: >=3.
|
|
9
|
+
Requires-Python: >=3.12,<4.0
|
|
11
10
|
Classifier: Development Status :: 4 - Beta
|
|
12
11
|
Classifier: Environment :: Console
|
|
13
12
|
Classifier: Environment :: Web Environment
|
|
14
13
|
Classifier: Intended Audience :: Developers
|
|
15
14
|
Classifier: License :: OSI Approved :: Apache Software License
|
|
16
15
|
Classifier: Programming Language :: Python :: 3
|
|
17
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
19
16
|
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
18
|
Classifier: Topic :: Software Development :: Version Control
|
|
21
19
|
Requires-Dist: PyGithub (>=2.3.0,<3.0.0)
|
|
22
20
|
Requires-Dist: aiohttp (>=3.9.5,<4.0.0)
|
|
23
21
|
Requires-Dist: binaryornot
|
|
24
22
|
Requires-Dist: pillow
|
|
25
23
|
Requires-Dist: unidiff (>=0.7.4,<0.8.0)
|
|
24
|
+
Project-URL: Homepage, https://github.com/danvk/webdiff/
|
|
26
25
|
Project-URL: Repository, https://github.com/danvk/webdiff/
|
|
27
26
|
Description-Content-Type: text/markdown
|
|
28
27
|
|
|
@@ -107,6 +106,14 @@ You can also use `git webshow` in place of `git show` to show a single commit:
|
|
|
107
106
|
|
|
108
107
|
`git webshow REF` is shorthand for `git webdiff REF^..REF`.
|
|
109
108
|
|
|
109
|
+
Recommended aliases:
|
|
110
|
+
|
|
111
|
+
```bash
|
|
112
|
+
alias gw='git webdiff'
|
|
113
|
+
alias gwh='git webshow head'
|
|
114
|
+
alias gwdm='git webdiff $(git merge-base HEAD main)'
|
|
115
|
+
```
|
|
116
|
+
|
|
110
117
|
## Configuration
|
|
111
118
|
|
|
112
119
|
webdiff can be configured via [`git config`][git config]. To change the syntax highlighting theme, for example:
|
|
@@ -171,8 +178,9 @@ To debug `git webdiff`, run:
|
|
|
171
178
|
To iterate on the PyPI package, run:
|
|
172
179
|
|
|
173
180
|
pip3 uninstall webdiff
|
|
181
|
+
cd ts && yarn build && cd ..
|
|
174
182
|
poetry build
|
|
175
|
-
pip3 install dist/webdiff
|
|
183
|
+
pip3 install dist/webdiff-(latest).tar.gz
|
|
176
184
|
|
|
177
185
|
To publish to pypitest:
|
|
178
186
|
|
|
@@ -183,6 +191,10 @@ And to the real pypi:
|
|
|
183
191
|
|
|
184
192
|
poetry publish
|
|
185
193
|
|
|
194
|
+
You can publish pre-release versions to pypi by adding "bN" to the version number. To install a prerelease with `pipx`, use:
|
|
195
|
+
|
|
196
|
+
pipx install webdiff --pip-args="--pre"
|
|
197
|
+
|
|
186
198
|
See [pypirc][] and [poetry][] docs for details on setting up tokens for pypi.
|
|
187
199
|
|
|
188
200
|
Publication checklist. Do these from _outside_ the webdiff directory:
|
|
@@ -212,13 +224,16 @@ When you run `git webdiff (args)`, it runs:
|
|
|
212
224
|
|
|
213
225
|
This tells `git` to set up two directories and invoke `webdiff leftdir rightdir`.
|
|
214
226
|
|
|
215
|
-
There
|
|
227
|
+
There are two wrinkles here:
|
|
228
|
+
|
|
229
|
+
- `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.
|
|
230
|
+
- `git difftool` cleans up its temporary directories when the main webdiff process terminates. Since webdiff detaches to give you back your terminal, it has to make another copy of the directories (this time without resolving symlinks) to make sure they're still there for the child process.
|
|
216
231
|
|
|
217
232
|
[pypirc]: https://packaging.python.org/specifications/pypirc/
|
|
218
233
|
[Homebrew]: https://brew.sh/
|
|
219
234
|
[ImageMagick]: https://imagemagick.org/index.php
|
|
220
235
|
[git config]: https://git-scm.com/docs/git-config
|
|
221
|
-
[themes]:
|
|
236
|
+
[themes]: https://github.com/danvk/webdiff/tree/main/webdiff/static/css/themes
|
|
222
237
|
[poetry]: https://python-poetry.org/docs/repositories/#publishable-repositories
|
|
223
238
|
[pipx]: https://pipx.pypa.io/stable/
|
|
224
239
|
|
|
@@ -79,6 +79,14 @@ You can also use `git webshow` in place of `git show` to show a single commit:
|
|
|
79
79
|
|
|
80
80
|
`git webshow REF` is shorthand for `git webdiff REF^..REF`.
|
|
81
81
|
|
|
82
|
+
Recommended aliases:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
alias gw='git webdiff'
|
|
86
|
+
alias gwh='git webshow head'
|
|
87
|
+
alias gwdm='git webdiff $(git merge-base HEAD main)'
|
|
88
|
+
```
|
|
89
|
+
|
|
82
90
|
## Configuration
|
|
83
91
|
|
|
84
92
|
webdiff can be configured via [`git config`][git config]. To change the syntax highlighting theme, for example:
|
|
@@ -143,8 +151,9 @@ To debug `git webdiff`, run:
|
|
|
143
151
|
To iterate on the PyPI package, run:
|
|
144
152
|
|
|
145
153
|
pip3 uninstall webdiff
|
|
154
|
+
cd ts && yarn build && cd ..
|
|
146
155
|
poetry build
|
|
147
|
-
pip3 install dist/webdiff
|
|
156
|
+
pip3 install dist/webdiff-(latest).tar.gz
|
|
148
157
|
|
|
149
158
|
To publish to pypitest:
|
|
150
159
|
|
|
@@ -155,6 +164,10 @@ And to the real pypi:
|
|
|
155
164
|
|
|
156
165
|
poetry publish
|
|
157
166
|
|
|
167
|
+
You can publish pre-release versions to pypi by adding "bN" to the version number. To install a prerelease with `pipx`, use:
|
|
168
|
+
|
|
169
|
+
pipx install webdiff --pip-args="--pre"
|
|
170
|
+
|
|
158
171
|
See [pypirc][] and [poetry][] docs for details on setting up tokens for pypi.
|
|
159
172
|
|
|
160
173
|
Publication checklist. Do these from _outside_ the webdiff directory:
|
|
@@ -184,12 +197,15 @@ When you run `git webdiff (args)`, it runs:
|
|
|
184
197
|
|
|
185
198
|
This tells `git` to set up two directories and invoke `webdiff leftdir rightdir`.
|
|
186
199
|
|
|
187
|
-
There
|
|
200
|
+
There are two wrinkles here:
|
|
201
|
+
|
|
202
|
+
- `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.
|
|
203
|
+
- `git difftool` cleans up its temporary directories when the main webdiff process terminates. Since webdiff detaches to give you back your terminal, it has to make another copy of the directories (this time without resolving symlinks) to make sure they're still there for the child process.
|
|
188
204
|
|
|
189
205
|
[pypirc]: https://packaging.python.org/specifications/pypirc/
|
|
190
206
|
[Homebrew]: https://brew.sh/
|
|
191
207
|
[ImageMagick]: https://imagemagick.org/index.php
|
|
192
208
|
[git config]: https://git-scm.com/docs/git-config
|
|
193
|
-
[themes]:
|
|
209
|
+
[themes]: https://github.com/danvk/webdiff/tree/main/webdiff/static/css/themes
|
|
194
210
|
[poetry]: https://python-poetry.org/docs/repositories/#publishable-repositories
|
|
195
211
|
[pipx]: https://pipx.pypa.io/stable/
|
|
@@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api"
|
|
|
4
4
|
|
|
5
5
|
[tool.poetry]
|
|
6
6
|
name = "webdiff"
|
|
7
|
-
version = "1.
|
|
7
|
+
version = "1.4.0b2"
|
|
8
8
|
description = "Two-column web-based git difftool"
|
|
9
9
|
license = "Apache-2.0"
|
|
10
10
|
readme = "README.md"
|
|
@@ -22,10 +22,12 @@ classifiers = [
|
|
|
22
22
|
"Topic :: Software Development :: Version Control"
|
|
23
23
|
]
|
|
24
24
|
# This is generated, so it's in .gitignore. But we need to package it.
|
|
25
|
-
include = [
|
|
25
|
+
include = [
|
|
26
|
+
{ path = "webdiff/static/js/file_diff.js", format = ["sdist", "wheel"] }
|
|
27
|
+
]
|
|
26
28
|
|
|
27
29
|
[tool.poetry.dependencies]
|
|
28
|
-
python = "^3.
|
|
30
|
+
python = "^3.12"
|
|
29
31
|
binaryornot = "*"
|
|
30
32
|
pillow = "*"
|
|
31
33
|
PyGithub = "^2.3.0"
|
|
@@ -33,8 +35,8 @@ unidiff = "^0.7.4"
|
|
|
33
35
|
aiohttp = "^3.9.5"
|
|
34
36
|
|
|
35
37
|
[tool.poetry.group.dev.dependencies]
|
|
36
|
-
pytest = "^
|
|
37
|
-
ruff = "0.
|
|
38
|
+
pytest = "^9.0"
|
|
39
|
+
ruff = "^0.15"
|
|
38
40
|
|
|
39
41
|
[tool.poetry.scripts]
|
|
40
42
|
webdiff = "webdiff.app:run"
|
|
@@ -13,6 +13,7 @@ import os
|
|
|
13
13
|
import platform
|
|
14
14
|
import signal
|
|
15
15
|
import socket
|
|
16
|
+
import subprocess
|
|
16
17
|
import sys
|
|
17
18
|
import threading
|
|
18
19
|
import time
|
|
@@ -24,6 +25,7 @@ from aiohttp import web
|
|
|
24
25
|
from binaryornot.check import is_binary
|
|
25
26
|
|
|
26
27
|
from webdiff import argparser, diff, options, util
|
|
28
|
+
from webdiff.dirdiff import make_resolved_dir
|
|
27
29
|
|
|
28
30
|
VERSION = importlib.metadata.version('webdiff')
|
|
29
31
|
|
|
@@ -46,6 +48,7 @@ DIFF = None
|
|
|
46
48
|
PORT = None
|
|
47
49
|
HOSTNAME = 'localhost'
|
|
48
50
|
DEBUG = os.environ.get('DEBUG')
|
|
51
|
+
DEBUG_DETACH = os.environ.get('DEBUG_DETACH')
|
|
49
52
|
WEBDIFF_DIR = determine_path()
|
|
50
53
|
|
|
51
54
|
if DEBUG:
|
|
@@ -273,15 +276,8 @@ def pick_a_port(args, webdiff_config):
|
|
|
273
276
|
|
|
274
277
|
|
|
275
278
|
def run_http():
|
|
276
|
-
sys.stderr.write(
|
|
277
|
-
"""Serving diffs on http://%s:%s
|
|
278
|
-
Close the browser tab or hit Ctrl-C when you're done.
|
|
279
|
-
"""
|
|
280
|
-
% (HOSTNAME, PORT)
|
|
281
|
-
)
|
|
282
279
|
threading.Timer(0.1, open_browser).start()
|
|
283
|
-
|
|
284
|
-
web.run_app(app, host=HOSTNAME, port=PORT)
|
|
280
|
+
web.run_app(app, host=HOSTNAME, port=PORT, print=print if DEBUG else None)
|
|
285
281
|
logging.debug('http server shut down')
|
|
286
282
|
|
|
287
283
|
|
|
@@ -291,7 +287,7 @@ def maybe_shutdown():
|
|
|
291
287
|
|
|
292
288
|
def shutdown():
|
|
293
289
|
if LAST_REQUEST_MS <= last_ms: # subsequent requests abort shutdown
|
|
294
|
-
|
|
290
|
+
logging.debug('Shutting down...')
|
|
295
291
|
signal.raise_signal(signal.SIGINT)
|
|
296
292
|
else:
|
|
297
293
|
logging.debug('Received subsequent request; shutdown aborted.')
|
|
@@ -334,7 +330,36 @@ def run():
|
|
|
334
330
|
else:
|
|
335
331
|
HOSTNAME = _hostname
|
|
336
332
|
|
|
337
|
-
|
|
333
|
+
run_in_process = os.environ.get('WEBDIFF_RUN_IN_PROCESS') or (
|
|
334
|
+
DEBUG and not DEBUG_DETACH
|
|
335
|
+
)
|
|
336
|
+
|
|
337
|
+
if not os.environ.get('WEBDIFF_LOGGED_MESSAGE'):
|
|
338
|
+
# Printing this in the main process gives you your prompt back more cleanly.
|
|
339
|
+
print(
|
|
340
|
+
"""Serving diffs on http://%s:%s
|
|
341
|
+
Close the browser tab when you're done to terminate the process."""
|
|
342
|
+
% (HOSTNAME, PORT)
|
|
343
|
+
)
|
|
344
|
+
os.environ['WEBDIFF_LOGGED_MESSAGE'] = '1'
|
|
345
|
+
|
|
346
|
+
if run_in_process:
|
|
347
|
+
run_http()
|
|
348
|
+
else:
|
|
349
|
+
os.environ['WEBDIFF_RUN_IN_PROCESS'] = '1'
|
|
350
|
+
os.environ['WEBDIFF_PORT'] = str(PORT)
|
|
351
|
+
if os.environ.get('WEBDIFF_FROM_GIT_DIFFTOOL'):
|
|
352
|
+
# git difftool will clean up these directories when we detach.
|
|
353
|
+
# To make them accessible to the child process, we make a (shallow) copy.
|
|
354
|
+
assert 'dirs' in parsed_args
|
|
355
|
+
dir_a, dir_b = parsed_args['dirs']
|
|
356
|
+
copied_dir_a = make_resolved_dir(dir_a)
|
|
357
|
+
copied_dir_b = make_resolved_dir(dir_b)
|
|
358
|
+
os.environ['WEBDIFF_DIR_A'] = copied_dir_a
|
|
359
|
+
os.environ['WEBDIFF_DIR_B'] = copied_dir_b
|
|
360
|
+
logging.debug(f'Copied {dir_a} -> {copied_dir_a} before detaching')
|
|
361
|
+
logging.debug(f'Copied {dir_b} -> {copied_dir_b} before detaching')
|
|
362
|
+
subprocess.Popen((sys.executable, *sys.argv))
|
|
338
363
|
|
|
339
364
|
|
|
340
365
|
if __name__ == '__main__':
|
|
@@ -4,9 +4,7 @@ import argparse
|
|
|
4
4
|
import os
|
|
5
5
|
import re
|
|
6
6
|
|
|
7
|
-
from webdiff import dirdiff
|
|
8
|
-
from webdiff import githubdiff
|
|
9
|
-
from webdiff import github_fetcher
|
|
7
|
+
from webdiff import dirdiff, github_fetcher, githubdiff
|
|
10
8
|
from webdiff.localfilediff import LocalFileDiff
|
|
11
9
|
|
|
12
10
|
|
|
@@ -81,6 +79,12 @@ def parse(args, version=None):
|
|
|
81
79
|
|
|
82
80
|
else:
|
|
83
81
|
a, b = args.dirs
|
|
82
|
+
if os.environ.get('WEBDIFF_DIR_A') and os.environ.get('WEBDIFF_DIR_B'):
|
|
83
|
+
# This happens when you run "git webdiff" and we have to make a copy of
|
|
84
|
+
# the temp directories before we detach and git difftool cleans them up.
|
|
85
|
+
a = os.environ.get('WEBDIFF_DIR_A')
|
|
86
|
+
b = os.environ.get('WEBDIFF_DIR_B')
|
|
87
|
+
|
|
84
88
|
for x in (a, b):
|
|
85
89
|
if not os.path.exists(x):
|
|
86
90
|
raise UsageError('"%s" does not exist' % x)
|
|
@@ -42,7 +42,12 @@ def fast_num_lines(path: str) -> int:
|
|
|
42
42
|
# See https://stackoverflow.com/q/9629179/388951 for the idea to use a Unix command.
|
|
43
43
|
# Unfortunately `wc -l` ignores the last line if there is no trailing newline. So
|
|
44
44
|
# instead, see https://stackoverflow.com/a/38870057/388951
|
|
45
|
-
|
|
45
|
+
try:
|
|
46
|
+
return int(subprocess.check_output(['grep', '-c', '', path]))
|
|
47
|
+
except subprocess.CalledProcessError as e:
|
|
48
|
+
if e.returncode == 1:
|
|
49
|
+
return 0 # grep -c returns an error code if there are no matches
|
|
50
|
+
raise
|
|
46
51
|
|
|
47
52
|
|
|
48
53
|
def get_diff_ops(
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Compute the diff between two directories on local disk."""
|
|
2
2
|
|
|
3
|
-
import os
|
|
4
3
|
import logging
|
|
4
|
+
import os
|
|
5
5
|
import shutil
|
|
6
6
|
import subprocess
|
|
7
7
|
import tempfile
|
|
@@ -27,7 +27,7 @@ def contains_symlinks(dir: str):
|
|
|
27
27
|
return False
|
|
28
28
|
|
|
29
29
|
|
|
30
|
-
def make_resolved_dir(dir: str) -> str:
|
|
30
|
+
def make_resolved_dir(dir: str, follow_symlinks=False) -> str:
|
|
31
31
|
# TODO: clean up this directory
|
|
32
32
|
temp_dir = tempfile.mkdtemp(prefix='webdiff')
|
|
33
33
|
for root, dirs, files in os.walk(dir):
|
|
@@ -38,7 +38,7 @@ def make_resolved_dir(dir: str) -> str:
|
|
|
38
38
|
src_file = os.path.join(root, file_name)
|
|
39
39
|
rel = os.path.relpath(src_file, dir)
|
|
40
40
|
dst_file = os.path.join(temp_dir, rel)
|
|
41
|
-
shutil.copy(src_file, dst_file, follow_symlinks=
|
|
41
|
+
shutil.copy(src_file, dst_file, follow_symlinks=follow_symlinks)
|
|
42
42
|
return temp_dir
|
|
43
43
|
|
|
44
44
|
|
|
@@ -49,11 +49,11 @@ def gitdiff(a_dir: str, b_dir: str, webdiff_config):
|
|
|
49
49
|
cmd += ' ' + extra_args
|
|
50
50
|
a_dir_nosym = a_dir
|
|
51
51
|
if contains_symlinks(a_dir):
|
|
52
|
-
a_dir_nosym = make_resolved_dir(a_dir)
|
|
52
|
+
a_dir_nosym = make_resolved_dir(a_dir, follow_symlinks=True)
|
|
53
53
|
logging.debug(f'Inlined symlinks in left directory {a_dir} -> {a_dir_nosym}')
|
|
54
54
|
b_dir_nosym = b_dir
|
|
55
55
|
if contains_symlinks(b_dir):
|
|
56
|
-
b_dir_nosym = make_resolved_dir(b_dir)
|
|
56
|
+
b_dir_nosym = make_resolved_dir(b_dir, follow_symlinks=True)
|
|
57
57
|
logging.debug(f'Inlined symlinks in right directory {b_dir} -> {b_dir_nosym}')
|
|
58
58
|
args = cmd.split(' ') + [a_dir_nosym, b_dir_nosym]
|
|
59
59
|
logging.debug('Running git command: %s', args)
|
|
@@ -6,11 +6,11 @@ This will create symlinks or clone git repos as needed.
|
|
|
6
6
|
# Use this PR for testing to see all four types of change at once:
|
|
7
7
|
# https://github.com/danvk/test-repo/pull/2/
|
|
8
8
|
|
|
9
|
-
from collections import OrderedDict
|
|
10
9
|
import os
|
|
11
10
|
import re
|
|
12
11
|
import subprocess
|
|
13
12
|
import sys
|
|
13
|
+
from collections import OrderedDict
|
|
14
14
|
|
|
15
15
|
from github import Github, UnknownObjectException
|
|
16
16
|
|
|
@@ -138,7 +138,7 @@ def _get_github_remotes():
|
|
|
138
138
|
|
|
139
139
|
# e.g. 'origin git@github.com:danvk/expandable-image-grid.git (push)'
|
|
140
140
|
ssh_push_re = re.compile(
|
|
141
|
-
'(?P<name>[^\s]+)\s+((?P<user>[^@]+)@)?(?P<host>[^:]+)(?::(?P<path>[^\s]+))?\s\(push\)'
|
|
141
|
+
r'(?P<name>[^\s]+)\s+((?P<user>[^@]+)@)?(?P<host>[^:]+)(?::(?P<path>[^\s]+))?\s\(push\)'
|
|
142
142
|
)
|
|
143
143
|
|
|
144
144
|
# e.g. 'origin https://github.com/danvk/git-helpers.git (push)'
|
|
@@ -21,6 +21,7 @@ def run(argv=sys.argv):
|
|
|
21
21
|
if not os.environ.get('DEBUG')
|
|
22
22
|
else os.path.join(os.path.curdir, 'test.sh')
|
|
23
23
|
)
|
|
24
|
+
os.environ['WEBDIFF_FROM_GIT_DIFFTOOL'] = '1'
|
|
24
25
|
subprocess.call(f'git difftool -d -x {cmd}'.split(' ') + argv[1:])
|
|
25
26
|
except KeyboardInterrupt:
|
|
26
27
|
# Don't raise an exception to the user when sigint is received
|
|
@@ -66,6 +66,12 @@ table.diff tr.skip-row td {
|
|
|
66
66
|
padding: 0.5em;
|
|
67
67
|
}
|
|
68
68
|
|
|
69
|
+
/* Partially collapse empty sides of diffs */
|
|
70
|
+
.diff.diff-add td.before,
|
|
71
|
+
.diff.diff-delete td.after {
|
|
72
|
+
width: 51ch;
|
|
73
|
+
}
|
|
74
|
+
|
|
69
75
|
.line-no, .code {
|
|
70
76
|
padding: 2px;
|
|
71
77
|
height: 1.11em;
|
|
@@ -154,3 +160,53 @@ span.skip {
|
|
|
154
160
|
-ms-user-select: text;
|
|
155
161
|
user-select: text;
|
|
156
162
|
}
|
|
163
|
+
|
|
164
|
+
a, a:visited {
|
|
165
|
+
text-decoration: none;
|
|
166
|
+
color: #00a;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
tr.skip-row {
|
|
170
|
+
position: relative;
|
|
171
|
+
line-height: 1.5em;
|
|
172
|
+
}
|
|
173
|
+
.skip.right {
|
|
174
|
+
position: absolute;
|
|
175
|
+
}
|
|
176
|
+
.skip.right {
|
|
177
|
+
right: 32px;
|
|
178
|
+
}
|
|
179
|
+
.skip.expand-up, .skip.expand-down {
|
|
180
|
+
font-size: 12px;
|
|
181
|
+
font-family: Inconsolata, Consolas, "Liberation Mono", Menlo, Courier, monospace;
|
|
182
|
+
color: #aaa;
|
|
183
|
+
background: #fff;
|
|
184
|
+
border: 1px solid #e8e8e8;
|
|
185
|
+
padding: 0px 5px;
|
|
186
|
+
cursor: pointer;
|
|
187
|
+
white-space: nowrap;
|
|
188
|
+
display: inline-block;
|
|
189
|
+
line-height: 1.3;
|
|
190
|
+
letter-spacing: 0.04em;
|
|
191
|
+
}
|
|
192
|
+
.skip.expand-up:hover, .skip.expand-down:hover {
|
|
193
|
+
background: #f5f5f5;
|
|
194
|
+
color: #888;
|
|
195
|
+
border-color: #ccc;
|
|
196
|
+
}
|
|
197
|
+
/* tab hangs down from the row above: no top border, rounded bottom corners */
|
|
198
|
+
.skip.expand-up {
|
|
199
|
+
top: 0;
|
|
200
|
+
border-top: none;
|
|
201
|
+
border-radius: 0 0 4px 4px;
|
|
202
|
+
}
|
|
203
|
+
/* tab sticks up from the row below: no bottom border, rounded top corners */
|
|
204
|
+
.skip.expand-down {
|
|
205
|
+
bottom: 0;
|
|
206
|
+
border-bottom: none;
|
|
207
|
+
border-radius: 4px 4px 0 0;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
a.show-more {
|
|
211
|
+
color: #888;
|
|
212
|
+
}
|
|
@@ -44,6 +44,10 @@ td.code {
|
|
|
44
44
|
width: 101ch; /* per-side max line length */
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
.code.equal.expanded {
|
|
48
|
+
background-color: #f7f7f7;
|
|
49
|
+
}
|
|
50
|
+
|
|
47
51
|
.file-selector {
|
|
48
52
|
padding-bottom: 5px;
|
|
49
53
|
border-bottom: 1px solid #ccc;
|
|
@@ -106,29 +110,30 @@ ul.file-list {
|
|
|
106
110
|
.side-a { border: 1px solid red; }
|
|
107
111
|
.side-b { border: 1px solid green; }
|
|
108
112
|
|
|
109
|
-
|
|
113
|
+
/* Per-file type diff controls: image diff mode, JSON normalization */
|
|
114
|
+
.diff-mode-controls {
|
|
110
115
|
text-align: center;
|
|
111
116
|
background-color: #f7f7f7;
|
|
112
117
|
padding: 5px;
|
|
113
118
|
}
|
|
114
|
-
.
|
|
119
|
+
.diff-mode-controls > input {
|
|
115
120
|
margin-left: 20px;
|
|
116
121
|
}
|
|
117
|
-
.
|
|
122
|
+
.diff-mode-controls a {
|
|
118
123
|
text-decoration: none;
|
|
119
124
|
}
|
|
120
|
-
.
|
|
125
|
+
.diff-mode-controls a, .diff-mode-controls a:visited {
|
|
121
126
|
color: #666;
|
|
122
127
|
}
|
|
123
|
-
.
|
|
128
|
+
.diff-mode-controls b {
|
|
124
129
|
color: black;
|
|
125
130
|
}
|
|
126
|
-
.
|
|
131
|
+
.diff-mode-controls .mode {
|
|
127
132
|
padding-left: 5px;
|
|
128
133
|
padding-right: 5px;
|
|
129
134
|
border-right: 1px solid #ccc;
|
|
130
135
|
}
|
|
131
|
-
.
|
|
136
|
+
.diff-mode-controls .mode:last-child {
|
|
132
137
|
border-right: none;
|
|
133
138
|
}
|
|
134
139
|
|
|
@@ -245,3 +250,8 @@ kbd {
|
|
|
245
250
|
list-style-type: none;
|
|
246
251
|
margin-bottom: 2px;
|
|
247
252
|
}
|
|
253
|
+
|
|
254
|
+
.suppressed-large-diff {
|
|
255
|
+
text-align: center;
|
|
256
|
+
background-color: lightyellow;
|
|
257
|
+
}
|