2010-03-27 3 views
15

(3 개월 전이 문제가 발생할 수 있음을 예견하고 부지런히 피할 수있게되었습니다.) 어제는 힘들었습니다. 나에게 진짜 돈이 든다. 나는 그것을 고칠 줄 알아야한다.)해당 py를 옮길 때 pyc 파일을 자동으로 삭제합니다 (Mercurial)

파이썬 소스 파일 중 하나를 다른 디렉토리로 옮기면, Mercurial이 (hg move) 이동했다는 것을 기억해야한다.

새로운 소프트웨어를 Mercurial을 사용하여 서버에 배포하면 이전의 Python 파일을 신중하게 삭제하고 새 디렉토리에 생성합니다.

그러나 Mercurial은 같은 디렉토리에있는 pyc 파일을 인식하지 못합니다. 이전 pyc는 동일한 디렉토리의 다른 모듈에 의해 새로운 python 파일보다 우선적으로 사용됩니다.

그 후에 일어나는 일은 우스꽝스럽지 않습니다.

파이썬 파일을 옮길 때 Mercurial이 자동으로 이전 pyc 파일을 삭제하도록 설득 할 수 있습니까? 다른 더 좋은 방법이 있습니까? 모든 Mercurial 리포지토리에서 pyc 파일을 삭제하는 것을 기억하려고 시도하는 것이 효과적이지 않습니다.

답변

3

는 실제로 수행 한 것 :

1) 나는 적절한 배포 전략을 사용하는 방법에 대한 니콜라스 기사의 제안을 고려하고있다. 자세한 내용은 BuildoutCollective.hostout에 대해 읽었습니다. 그러한 중무장 전략이 프로젝트의 상대적으로 간단한 요구 사항에 대해 가치가 있는지 여부를 결정해야합니다.

2) 내가 결정할 때까지 Ry4an의 업데이트 후크 개념을 단기간에 채택했습니다.

3) Ryan이 과잉 공격에 대한 경고를 무시하고 stray .pyc 파일 만 삭제하는 Python 스크립트를 작성했습니다.

#!/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

그게 효과가 있습니다. 원하는 경우 udpate 후크에서 .py 파일을 직접 서브 루틴 호출 할 수 있습니다. 그냥 후크 이름을 지정하고 .py 파일의 경로를 제공하십시오. 이렇게하면 전체 파이썬 VM을 절약 할 수 있습니다. –

+0

감사합니다, Ry4an. 그 제안에 대해 더 많은 담당자를 드릴 수 있기를 바랍니다. – Oddthinking

+1

