문제

Subversion을 사용하면 다음을 사용하여 다른 저장소의 작업 복사본을 포함할 수 있습니다. 외관, 프로젝트에서 타사 라이브러리 소프트웨어의 버전을 쉽게 제어할 수 있습니다.

이는 라이브러리 재사용 및 버전 제어에 이상적인 것처럼 보이지만 공급업체 소프트웨어, 그들은 없지 않습니다 그들의 비평가:

Subversion 외부 항목(또는 다른 도구의 유사한 항목)을 사용하지 마십시오. 이는 안티 패턴이므로 불필요합니다.

외부를 사용할 때 숨겨진 위험이 있습니까?왜 이것이 안티패턴으로 간주되는지 설명해주세요.

도움이 되었습니까?

해결책

나는 질문의 인용문의 저자입니다. 이전 답변.

Jason은 광산과 같은 간단한 진술을 의심하고 설명을 요청할 권리가 있습니다. 물론, 그 대답의 모든 것을 완전히 설명했다면, 나는 책을 써야했을 것입니다.

Mike는 또한 svn:external-유사한 기능은 대상 소스의 변경이 자신의 소스를 깨뜨릴 수 있다는 것입니다. 특히 타겟팅 된 소스가 소유하지 않은 저장소에있는 경우.

내 의견을 더 설명하면서 먼저 "안전한"방법이 있다고 말씀 드리겠습니다. svn:external다른 도구 나 기능과 마찬가지로 기능. 그러나 나는 그것을 an이라고합니다 반포 란 이 기능은 오용 가능성이 훨씬 높기 때문입니다. 내 경험상, 그것은 항상 오용되었으며, 나는 그 안전한 방식으로 그것을 사용하거나 그 사용을 권장하지 않을 것입니다. 또한 Bazaar로 넘어갈 계획이지만 전복 팀에 대한 불균형이 없다는 것을 의미합니다.

이 기능의 주요 문제는 장려되며 일반적으로 한 빌드의 소스 ( "프로젝트")를 다른 빌드의 소스에 직접 연결하거나 프로젝트를 이진 (DLL, JAR 등)에 연결하는 데 사용된다는 것입니다. 그것은 의존합니다. 이러한 용도 중 어느 것도 현명하지 않으며, 반포 란을 구성합니다.

다른 대답에서 말했듯이, 소프트웨어 빌드의 필수 원칙은 각 프로젝트가 정확히 하나의 바이너리 또는 1 차 전달 가능성을 구성한다는 것입니다. 이것은 원칙의 적용으로 간주 될 수 있습니다. 우려의 분리 빌드 프로세스에. 이것은 한 프로젝트가 다른 프로젝트의 출처를 직접 참조하는 경우에 특히 그렇습니다.이 프로젝트는 또한 원칙을 위반하는 것입니다. 캡슐화. 이러한 종류의 위반의 또 다른 형태는 하위 구축을 재귀 적으로 호출하여 전체 시스템 또는 하위 시스템을 구성하기 위해 빌드 계층 구조를 작성하려고 시도하는 것입니다. Maven 은이 행동을 강력하게 장려/시행하는데, 이것이 내가 추천하지 않는 많은 이유 중 하나입니다.

마지막으로, 나는이 기능을 바람직하지 않게 만드는 다양한 실질적인 문제가 있음을 알았습니다. 하나, svn:external 흥미로운 행동 특성이 있지만 세부 사항은 지금 나를 탈출합니다). 다른 한편으로, 나는 항상 소스 제어 메타 데이터로 묻히지 않은 프로젝트 (빌드 프로세스)에 명시 적으로 보이려면 그러한 종속성이 필요하다는 것을 알게됩니다.

그렇다면이 기능을 사용하는 "안전한"방식은 무엇입니까? 작업 환경을 "구성"하는 방법과 같이 한 사람 만 일시적으로 사용하는 경우를 고려할 것입니다. 프로그래머가 리포지토리 (또는 각 프로그래머마다 하나)에서 자신의 폴더를 구성 할 수있는 곳을 확인할 수 있습니다. svn:external 현재 진행중인 저장소의 다양한 다른 부분에 대한 링크. 그런 다음 해당 폴더의 결제는 현재 모든 프로젝트의 작업 사본을 만듭니다. 프로젝트가 추가되거나 완료되면 svn:external 정의를 조정하고 작업 사본을 적절하게 업데이트 할 수 있습니다. 그러나 체크 아웃을 호출하는 스크립트를 사용하여 특정 소스 제어 시스템과 관련이없는 접근 방식을 선호합니다.

