Автоматическое удаление файлов pyc при перемещении соответствующего py (Mercurial)
(Я предвидел, что эта проблема может случиться 3 месяца назад, и мне сказали, что она старательна, чтобы ее избежать. Вчера меня сильно укусили, и теперь, когда она стоила мне реальных денег, я очень хочу ее исправить.)
Если я переведу один из исходных файлов Python в другой каталог, мне нужно помнить, что Mercurial он переместил (hg move
).
Когда я развертываю новое программное обеспечение на своем сервере с помощью Mercurial, он тщательно удаляет старый файл Python и создает его в новом каталоге.
Однако Mercurial не знает файл pyc в том же каталоге и оставляет его. Старый pyc используется преимущественно над новым файлом python другими модулями в том же каталоге.
То, что происходит, не является весельем.
Как я могу убедить Mercurial автоматически удалять старый файл pyc при перемещении файла python? Есть ли еще одна лучшая практика? Пытаться запомнить файл pyc из всех хранилищ Mercurial не работает.
Ответы
Ответ 1
Что я на самом деле сделал:
1) Я рассматриваю предложение Николаса Найт об использовании правильной стратегии развертывания. Я читал о Buildout и Collective.hostout узнать больше. Мне нужно решить, нужны ли такие тяжеловесные стратегии для моего проекта относительно простыми требованиями.
2) Я принял концепцию крюка обновления Ry4an в краткосрочной перспективе, пока не решит.
3) Я проигнорировал предупреждение Ry4an о overkill и написал Python script, чтобы удалить только удаленные файлы .pyc.
#!/usr/bin/env python
""" Searches subdirectories of the current directory looking for .pyc files which
do not have matching .py files, and deletes them.
This is useful as a hook for version control when Python files are moved.
It is dangerous for projects that deliberately include Python
binaries without source.
"""
import os
import os.path
for root, dirs, files in os.walk("."):
pyc_files = filter(lambda filename: filename.endswith(".pyc"), files)
py_files = set(filter(lambda filename: filename.endswith(".py"), files))
excess_pyc_files = filter(lambda pyc_filename: pyc_filename[:-1] not in py_files, pyc_files)
for excess_pyc_file in excess_pyc_files:
full_path = os.path.join(root, excess_pyc_file)
print "Removing old PYC file:", full_path
os.remove(full_path)
Теперь мои крючки обновления вызывают это, а не команды "найти", предложенные другими.
Ответ 2
- Не храните файлы .pyc в репозитории.
- Автоматизировать .pyc удалить с помощью: find. -name '*.pyc' -delete
- Разрабатываем использование аргумента -B в Python.
Ответ 3
Как насчет использования крюка обновления на стороне сервера? Поместите это в каталог .hg
каталог hgrc
файл:
[hooks]
update = find . -name '*.pyc' | xargs rm
Это удалит все .pyc файлы при каждом обновлении на сервере. Если вы беспокоитесь о стоимости восстановления всех файлов .pyc, вы всегда можете получить чуть более умный крючок и удалить только .pyc, для которого нет .py, но это, вероятно, перебор.
Ответ 4
Вам нужно:
1) Реальная инфраструктура развертывания, даже если это всего лишь оболочка script, которая делает все. Клонирование/проверка обновленной копии из исходного элемента управления не является стратегией развертывания.
2) Любая система развертывания должна полностью очистить структуру каталогов. Мое обычное предпочтение заключается в том, что каждое развертывание происходит с новым каталогом с именем date + timestamp, а символическая ссылка (с именем типа "текущий" ) обновляется, указывая на новый каталог. Это дает вам панировки на каждом сервере, если что-то пойдет не так.
3) Чтобы исправить все, что работает с кодом Python. Новые исходные файлы .py всегда должны иметь приоритет над кешированными файлами .pyc. Если это не то поведение, которое вы видите, это ошибка, и вам нужно выяснить, почему это происходит.
Ответ 5
Здесь однострочный unix файл, который будет удалять файлы .pyc каждый раз при запуске hg update
.
Добавьте это в свой файл hgrc:
[hooks]
preupdate.cleanpyc = hg status --no-status --removed --deleted --include "**.py" --rev .:$HG_PARENT1 --print0 | xargs -0 -I '{}' rm -f '{}c'
Это выполняется непосредственно перед обновлением и получает все .py файлы, которые будут удалены или удалены при выполнении обновления, а затем удалит соответствующие файлы .pyc.
Вот краткое описание того, как это работает:
hg status --no-status --removed --deleted --include "**.py" --rev .:$HG_PARENT1
Это приведет к удалению всех файлов (например, hg forget
) или удалению (hg rm
, hg mv
и т.д.) между текущей версией .
и пунктом назначения ($HG_PARENT
). Вы можете добавить --subrepos
, чтобы получить все изменения в субрепозиториях, если вы используете эту функцию.
xargs -0 -I '{}' rm -f '{}c'
Это просто добавляет 'c' в конец каждого имени файла, возвращаемого из hg status
, и пытается удалить его. Флаг -f
для rm
гарантирует, что он не является ошибкой, если файл .pyc не существует.
Обратите внимание, что mercurial автоматически удаляет пустые каталоги после обновления, но потерянные .pyc файлы часто приводят к тому, что каталоги остаются. Поскольку это выполняется до обновления, это гарантирует, что пустые каталоги будут удалены правильно.
Ответ 6
Я использую файл .hgignore
, чтобы пропустить версию всех моих .pyc и .py ~ (файлов temp редактора). Например, это моя версия:
# use glob syntax.
syntax: glob
.directory
*.pyc
*~
*.o
*.tgz
*.tbz2
*.gz
*.bz2
Также добавление крюка на обновление для их удаления также является интересным трюком, если вы хотите не только игнорировать шум, но и удалять его из локальной области рабочей области.
Ответ 7
Я использую этот script для удаления файлов .pyc в текущей папке, этот script может использоваться один или включать его в функцию exit для удаления файлов .pyc при выходе u.
import os
files = [f for f in os.listdir('.') if os.path.isfile(f) and '.pyc' in str(f)]
for f in files : os.unlink(os.getcwd()+'/'+f)