installSoftware

This commit is contained in:
Geoffrey Frogeye 2019-10-24 19:35:00 +02:00
parent 10f8511294
commit 1b104be690
4 changed files with 677 additions and 294 deletions

View file

@ -2,307 +2,29 @@
# Installs user preferences the way I like it
# Configuration
function prompt { # text
while true; do
read -p "$1 [yn] " yn
case $yn in
[Yy]* ) return 1;;
[Nn]* ) return 0;;
* ) echo "Please answer yes or no.";;
esac
done
}
# NOTE In the process of migrating to a new install workflow.
# This holds stuff that have not been migrated yet.
# TODO A lot of stuff
# Don't ask for things that are already there
TERMUX=0
if [ -d /data/data/com.termux/files ]; then
TERMUX=1
GUI=0
fi
cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1
. softwareList
if which i3 &> /dev/null; then
GUI=1
fi
if [ -z $ADMIN ]; then
prompt "Are you a superuser on this machine?"
ADMIN=$?
fi
if [ -z $GUI ]; then
prompt "Do you want a X environment on this machine?"
GUI=$?
fi
if [ -z $EXTRA ]; then
prompt "Do you want not-so-needed software on this machine?"
EXTRA=$?
fi
# TODO Verify if the package exists before installing it
# System detection
if which pacman &> /dev/null; then
ARCH=1
if [ $ADMIN == 1 ]; then
sudo pacman -Sy
function installOne { # package
pacman -Q $1 &> /dev/null
if [ $? == 1 ]; then
sudo pacman -S $1 --noconfirm --needed
fi
}
function installFileOne { # file
sudo pacman -U "$1"
}
if which aurman &> /dev/null; then
function altInstallOne { # package
pacman -Q $1 &> /dev/null
if [ $? == 1 ]; then
aurman -S "$1" --noconfirm --noedit
fi
}
elif which pacaur &> /dev/null; then
function altInstallOne { # package
pacman -Q $1 &> /dev/null
if [ $? == 1 ]; then
pacaur -S "$1" --noconfirm --noedit
fi
}
elif which yaourt &> /dev/null; then
function altInstallOne { # package
pacman -Q $1 &> /dev/null
if [ $? == 1 ]; then
yaourt -S "$1" --noconfirm
fi
}
else
# Install package from PKGBUILD file
function installPKGBUILD { # url
TMP_DIR="$(mktemp -d /tmp/pkgbuild.XXXXXXXXXX)"
cd "$TMP_DIR"
wget "$1" -O PKGBUILD
makepkg -si
cd -
rm -rf "$TMP_DIR"
}
function altInstallOne { # package
pacman -Q $1 &> /dev/null
if [ $? == 1 ]; then
installPKGBUILD "https://aur.archlinux.org/cgit/aur.git/plain/PKGBUILD?h=$1"
fi
}
fi
else
echo "You're on a Arch System but it's not yours? Did Arch got that popular?"
return 42
fi
elif which dpkg &> /dev/null; then
DEBIAN=1
if [[ $ADMIN == 1 || $TERMUX == 1 ]]; then
if [ $TERMUX == 1 ]; then
DEBIAN=0
apt update -y
else
sudo apt-get update -y
fi
function installOne { # package
# Finding out if it's already installed or not
STATUS=$(mktemp)
LANG=C dpkg-query --status $1 &> $STATUS
installed=0
if [ $? == 0 ]; then
cat $STATUS | grep '^Status:' | grep ' installed' --quiet
if [ $? == 0 ]; then
installed=1
fi
fi
rm -f $STATUS > /dev/null
# Installing if it's not installed
if [ $installed == 0 ]; then
# TODO noconfirm
if [ $TERMUX == 1 ]; then
apt install $1 -y
else
sudo apt-get install $1 -y
fi
fi
}
function installFileOne { # file
dpkg -i "$1"
}
else
function installOne { # package
debloc install $1
}
function installFileOne { # file
debloc deb "$1"
}
fi
function altInstallOne {
echo "[ERROR] There's no alternate installer for this distribution. Can't install $1."
}
else
echo "Uuuh, what kind of distribution is this?"
return 1
fi
# Install package with the standard
# package manager for the distribution
function inst {
for pkg in $*; do
installOne $pkg
done
}
# Install package FILE with the standard
# package manager for the distribution
function instFile {
for pkg in $*; do
installFileOne $pkg
done
}
# Install package with the alternate
# package manager for the distribution
function altInst {
for pkg in $*; do
altInstallOne $pkg
done
}
function systemdUserUnit {
systemctl --user enable "$1"
systemctl --user start "$1"
}
# Common CLI
echo "Doing stuff cuz"
changeColors monokai
# Utils
if [ $TERMUX == 1 ]; then
inst coreutils man openssl-tool grep sed sh tar
inst termux-api
if [ $ADMIN == 1 ]; then
inst tsu
fi
fi
inst moreutils screen ncdu lsof htop proxytunnel pv curl wget socat mosh bash-completion rsync pwgen fzf highlight
# TODO Test those who are on Debian machines and those who aren't
if [ $ARCH == 1 ]; then
inst bash-completion
altInst gopass
else
inst pass
fi
# Dev
if [ $DEBIAN == 1 ]; then
inst build-essential
elif [ $ARCH == 1 ]; then
inst base-devel
else
inst make
fi
inst git
# Text editor
inst neovim
if [ $DEBIAN == 1]; then
inst python-neovim pyhon3-neovim
elif [ $ARCH == 1]; then
inst python2-neovim python-neovim
fi
if [ $DEBIAN == 1 ]; then
inst exuberant-ctags
else
inst ctags
fi
vim +PlugUpgrade +PlugUpdate +PlugInstall +qall
# Common GUI
if [ $GUI == 1 ]; then
.Xresources.d/configure
### RECYCLE BIN
# Help yourself
# Desktop manager
inst dunst feh i3-wm i3lock numlockx qutebrowser rofi rxvt-unicode scrot trayer unclutter xautolock xclip
if [ $ARCH == 1 ]; then
inst xorg-xinit xorg-xbacklight ttf-dejavu autorandr
altInst lemonbar-xft-git keynav-enhanced pacmixer rofi-pass
elif [ $DEBIAN == 1 ]; then
# TODO autorandr pacmixer rofi-pass ttf-dejavu
inst lemonbar keynav xbacklight
fi
# Screen filter
if [ $ARCH == 1 ]; then
altInst sct
elif [ $TERMUX != 1 ]; then
if [ ! -f $HOME/.local/bin/sct ]; then
TMP=$(mktemp /tmp/XXXXXXXXXX.c)
wget https://gist.githubusercontent.com/ajnirp/208c03d3aa7f02c743d2/raw/55bf3eed25739173d8be57b5179ed5542cf40ed6/sct.c -O $TMP
cc $TMP --std=c99 -lX11 -lXrandr -o $HOME/.local/bin/sct
rm $TMP
fi
fi
fi
# # translate-shell
# curl -L git.io/trans > ~/.local/bin/trans
# chmod +x ~/.local/bin/trans
if [ $EXTRA == 1 ]; then
# Extra dev (not on mobile though ^^)
if [ $TERMUX == 0 ]; then
inst cmake clang llvm ccache python-pip gdb
fi
# Extra CLI
inst ffmpeg optipng syncthing mutt msmtp notmuch mbsync jq lynx strace
inst unzip unrar jdupes bedup p7zip
inst youtube-dl megatools speedtest-cli
systemdUserUnit syncthing
if [ $ARCH == 1 ]; then
insta pandoc youtube-dl translate-shell imagemagick
altInst insect pdftk visidata
# Orga
# TODO For others
inst vdirsyncer khard todoman offlineimap khal
systemdUserUnit vdirsyncer.timer
elif [ $DEBIAN == 1]; then
inst pandoc pdftk visidata translate-shell youtube-dl
else
# translate-shell
curl -L git.io/trans > ~/.local/bin/trans
chmod +x ~/.local/bin/trans
# TODO Others
fi
# FPGA goodness
if [ $ARCH == 1 ]; then
inst iverilog
altInst ghdl
fi
# Extra GUI
if [ $GUI == 1 ]; then
inst vlc gimp inkscape mpd thunar musescore llpp pdfpc texlive-{most,lang}
if [ $ARCH == 1 ]; then
inst simplescreenrecorder mpc
altInst vimpc-git ashuffle-git ttf-emojione-color puddletag
# FPGA goodness
inst gtkwave
fi
# TODO Others
fi
fi
# # sct
# TMP=$(mktemp /tmp/XXXXXXXXXX.c)
# wget https://gist.githubusercontent.com/ajnirp/208c03d3aa7f02c743d2/raw/55bf3eed25739173d8be57b5179ed5542cf40ed6/sct.c -O $TMP
# cc $TMP --std=c99 -lX11 -lXrandr -o $HOME/.local/bin/sct
# rm $TMP