기록상,이 문제에 대한 가장 최근의 노출은 2008 년 여름에 사용중인 컨설팅 고객에서 발생했습니다. svn:external 거대한 규모로-모든 마스터 작업 사본을 생성하기 위해 모든 것이 가교되었습니다. 그들의 Ant & Jython 기반 (Weblogic for Weblogic) 빌드 스크립트는이 마스터 작업 사본 위에 구축되었습니다. 순 결과 : 독립형으로 만들 수있는 것은 없으며 말 그대로 수십 개의 하위 프로젝트가 있었지만 그 자체로 체크 아웃/작업하기에 안전하지는 않았습니다. 따라서이 시스템의 모든 작업에는 먼저 2GB 이상의 파일의 체크 아웃/업데이트가 필요했습니다 (이 바이너리도 리포지토리에도 적용). 아무것도 끝내는 것은 무익한 운동이었고, 나는 3 개월 동안 시도한 후 떠났다 (다른 많은 반포 란도 존재했다).

편집 : 재귀 빌드에 대한 설명 -

수년에 걸쳐 (특히 지난 10 년 동안), 나는 포춘 500 대 기업과 대규모 정부 기관을위한 대규모 시스템을 구축했습니다. Microsoft Visual Studio Projects/Solutions를 사용하여 Java 기반 시스템을 위해 .NET 기반 시스템, Ant 또는 Maven 2를 구성했으며 Python 기반 시스템에 Distutils 및 Setuptools (EasyInstall)를 사용하기 시작했습니다. 이 시스템에는 일반적으로 Oracle 또는 Microsoft SQL Server에 거대한 데이터베이스가 포함되어 있습니다.

나는 사용 편의성과 반복성을 위해이 거대한 빌드를 설계하는 데 큰 성공을 거두었습니다. 내 디자인 표준은 새로운 개발자가 첫날에 나타날 수 있고, 새로운 워크 스테이션을받을 수 있다는 것입니다 (아마도 일반적인 OS 설치만으로 Dell에서 직접) 간단한 설정 문서 (일반적으로 설치 지침의 한 페이지)가 제공됩니다. 그리고 워크 스테이션을 완전히 설정하고 소스, 감독되지 않은, 보조금이없고 반나절 이하로 전체 시스템을 구축 할 수 있습니다. 빌드 자체를 호출하려면 명령 쉘을 열고, 소스 트리의 루트 디렉토리로 변경하고, 한 줄 명령을 발행하여 모든 것을 빌드해야합니다.

이러한 성공에도 불구하고, 이러한 대규모 빌드 시스템을 구성하려면 대규모 비즈니스 크리티컬 애플리케이션/시스템을 구성하는 것과 마찬가지로, 이러한 대규모 빌드 시스템을 구축하려면 탄탄한 디자인 원칙에 대한 친밀한 준수가 필요합니다. 중요한 부분은 각 프로젝트 (단일 아티팩트/배송 가능)가 단일 빌드 스크립트를 가져야하며, 이는 잘 정의 된 인터페이스 (빌드 프로세스의 일부를 호출하기위한 명령)가 있어야한다는 것입니다. 다른 모든 (하위) 프로젝트에서만. 역사적으로 전체 시스템을 구축하기는 쉽지만 한 조각 만 빌드하기가 어렵거나 불가능합니다. 최근에야 나는 각 프로젝트가 진정으로 혼자 서도록주의 깊게 보장하는 법을 배웠습니다.