후자를 위해,이'find' 명령과 sh 루프는 비슷합니다 :'find. -path './virtualenv/*'-prune -or -name '* .pyc'-print | 읽는 동안 f; [[! -f "$ {f %?}"]] && echo "$ f"&& rm "$ f"; done' – Dougal

6

당신이 필요합니다 모든 것을 수행

1) 실제 배포 인프라,이 경우에도 단지 쉘 스크립트를. 원본 컨트롤에서 업데이트 된 복사본을 복제/체크 아웃하는 것은 배포 전략이 아닙니다.

2) 모든 배포 시스템에서 디렉터리 구조를 완전히 정리해야합니다. 필자가 선호하는 것은 각 배포가 date + timestamp라는 이름의 새 디렉토리에 발생하고 symlink ("current"와 같은 이름)가 새 디렉토리를 가리 키도록 업데이트된다는 것입니다. 이로 인해 문제가 발생할 경우 각 서버에 빵 부스러기가 생깁니다.

3) 파이썬 코드를 실행하는 모든 것을 수정하십시오. 새로운 .py 소스 파일은 항상 캐시 된 .pyc 파일보다 우선해야합니다. 그것이 당신이보고있는 행동이 아니라면, 그것은 버그이며, 당신은 그것이 일어나고있는 이유를 알아 내야 할 필요가 있습니다.

+0

파이썬은 쉽습니다. 파이 파일을 복사하고 필요한 모든 것을 복사하고 .pyc 파일은 무시하십시오. – bigredbob

+3

3을 가리키면 .py가 존재하지 않기 때문에 발생하지 않는 이유가 있습니다. .py가 없으면 비교할 시간이없고 python은 .py가없는 pyc만을 무시하지 않습니다. –

+0

친절하게 1)에 정성을 다하십시오. 여기에서 논의 된 .pyc 파일을 제외하고는 "hg pull -u"전략이 잘 작동합니다. 필자는 정확히 하나의 대상 머신을 가지고 있다고 언급해야합니다 (테스트를 위해 여러 저장소가 있지만). 내 스테이징 시스템과 프로덕션 시스템은 동일하지만 서로 다른 계정과 구성 파일을 사용하므로 서로 쾅쾅 거리지 않습니다. 성능, 가용성 및 확장 성은이 프로젝트에서 중요하지 않습니다. – Oddthinking

9

서버 측에 update hook을 사용하는 것은 어떻습니까? 저장소의 .hg 디렉토리의 hgrc 파일이 넣어 : 서버에 업데이트 할 때마다 모든 된 .pyc 파일을 삭제합니다

[hooks] 
update = find . -name '*.pyc' | xargs rm 

합니다. 모든 .pyc 파일을 다시 작성하는 데 대한 비용이 걱정된다면 .py 파일이없는 .pyc 파일 만 삭제할 수 있지만 과장 될 수 있습니다.

+5

찾기. -name '* .pyc'-delete – mkotechno

+0

감사합니다. 이것은 내가 필요한 정보였다. 나는 앞서 가서 지나치게 살폈다. 이 질문에 대한 내 대답을보십시오. – Oddthinking

16
  1. .pyc 파일을 저장소에 저장하지 마십시오.
  2. .pyc 삭제로 자동화 : 찾기. -name '* .pyc'-delete
  3. Python에서 -B 인수를 사용하는 동안 개발.
+3

또한 릴리스의 모든 .pyc 파일을 사전 처리 컴파일하십시오. repo에 태그를 지정하고 프로덕션으로 푸시하는 등 배포합니다. .pyc 파일을 컴파일하면 거기에 적합합니다. 바이너리를 컴파일하는 다른 언어는 태양 아래에서 가장 자연스러운 일입니다. –

+1

1) .pyc 파일을 저장소에 저장하지 않습니다. 2) 나는 명령을 좋아한다. 자세한 내용은 http://stackoverflow.com/questions/785519/remove-all-pyc-files-from-a-project를 참조하십시오. 나는 "automatizing"도움을 찾고 있다고 생각한다. 3) 나는 이것을 보았다. 가져온 모듈에 바이트 코드를 저장하지 않습니까? 왜 안돼? – Oddthinking

+0

질문에 대답하지 않을 때이 답변에 16 개의 상행승이있는 이유는 무엇입니까? – Oddthinking

1

.hgignore 파일을 사용하여 모든 .pyc 및 .py ~ (편집기의 임시 파일)의 버전을 건너 뜁니다. 당신이 소음을 무시하지만, 로컬 작업 영역에서 제거뿐만 아니라 원하는 경우

# use glob syntax. 
syntax: glob 

.directory 
*.pyc 
*~ 
*.o 
*.tgz 
*.tbz2 
*.gz 
*.bz2 

또한 그들을 제거 업데이트에 대한 후크를 추가도 재미있는 트릭 : 예를 들어, 내 버전입니다.

+0

감사합니다, edomaur,하지만 이미 .hgignore 파일이 있습니다 (실제로 두 개의 교차 프로젝트와 다른 프로젝트 관련.) .pyc 파일을 버전 관리하지 않습니다. 그것은 근본적인 문제가 아닙니다. – Oddthinking

+0

좋아요, 당신이 무엇을 목표로하고 있는지 확신 할 수 없었지만 지금은 이해하고 있다고 생각합니다. – edomaur

2

다음은 hg update을 실행할 때마다 .pyc 파일을 삭제하는 유닉스 원 라이너입니다.

당신의 hgrc 파일이 추가 :이 업데이트 바로 전에 실행

[hooks] 
preupdate.cleanpyc = hg status --no-status --removed --deleted --include "**.py" --rev .:$HG_PARENT1 --print0 | xargs -0 -I '{}' rm -f '{}c' 

및 업데이트가 수행 될 때 제거되거나 삭제 될 모든 평 파일을 가져온 다음 파일을 .pyc 파일에 대응 삭제합니다 .

여기 그것이 작동하는 방법의 빠른 고장입니다 :

hg status --no-status --removed --deleted --include "**.py" --rev .:$HG_PARENT1 

이 가져 제거 된 모든 파일 (예를 들어, hg forget) 또는 현재 버전 . 및 대상 ($HG_PARENT) 사이 (hg rm, hg mv 등)을 삭제. 해당 기능을 사용하는 경우 서브 저장소의 모든 변경 사항을 가져 오려면 --subrepos을 추가 할 수 있습니다.

xargs -0 -I '{}' rm -f '{}c' 

이 단순히 hg status에서 반환 된 각 파일 이름의 끝에 'C'를 추가하고 삭제하려고합니다. rm에 대한 -f 플래그는 .pyc 파일이 없으면 오류가 발생하지 않도록합니다.

mercurial은 업데이트 후에 자동으로 빈 디렉토리를 삭제하지만 .phyc 파일이 분리되면 종종 디렉토리가 주위에 남아있게됩니다. 이 파일은 업데이트 전에 실행되기 때문에 빈 디렉토리가 제대로 삭제됩니다.

+0

어떻게 작동하는지 설명해 주시겠습니까? 이전에 Mercurial에 저장되었던 .pyc 파일 만 (제거/삭제 된) 포함하는 것으로 보이지만, .pyc 파일은 Mercurial에 저장되지 않습니다. – Oddthinking

+0

당신 말이 맞아서 오타를 바로 잡았습니다. 지금은 분명해야하지만 좀 더 철저한 설명을 추가했습니다. – chadrik

0

이 스크립트를 사용하여 현재 폴더의 .pyc 파일을 삭제할 수 있습니다.이 스크립트는 단독으로 사용하거나 종료 할 때 .pyc 파일을 삭제하는 exit 기능에 포함시킬 수 있습니다.

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) 
관련 문제