331
config/scripts/installSoftware Executable file
View file

@ -0,0 +1,331 @@
#!/usr/bin/env sh
# set -x
# Allows to install software
# Find list of available installers in order of preference
# Read wanted packages and their availability
# Install packages per installer (after prompting)
# COMMON FUNCTIONS
# GLOBAL VARIABLES
# TODO Lock or temp folder
CACHE_DIR="${XDG_CACHE_DIR:-$HOME/.cache}/installSoftware"
INSTALLERS_DIR="${CACHE_DIR}/installers"
INSTALLERS_LIST="${CACHE_DIR}/installers.list"
# INSTALLER SPECIFIC FUNCTIONS
# Test if available
available_pkgbuild() {
true
}
# Update the database
update_Rpacman() {
sudo pacman -Syu --noconfirm
}
update_Ryay() {
yay -Syu --noconfirm --devel
}
update_Rapt() {
# TODO non-interactive
sudo apt update -y
sudo apt upgrade -y
}
# Test if installed
installed_Rpacman() { # packageName
pacman -Qq "$1" &> /dev/null
}
installed_Ryay() { # package
installed_Rpacman "$@"
}
installed_pip() { # package
pip show "$@" > /dev/null
}
installed_makepkg() { # package
installed_Rpacman "$@"
}
installed_pkgbuild() { # package
installed_Rpacman "$@"
# TODO Might need all the systems package too
}
installed_Rapt() {
STATUS=$(mktemp)
LANG=C dpkg-query --status $1 &> $STATUS
installed=0
if [ $? == 0 ]; then
cat $STATUS | grep '^Status:' | grep ' installed' --quiet
if [ $? == 0 ]; then
installed=1
fi
fi
rm -f $STATUS > /dev/null
return $installed
}
# Test if available in the repositories
installable_aur() {
curl --fail --silent --head "https://aur.archlinux.org/packages/$@" > /dev/null
}
installable_Rpacman() {
pacman -Ss "$1" > /dev/null
}
installable_Ryay() {
# yay -Ss "$1" > /dev/null
installable_aur
}
installable_pkgbuild() {
installable_aur
}
installable_makepkg() {
installable_aur
}
# Tell if it hadles mutiple argument for install
multiinstall_pacman() {
true
}
multiinstall_pip() {
true
}
multiinstall_apt() {
true
}
# Really install
install_Rpacman() {
sudo pacman -S --needed --noconfirm $@
}
install_Ryay() {
yay -S --needed --noconfirm $@
}
install_Rapt() {
apt install -y $@
}
install_Rpip() {
sudo pip install $@
}
install_Upip() {
pip install --user $@
}
installable_Rmakepkg() {
old_pwd="$PWD"
TMP_DIR="$(mktemp -d /tmp/pkgbuild.XXXXXXXXXX)"
cd "$TMP_DIR"
wget "https://aur.archlinux.org/cgit/aur.git/snapshot/$1.tar.gz"
tar xzvf "$1.tar.gz"
cd "$1"
makepkg -si
cd "$old_pwd"
rm -rf "$TMP_DIR"
}
# GENERIC INSTALLER FUNCTIONS
installerCanonicalName() { # installerName
echo "${1:1}"
}
notImplementedFallback() { # command installerName
echo "[NIMPL] Not implemented: command $1_$2"
false
}
# Wrapper to run a command for an installer
commandInstaller() { # command installerName fallback args...
# echo "[DEBUG] commandInstaller $*"
command="$1"
installerName="$2"
fallback="$3"
shift; shift; shift
installerCName="$(installerCanonicalName "$installerName")"
if command -v "${command}_$installerName" > /dev/null
then
"${command}_$installerName" "$@"
elif command -v "${command}_$installerCName" > /dev/null
then
"${command}_$installerCName" "$@"
else
$fallback "$command" "$installerName" "$@"
fi
}
# INSTALLER LIST FUNCTIONS
availableInstallerFallback() { # command installerName
command -v "$(installerCanonicalName "$2")" > /dev/null
}
availableInstaller() { # installerName
commandInstaller "available" "$1" availableInstallerFallback
}
# Clears the list of installers to use
resetInstallers() {
rm -f "$INSTALLERS_LIST"
touch "$INSTALLERS_LIST"
rm -rf "$INSTALLERS_DIR"
mkdir -p "$INSTALLERS_DIR"
}
addInstaller() { # installername
if availableInstaller "$1"
then
echo "$1" >> "$INSTALLERS_LIST"
rm -f "$INSTALLERS_DIR/$1"
touch "$INSTALLERS_DIR/$1"
return 0
fi
return 1
}
listInstallers() {
cat "$INSTALLERS_LIST"
}
hasInstaller() { # installerName
[ -f "${INSTALLERS_DIR}/$1" ]
}
# Installers that install in the user directory
addUserInstallers() {
addInstaller Umakepkg
addInstaller Upip
addInstaller Upkgbuild
}
# Installers that install with the system package manager
addSystemInstallers() {
addInstaller Rapt
addInstaller Rpacman
addInstaller Ryay || addInstaller Rmakepkg
}
# Installers that install in the system root but not tracked with system package manager
addRootInstallers() {
addInstaller Rnode
addInstaller Rpip
addInstaller Rpkgbuild
}
# UPDATING INSTALLER DATABASES
updateInstallers() {
for installerName in $(listInstallers)
do
commandInstaller "update" "$installerName" true
done
}
# MARKING PACKAGES TO INSTALL
markPackage() { # installer package
# echo "[DEBUG] Marked $*"
echo "$2" >> "$INSTALLERS_DIR/$1"
}
# Test if a package is installed
installedPackage() { # package
for installerName in $(listInstallers)
do
if commandInstaller "installed" "$installerName" notImplementedFallback "$1"
then
return 0
fi
done
return 1
}
installablePackageBy() { # installer package
commandInstaller "installable" "$1" notImplementedFallback "$2"
}
# List packages to install by given installer
listPackagesForInstaller() { # installer
cat "$INSTALLERS_DIR/$1"
}
isToInstall() { # package
for installerName in $(listInstallers)
do
listPackagesForInstaller "$installerName" | grep -q "^$1\$" && return 0
done
return 1
}
# Mark package to installer list where available
tryPackage() { # packageNames
# If package is already installed or marked to install, skip
for package in "$@"
do
installedPackage "$package" && return 0
isToInstall "$package" && return 0
done
# For each installer
for installerName in $(listInstallers)
do
# For each name given
for package in "$@"
do
# Mark if name available to installer
if installablePackageBy "$installerName" "$package"
then
markPackage "$installerName" "$package"
return 0
fi
done
done
echo "[ERR] Cannot install package with aliases: $*"
return 1
}
alias i=tryPackage
installPackages() {
for installerName in $(listInstallers)
do
# If we can install multiple packages in one go
if commandInstaller "multiinstall" "$installerName" false
then
packages=$(listPackagesForInstaller "$installerName")
[ -z "$packages" ] && continue
commandInstaller "install" "$installerName" notImplementedFallback $packages
else
for packageName in $(listPackagesForInstaller "$installerName")
do
commandInstaller "install" "$installerName" notImplementedFallback "$packageName"
done
fi
done
}