실제로 이것은 적어도 두 개의 빌드 스크립트가 있어야 함을 의미합니다. 가장 낮은 계층은 각 전달 가능/아티팩트를 생성하는 프로젝트 빌드 스크립트입니다. 각 스크립트는 프로젝트 소스 트리의 루트 디렉토리에 있습니다 (실제로이 스크립트는 프로젝트 소스 트리를 정의합니다), 이러한 스크립트는 소스 컨트롤에 대해 아무것도 모르고 명령 줄에서 실행될 것으로 예상되며 프로젝트 상대의 모든 것을 참조합니다. 빌드 스크립트에 몇 가지 구성 가능한 설정 (환경 변수, 구성 파일 등)을 기반으로 외부 종속성 (도구 또는 이진 아티팩트, 기타 소스 프로젝트 없음)을 참조하십시오.

빌드 스크립트의 두 번째 계층은 또한 명령 줄에서 호출되기위한 것이지만 소스 컨트롤에 대해 알고 있습니다. 실제로,이 두 번째 레이어는 종종 프로젝트 이름과 버전으로 호출되는 단일 스크립트이며, 이름이 지정된 프로젝트의 소스를 새 임시 디렉토리 (명령 줄에 지정 됨)로 확인하고 빌드 스크립트를 호출합니다.

지속적인 통합 서버, 여러 플랫폼 및 다양한 릴리스 시나리오를 수용하려면 더 많은 변화가 필요할 수 있습니다.

때로는 전체 프로젝트 세트의 특정 서브 세트를 구축 할 목적으로 두 번째 스크립트 계층 (첫 번째 레이어를 호출)을 호출하는 세 번째 스크립트 계층이 필요합니다. 예를 들어, 각 개발자는 오늘날 작업중 인 프로젝트를 구축하는 자체 스크립트를 가질 수 있습니다. 마스터 문서를 생성하거나 메트릭을 계산하기 위해 모든 것을 구축하는 스크립트가있을 수 있습니다.

그럼에도 불구하고, 나는 시스템을 프로젝트의 계층 구조로 취급하는 것이 비생산적이라는 것을 알게되었습니다. 프로젝트를 서로 연결하여 혼자 또는 임의의 위치 (연속 통합 서버의 임시 디렉토리) 또는 임의 순서 (종속성이 만족한다고 가정)로 자유롭게 구축 할 수 없도록 프로젝트를 연결합니다. 종종 계층 구조를 강요하려고 시도하면 시도 할 수있는 IDE 통합이 중단됩니다.

마지막으로, 대규모 프로젝트 계층 구조를 구축하는 것은 단순히 성능 집약적 일 수 있습니다. 예를 들어, 2007 년 봄 동안 나는 개미를 사용하여 제작 한 겸손한 소스 계층 구조 (Java Plus Oracle)를 시도했는데, 이는 결국 Java OutofMemoryException으로 빌드가 항상 중단 되었기 때문에 결국 실패했습니다. 이것은 3.5GB 스왑 공간이있는 2GB RAM 워크 스테이션에 있었으며, 이용 가능한 모든 메모리를 사용할 수 있도록 JVM을 조정했습니다. 응용 프로그램/시스템은 코드의 양 측면에서 상대적으로 사소했지만, 재귀 빌드 호출은 내가 얼마나 많은 메모리를 준 메모리에 관계없이 메모리를 소진했습니다. 물론, 그것은 또한 실행하는데 영원히 걸렸다 (30-60 분은 낙태되기 전에 일반적이었다). 나는 잘 조정하는 방법을 알고 있지만 궁극적으로 도구의 한계를 초과하고있었습니다 (이 경우 Java/Ant).

따라서 자신에게 호의를 베풀고, 빌드를 독립형 프로젝트로 구성한 다음 전체 시스템으로 구성하십시오. 가볍고 유연하게 유지하십시오. 즐기다.

편집 : 반포 란에 대한 자세한 내용

엄격히 말하면, 반포 란드는 문제를 해결하는 것처럼 보이지만 중요한 차이를 남기거나 추가 문제를 도입하기 때문에 (종종 원래 문제보다 나쁘다) 일반적인 솔루션입니다. 솔루션에는 반드시 하나 이상의 도구와 문제에 적용하는 기술이 포함됩니다. 따라서 도구의 도구 또는 특정 기능을 도구의 반포 링으로 언급하는 것은 스트레칭이며, 사람들은 그 스트레치를 감지하고 반응하는 것으로 보입니다.

반면에, 우리 업계에서 기술보다는 도구에 초점을 맞추는 것이 일반적인 관행 인 것처럼 보이기 때문에,주의를 기울이는 도구/기능입니다 (여기서 StackoverFlow에 대한 질문에 대한 캐주얼 조사는 쉽게 설명하는 것 같습니다). 내 의견 과이 질문 자체는 그 관행을 반영합니다.

그러나 때로는이 경우와 같이 그 스트레칭을하는 것이 특히 정당한 것 같습니다. 일부 도구는 사용자를 적용하기위한 특정 기술로 "리드"하는 것 같습니다. 도구 모양 생각 (약간 리판). 내가 제안하는 것은 대부분 그 정신에 있습니다. svn:external 반포 란입니다.

문제를보다 엄격히 진술하기 위해, 반 반포 스른은 소스 수준에서 프로젝트를 함께 묶는 것을 포함하는 빌드 솔루션을 설계하거나 프로젝트 간의 종속성을 암시 적으로 버전하거나 그러한 종속성이 암시 적으로 변경되도록하는 것입니다. 결과. 의 본질 svn:external-같은 기능은 이러한 부정적인 결과를 피하는 것을 매우 어렵게 만듭니다.

프로젝트 간의 종속성을 올바르게 처리하려면 기본 문제와 함께 해당 역학을 해결하는 것이 포함되며 도구와 기술은 다른 경로를 이끌어냅니다. 고려해야 할 예는입니다 여자 이름, 이것은 Maven과 비슷한 방식으로 도움이되지만 많은 단점이 없습니다. Java 빌드 문제에 대한 단기 솔루션으로 개미와 함께 Ivy를 조사하고 있습니다. 장기적으로 핵심 개념과 기능을 멀티 플랫폼 솔루션을 용이하게하는 오픈 소스 도구에 통합하려고합니다.

다른 팁

나는 이것이 전혀 안티 패턴이라고 생각하지 않습니다.Google에서 몇 가지 빠른 검색을 수행했지만 기본적으로 아무것도 나오지 않았습니다.svn:externals를 사용하는 것이 나쁘거나 해롭다고 불평하는 사람은 아무도 없습니다.물론 주의해야 할 사항도 있습니다만...그리고 그것은 모든 저장소에 많이 뿌려야 하는 것이 아닙니다...하지만 원래 인용문은 그의 개인적(주관적) 의견일 뿐입니다.그는 svn:externals를 반패턴으로 비난하는 것 외에는 실제로 논의한 적이 없습니다.그 사람이 어떻게 그 진술을 하게 되었는지에 대한 어떠한 뒷받침이나 최소한의 추론도 없는 그러한 포괄적인 진술은 항상 의심스럽습니다.

즉, 외부 사용에는 몇 가지 문제가 있습니다.Mike가 답변한 것처럼 이는 출시된 소프트웨어의 안정적인 분기를 가리키는 데 매우 도움이 될 수 있습니다...특히 이미 제어하고 있는 소프트웨어.우리는 유틸리티 라이브러리 등을 위한 여러 프로젝트에서 내부적으로 이를 사용합니다.우리는 유틸리티 라이브러리 기반을 향상하고 작업하는 소규모 그룹을 가지고 있지만 해당 기본 코드는 여러 프로젝트에서 공유됩니다.우리는 다양한 팀이 유틸리티 프로젝트 코드만 확인하는 것을 원하지 않으며 백만 개의 분기를 처리하고 싶지 않으므로 svn:externals는 매우 잘 작동합니다.어떤 사람들에게는 이것이 답이 아닐 수도 있습니다.그러나 나는 "...을 사용하지 마십시오"라는 말과 이러한 도구가 안티 패턴을 나타낸다는 말에 강력히 동의하지 않습니다.

SVN : Externals를 사용하면 주요 위험은 참조 된 저장소가 코드를 중단하거나 보안 취약점을 도입하는 방식으로 변경되는 것입니다. 외부 저장소가 귀하의 제어하에있는 경우 허용 가능할 수 있습니다.

개인적으로, 나는 SVN : 외부를 사용하여 내가 소유 한 저장소의 "안정적인"지점을 가리 킵니다.