325
config/scripts/softwareList Executable file
View file

@ -0,0 +1,325 @@
#!/usr/bin/env sh
# List of the software I use divided by categories.
# Oh and it asks the category you want to install on
# the running machine too.
# TODO Not really tested in conditions
# TODO Not tested with Debian derivate
# TODO Not tested on home folder
CONFIG_FILE="${XDG_CONFIG_DIR:=$HOME/.config}/softwareList"
mkdir -p $XDG_CONFIG_DIR
touch $CONFIG_FILE
. $CONFIG_FILE
prompt() { # text
res="none"
while [ "$res" = "none" ]
do
printf "%s [yn] " "$1"
read -r yn
case $yn in
[Yy]* ) return 0;;
[Nn]* ) return 1;;
* ) echo "Please answer y or n.";;
esac
done
}
uservar() { # var text
if [ -z "${!1}" ]
then
prompt "${2}" && res=true || res=false
export "$1"="$res"
echo "$1"="$res" >> "$CONFIG_FILE"
fi
}
echo "Please answer some questions about this machine and what you want to do on it:"
# Setting variables
[ -d /data/data/com.termux/files ] && TERMUX=true || TERMUX=false
$TERMUX && INSTALL_GUI=false
[ "$USER" = "root" ] && SUPERUSER=true
uservar SUPERUSER "Have root permissions?"
uservar INSTALL_GUI "Install a GUI environment?"
$INSTALL_GUI && INSTALL_X=true
INSTALL_WAYLAND=false
uservar INSTALL_PASSWORD "Handle password?"
uservar INSTALL_MAIL "Read/send mail?"
uservar INSTALL_ORGANISATION "Handle agenda/contacts?"
uservar INSTALL_HOUSEKEEPING "Do some housekeeping?"
uservar INSTALL_FPGA "Handle FPGAs?"
uservar INSTALL_UTILITIES "Extra utilities?"
uservar INSTALL_DOCUMENT "Create documents?"
uservar INSTALL_IMAGE "Do image editing?"
uservar INSTALL_MUSIC "Play/edit music?"
uservar INSTALL_VIDEO "Play/edit videos?"
echo "(you can change those answers later in $CONFIG_FILE)"
# Preparing installers
. ./installSoftware
resetInstallers
$SUPERUSER && addSystemInstallers
addUserInstallers
echo "Installers that will be used:"
listInstallers | sed 's/^/- /'
echo "Updating databases & packages"
# updateInstallers # DEBUG put back
echo "Finding packages to install"
# Note: i A B: will try A then B for each installer
# i A || i B: will try A for each installer, then B for each installer
# Package managers (install first)
i yay
i python-pip python3-pip pip3
# TODO Install first and recharge installers
# Utils used by those scripts
i base coreutils # Basic shell commands (ls, rm, cp...)
i bash # Shell
i grep # Text finder
i sed # Text replacer
i tar # Archive tool
i openssl openssl-tools # machines script verification
# Various utilities
$SUPERUSER && i sudo tsu
$TERMUX && termux-api
# Shell utilities
i moreutils # Advanced shell commands (ts, sponge...)
i tmux # Terminal multiplexer
i bash-completion # Shell completions
i fzf # Fancy file finder
i highlight # Syntax highlighter
i zsh # Shell
i zsh-autosuggestions # Shell suggestions
i zsh-completions # Shell completions
i zsh-history-substring-search # Shell config
i zsh-syntax-highlighting # Shell highlighting
# Text edition
(i neovim nvim && i python-neovim python3-neovim) || i vim || i vi # Text editor
# Monitoring utilities
i ncdu # Explore directories by weight on disk
i lsof # Find who/what uses the files
i htop # List process by resources
i pv # Allow to show progress in pipe
i progress # Show progress of functions
# Network utilities
i proxytunnel # Proxy connections through HTTPS
i curl # Transfer URL
i wget # Download URL
i gnu-netcat # Network piping
i socat # Multi-purpose relay
i rsync # Remote file-copying tool
i speedtest-cli # Network speed benchmarker
# Archives utilities
i unzip # Unarchive ZIP files
i unrar # Unarchive RAR files
i p7zip # Unarchive 7z files
# Password handling
if $INSTALL_PASSWORD
then
i pwgen # Password generator
i gopass || i pass # Password manager
if $INSTALL_GUI
then
i rofi-pass # Password selector
fi
fi
if $INSTALL_MAIL
then
# i offlineimap # Synchronize IMAP (legacy)
i isync mbsync # Synchronize IMAP
i msmtp # Send mail via SMTP
i notmuch # Index mail
i neomutt || i mutt # CLI mail client
i lynx # CLI web browser (for HTML mail)
if $INSTALL_GUI
then
i thunderbird # GUI mail client (just in case)
fi
fi
if $INSTALL_ORGANISATION
then
i vdirsyncer # Synchronize DAV
i khard # Contacts editor
i khal # Calendar editor
i task # Todo-list
i timew # Time-tracker
fi
if $INSTALL_HOUSEKEEPING
then
i syncthing # Synchronize files amongst devices
i jdupes # Find duplicates
i duperemove # Find and merge dupplicates on BTRFS partitions
i optipng # Optimize PNG files
i jpegtran libjpeg-turbo # Compress JPEG files
fi
# Dev utilities
i base-devel build-essential || (i make; i gcc)
i git
[ -z "$INSTALL_DEV" ] && $TERMUX && INSTALL_DEV=false
if $INSTALL_DEV
then
# Misc/Reusable
i strace # Tracer
i ctags universal-ctags exuberant-ctags # Tags generator
# C/C++
i cmake # C++ Build system
i clang # C/C++ Compiler
i ccache # Build cache
i gdb # Debugger
# JS
i jq # CLI JSON file handler
# Python
i python-language-server # Python language server
i mypy && i pyls-mypy # Static typing checker for Python
# Bash
i bash-language-server # Bash / SH language server
fi
if $INSTALL_FPGA
then
i yosys # Verilog processor
i iverilog # Verilog simulator
i ghdl # VHDL simulator
i gtkwave # Simulation file viewer
fi
if $INSTALL_UTILITIES
then
i visidata # CSV file reader
i insect # Unit calculator
fi
if $INSTALL_DOCUMENT
then
i pandoc # Document converter
i texlive-most && i texlive-lang # LaTeX renderer
i pdftk # PDF manipulator
i translate-shell # Translator
i inkscape # Vector image converter
i optipng # Optimize PNG files
i jpegtran libjpeg-turbo # Compress JPEG files
fi
if $INSTALL_IMAGE
then
i imagemagick # CLI Image manipulator
i gimp # Photo editor
i darktable # Raw photo editor
i inkscape # Vectorial image editor
i optipng # Optimize PNG files
i jpegtran libjpeg-turbo # Compress JPEG files
fi
if $INSTALL_MUSIC
then
i mpv # Audio/Video player
i puddletag # Musig tag editor
i mpd # Music player daemon
i mpc # CLI MPD client
i vimpc-git # CLI UI MPD client
i musescore # Music sheet editor
i ashuffle # Auto-fill MPD playlist
fi
if $INSTALL_VIDEO
then
i vlc # Video player
i mpv # Audio/Video player
i ffmpeg # Video/Audio file handler
i youtube-dl # Downloader for videos
i megatools # Downloader for mega.nz
if $INSTALL_X
then
i simplescreenrecorder # Screen recorder
fi
fi
# Desktop environment
if $INSTALL_GUI
then
i firefox # Web browser
i thunar # Directory browser (just in case)
i feh # Background / Image viewer
i zathura && i zathura-pdf-mupdf # PDF viewer
i ttf-twemoji # Emoji fonts
if $INSTALL_X
then
i i3-wm # WM
i dunst # Notifications
i i3lock # Locker
i numlockx # Numlock auto-unlock
i rofi # HUD selector
i rxvt-unicode # Terminal emulator
i scrot # Screenshot taker
i trayer # Tray icons (just in case)
i unclutter # Auto mask mouse
i xautolock # Auto lock screen
i xclip # Copy/paste
i lemonbar-xft-git lemonbar # Bottom bar
i autorandr # Multiple screen configurations
i ttf-dejavu # Font
i keynav-enhanced keynav # Use mouse with keyboard
i pacmixer # To change PA volumes
i sct # Red filter # TODO Autocompile
i xorg-xinit # To launch X
i xorg-xbacklight xbacklight # For laptop brightness
i pulseaudio # To get ausdio
# TODO Bluetooth headset stuff
fi
if $INSTALL_WAYLAND
then
i sway
fi
fi
echo "Listing software to install"
listInstallers | while read -r installerName
do
echo " Installer $installerName will install:"
listPackagesForInstaller "$installerName" | sed 's/^/ - /'
done
prompt "Okay with those?" || exit 0
echo "Installing packages"
installPackages

View file

@ -71,6 +71,8 @@ if len(sys.argv) >= 3:
show_name = sys.argv[2]
else:
show_name = os.path.split(os.path.realpath(os.path.curdir))[1]
if '(' in show_name:
show_name = show_name.split('(')[0].strip()
search = tv.search(show_name)
@ -180,6 +182,9 @@ for association in associations:
if a_basename == basename:
old_path = os.path.join(root, a_filename)
new_path = os.path.join(root, new_name + a_ext)
if old_path == new_path:
continue
print(old_path, "->", new_path)
if not dryrun:
os.rename(old_path, new_path)