오래된 스레드이지만 변화하는 외부가 코드를 깨뜨릴 수 있다는 우려를 해결하고 싶습니다. 이전에 지적했듯이, 이것은 대부분 외부 속성의 사용이 잘못 되었기 때문입니다. 외부 참조는 거의 모든 사례에서 외부 저장소 URI의 특정 개정 번호를 가리켜 야합니다. 이렇게하면 다른 개정 번호를 가리 키도록 변경하지 않으면 외부가 변경되지 않도록합니다.

최종 사용자 프로젝트에서 외부로 사용하는 일부 내부 라이브러리의 경우 Major.Minor 버전에서 라이브러리 태그를 작성하는 것이 유용한 것으로 나타났습니다. 4 점 버전 관리 체계 (major.minor.bugfix.build)를 사용하면 Bugfix.build 변경으로 태그를 최신 상태로 유지할 수 있습니다 (다시 깨지지 않음). 이를 통해 개정 번호없이 태그에 대한 외부 참조를 사용할 수 있습니다. 전공 또는 기타 중단 변경의 경우 새 태그가 생성됩니다.

외부 자체는 나쁘지 않지만 사람들이 나쁜 구현을 만들지 못하게하는 것은 아닙니다. 안전하고 효과적으로 사용하는 방법을 배우려면 많은 연구가 필요하지 않습니다.

평범한 외부가 안티 패턴 인 경우 저장소를 깨뜨릴 수 있으므로 명시 적 개정이있는 사람은 그렇지 않아야합니다.

발췌 SVN 책:

외부 정의는 로컬 디렉토리를 URL **에 매핑하는 것입니다.

나는 그것이 기능을 사용하려는 당신의 목적에 달려 있다고 생각합니다. 그것은 그 자체로 반란이 아닙니다.

전복 외부에는 명확한 결함이 있지만, 현재 프로젝트가 의존하는 라이브러리 (자체 및 공급 업체)를 포함시키는 데 합리적으로 성공적으로 사용하는 것 같습니다. 그래서 나는 그것들을 "반포 팬"으로 보지 않습니다. 나에게 중요한 사용 지점은 다음과 같습니다.

  • 그들은 다른 프로젝트의 특정 개정 또는 태그 (결코 헤드)를 가리 킵니다.
  • 그들은 자체 소스 코드 등 (예 : "지원 파일"이라는 하위 디렉토리에서)에서 현재 프로젝트에 삽입됩니다.
  • 그들은 다른 프로젝트 "인터페이스"파일 (예 : 폴더 포함)과 이진 라이브러리 (즉, 다른 프로젝트의 전체 소스를 얻지 못함)를 참조합니다.

나도이 배열의 주요 위험과 더 나은 접근 방식에 관심이있을 것입니다.

에 대해 말하는 것 a는 b입니다 만들지 않습니다 당신이 말하지 않는 한 이것은 그렇습니다.

외부 참조에서 Subversion에서 볼 수있는 주요 결함은 작업 사본을 업데이트 할 때 저장소가 존재한다는 보장이 아니라는 것입니다.

전복 외부 참조를 사용하고 학대 할 수 있으며 기능 자체 그저 그저 그냥, 특징. 말할 수는 없습니다 패턴, 또는 a 반포 란.

나는 당신이 인용 한 사람의 답을 읽었으며, 나는 동의하지 않는다고 말해야합니다. 프로젝트에 리포지토리에서 파일 버전 XYZ가 필요한 경우 외부 전력 참조가 쉽게 제공 할 수 있습니다.

예, 필요한 참조 버전을 구체적으로 지정하지 않음으로써 잘못 사용할 수 있습니다. 그것이 당신에게 문제를 줄까요? 할 것 같은!

antipattern입니까? 글쎄, 그것은 달라집니다. 당신이 인용 한 텍스트의 저자가 제공 한 링크를 따르는 경우, 즉 (예 :). 여기, 그럼 아닙니다. 그게 뭔가 ~할 수 있다 나쁜 솔루션을 제공하는 데 사용되는 것은 그렇게하는 전체 방법을 만들지 않습니다. 반포 란. 그것이 규칙이라면, 나는 모든 프로그래밍 언어에서 당신이 나쁜 솔루션을 만들 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top