Subversion Externals는 반 패턴입니까?
Subversion을 사용하면 외부를 사용하여 다른 저장소의 작업 복사본을 포함 할 수 있으므로 프로젝트에서 타사 라이브러리 소프트웨어의 버전을 쉽게 제어 할 수 있습니다.
이들은 라이브러리의 재사용과 벤더 소프트웨어 의 버전 관리에 이상적이라고 보이지만 비평가 가없는 것은 아닙니다 .
Subversion 외부 (또는 다른 도구에서 유사한)를 사용하지 마십시오. 안티 패턴이므로 불필요합니다.
외부를 사용할 때 숨겨진 위험이 있습니까? 그들이 반 패턴으로 간주되는 이유를 설명하십시오.
나는 이전 답변 에서 나온 질문의 인용문의 저자입니다 .
제이슨은 저와 같은 간단한 진술을 의심하고 설명을 요청하는 것이 옳습니다. 물론 그 답을 전부 다 설명했다면 책을 써야했을 것입니다.
Mike는 또한 svn:external유사 기능 의 문제점 중 하나 는 대상 소스의 변경 사항이 특히 대상 소스가 소유하지 않은 저장소에있는 경우 자신의 소스를 손상시킬 수 있다는 점이라고 지적하는 것이 옳습니다 .
내 의견을 추가로 설명하면서 svn:external다른 도구 나 기능과 마찬가지로 유사 기능 을 사용하는 "안전한"방법이 있다고 먼저 말씀 드리겠습니다 . 그러나 기능이 오용 될 가능성이 훨씬 더 높기 때문에 이를 반 패턴 이라고합니다. 내 경험상 항상 오용되어 왔으며, 안전한 방식으로 사용하거나 권장하지 않을 가능성이 매우 낮습니다. 더 나아가 Subversion 팀에 대한 비난은 없습니다. Bazaar로 넘어갈 계획이지만 Subversion을 좋아합니다.
이 기능의 주요 문제는 권장하고 일반적으로 한 빌드 ( "프로젝트")의 소스를 다른 빌드의 소스에 직접 연결하거나 프로젝트를 바이너리 (DLL, JAR 등)에 연결하는 데 사용된다는 것입니다. 의존합니다. 이러한 용도는 현명하지 않으며 반 패턴을 구성합니다.
다른 답변에서 말했듯이 소프트웨어 빌드의 필수 원칙은 각 프로젝트가 정확히 하나의 바이너리 또는 기본 결과물을 구성한다는 것입니다. 이는 빌드 프로세스 에 대한 관심사 분리 원칙의 적용으로 간주 될 수 있습니다 . 이것은 캡슐화 원칙을 위반하는 다른 프로젝트의 소스를 직접 참조하는 한 프로젝트에서 특히 그렇습니다 . 이러한 종류의 위반의 또 다른 형태는 하위 빌드를 재귀 적으로 호출하여 전체 시스템 또는 하위 시스템을 구성하는 빌드 계층 구조를 생성하려는 시도입니다. Maven은이 동작을 강력히 권장 / 강제합니다. 이것이 제가 권장하지 않는 많은 이유 중 하나입니다.
마지막으로이 기능을 바람직하지 않게 만드는 다양한 실제 문제가 있음을 알게되었습니다. 우선, svn:external몇 가지 흥미로운 행동 특성이 있습니다 (그러나 세부 사항은 당분간 저를 피할 수 있습니다). 또 다른 경우에는 소스 제어 메타 데이터로 묻히지 않고 프로젝트 (빌드 프로세스)에서 명시 적으로 볼 수 있도록 이러한 종속성이 필요하다는 사실을 항상 발견합니다.
그렇다면이 기능을 사용하는 "안전한"방식은 무엇입니까? 작업 환경을 "구성"하는 방법과 같이 한 사람 만 일시적으로 사용하는 경우라고 생각합니다. 프로그래머 svn:external가 현재 작업중인 저장소의 다양한 부분에 대한 링크를 구성하는 저장소 (또는 각 프로그래머에 대해 하나씩)에서 자신의 폴더를 만드는 위치를 볼 수있었습니다 . 그런 다음 해당 폴더를 체크 아웃하면 현재 모든 프로젝트의 작업 복사본이 생성됩니다. 프로젝트가 추가되거나 완료되면 svn:external정의를 조정하고 작업 사본을 적절하게 업데이트 할 수 있습니다. 그러나 나는 체크 아웃을 호출하는 스크립트를 사용하는 것과 같이 특정 소스 제어 시스템과 관련이없는 접근 방식을 선호합니다.
기록을 위해,이 문제에 대한 가장 최근의 노출은 2008 년 여름에 svn:external대규모 로 사용하는 컨설팅 클라이언트에서 발생했습니다. 모든 것이 교차 연결되어 단일 마스터 작업 사본을 생성했습니다. Ant 및 Jython 기반 (WebLogic 용) 빌드 스크립트는이 마스터 작업 사본 위에 빌드되었습니다. 최종 결과 : 독립형으로 구축 할 수있는 것은 없으며, 말 그대로 수십 개의 하위 프로젝트가 있었지만, 자체적으로 체크 아웃 / 작업하기에 안전한 것은 없었습니다. 따라서이 시스템에서 작업하려면 먼저 2GB 이상의 파일을 체크 아웃 / 업데이트해야했습니다 (저장소에도 바이너리를 넣음). 무엇이든하는 것은 헛된 일이었고, 나는 3 개월 동안 노력한 후에 떠났습니다 (다른 많은 반 패턴들도 존재했습니다).
편집 : 재귀 빌드에 대한 설명-
수년 동안 (특히 지난 10 년 동안) 저는 여러 수준의 디렉터리 계층 구조로 배열 된 수십 개의 하위 프로젝트를 포함하는 Fortune 500 대 기업과 대규모 정부 기관을위한 대규모 시스템을 구축했습니다. 저는 Microsoft Visual Studio 프로젝트 / 솔루션을 사용하여 .NET 기반 시스템, Ant 또는 Maven 2 (Java 기반 시스템 용)를 구성했으며 distutils 및 setuptools (easyinstall)를 Python 기반 시스템 용으로 사용하기 시작했습니다. 이러한 시스템에는 일반적으로 Oracle 또는 Microsoft SQL Server에있는 거대한 데이터베이스도 포함되어 있습니다.
나는 사용의 용이성과 반복성을 위해 이러한 대규모 빌드를 설계하는 데 큰 성공을 거두었습니다. 저의 설계 표준은 새로운 개발자가 첫날 나타나고 새 워크 스테이션 (일반적인 OS 설치 만있는 Dell에서 직접 제공)을 제공하고 간단한 설정 문서 (일반적으로 설치 지침 한 페이지)를 제공 할 수 있다는 것입니다. 워크 스테이션을 완전히 설정하고 소스에서 감독 및 지원없이 반나절 이내에 전체 시스템을 구축 할 수 있습니다. 빌드 자체를 호출하려면 명령 셸을 열고 소스 트리의 루트 디렉터리로 변경하고 한 줄 명령을 실행하여 모든 것을 빌드합니다.
이러한 성공에도 불구하고 이러한 대규모 빌드 시스템을 구축하려면 대규모 비즈니스 크리티컬 애플리케이션 / 시스템을 구축 할 때와 마찬가지로 세심한주의와 견고한 설계 원칙을 철저히 준수해야합니다. 중요한 부분은 각 프로젝트 (단일 아티팩트 / 배달 가능 항목을 생성 함)가 잘 정의 된 인터페이스 (빌드 프로세스의 일부를 호출하는 명령)가 있어야하는 단일 빌드 스크립트를 가져야한다는 것과 다른 모든 (하위) 프로젝트에서 단독으로. 역사적으로 전체 시스템을 구축하는 것은 쉽지만 하나만 구축하는 것은 어렵거나 불가능합니다. 저는 최근에야 각 프로젝트가 진정으로 독립적 인 지 확인하는 법을 배웠습니다.
실제로 이는 빌드 스크립트의 레이어가 두 개 이상 있어야 함을 의미합니다. 최하위 계층은 각 결과물 / 아티팩트를 생성하는 프로젝트 빌드 스크립트입니다. 이러한 각 스크립트는 프로젝트 소스 트리의 루트 디렉토리에 있습니다 (실제로이 스크립트는 프로젝트 소스 트리를 정의 함). 이러한 스크립트는 소스 제어에 대해 전혀 알지 못하며 명령 줄에서 실행될 것으로 예상하며 프로젝트의 모든 항목을 참조합니다. 몇 가지 구성 가능한 설정 (환경 변수, 구성 파일 등)을 기반으로 외부 종속성 (도구 또는 바이너리 아티팩트, 다른 소스 프로젝트 없음)을 참조합니다.
빌드 스크립트의 두 번째 레이어도 명령 줄에서 호출하도록되어 있지만 소스 제어에 대해 알고 있습니다. 실제로이 두 번째 레이어는 프로젝트 이름과 버전으로 호출되는 단일 스크립트 인 경우가 많습니다. 그런 다음 명명 된 프로젝트의 소스를 새 임시 디렉터리 (명령 줄에 지정되었을 수 있음)로 체크 아웃하고 빌드 스크립트를 호출합니다.
지속적인 통합 서버, 다중 플랫폼 및 다양한 릴리스 시나리오를 수용하려면 더 많은 변형이 필요할 수 있습니다.
때로는 전체 프로젝트 세트의 특정 하위 집합을 빌드하기 위해 두 번째 스크립트 레이어 (첫 번째 레이어를 호출 함)를 호출하는 세 번째 스크립트 레이어가 필요합니다. 예를 들어, 각 개발자는 현재 작업중인 프로젝트를 빌드하는 자체 스크립트를 가질 수 있습니다. 마스터 문서를 생성하거나 메트릭을 계산하기 위해 모든 것을 빌드하는 스크립트가있을 수 있습니다.
그럼에도 불구하고 시스템을 프로젝트의 계층 구조로 취급하려는 시도는 비생산적이라는 것을 발견했습니다. 프로젝트를 서로 연결하여 단독으로 또는 임의의 위치 (연속 통합 서버의 임시 디렉터리) 또는 임의의 순서 (종속성이 충족 된 것으로 가정)에 빌드 할 수 없도록합니다. 종종 계층 구조를 강제로 시도하면 시도 할 수있는 IDE 통합이 중단됩니다.
마지막으로 방대한 프로젝트 계층 구조를 구축하는 것은 단순히 성능 집약적 일 수 있습니다. 예를 들어, 2007 년 봄에 Ant를 사용하여 빌드 한 겸손한 소스 계층 구조 (Java + Oracle)를 시도했지만 빌드가 항상 Java OutOfMemoryException으로 중단 되었기 때문에 결국 실패했습니다. 이것은 3.5GB 스왑 공간이있는 2GB RAM 워크 스테이션에 있었고 사용 가능한 모든 메모리를 사용할 수 있도록 JVM을 조정했습니다. 응용 프로그램 / 시스템은 코드 양 측면에서 비교적 사소한 것이었지만 재귀 적 빌드 호출은 메모리 양에 관계없이 결국 메모리를 고갈 시켰습니다. 물론 실행하는데도 시간이 오래 걸렸습니다 (중단되기 전 30-60 분이 일반적이었습니다). 나는 아주 잘 조정하는 방법을 알고 있지만 궁극적으로 나는 도구의 한계를 넘어 섰다 (이 경우 Java / Ant).
그러니 자신에게 호의를 베풀고 독립형 프로젝트로 빌드를 구성한 다음 전체 시스템으로 구성하십시오. 가볍고 유연하게 유지하십시오. 즐겨.
편집 : 반 패턴에 대한 추가 정보
엄밀히 말해서, 반 패턴은 문제를 해결하는 것처럼 보이지만 문제를 해결하지 못하는 일반적인 솔루션입니다. 중요한 틈을 남기거나 추가 문제를 도입하기 때문입니다 (종종 원래 문제보다 더 나쁨). 해결책은 반드시 하나 이상의 도구와이를 당면한 문제에 적용하는 기술을 포함합니다. 따라서 도구 또는 도구의 특정 기능을 반 패턴으로 지칭하는 것은 스트레칭이며, 사람들은 그 스트레칭을 감지하고 이에 반응하는 것처럼 보입니다.
반면에 기술보다는 도구에 초점을 맞추는 것이 업계의 일반적인 관행 인 것처럼 보이므로 관심을 끄는 것은 도구 / 기능입니다 (여기서 StackOverflow에 대한 질문에 대한 간단한 설문 조사는 쉽게 설명하는 것 같습니다). 내 의견과이 질문 자체가 그 관행을 반영합니다.
그러나 때때로이 경우와 같이 그러한 스트레칭을하는 것이 특히 정당한 것처럼 보입니다. 일부 도구는 사용자를 특정 기술로 "유도"하여 도구가 사고를 형성한다고 주장하는 지점까지 (약간 다르게 표현됨) 것으로 보입니다 . 그것이 svn:external반 패턴 이라고 제안하는 것은 대부분 그 정신에 있습니다.
To more strictly state the issue, the antipattern is to design a build solution that includes tying projects together at the source level, or to implicitly version the dependencies between projects, or to allow such dependencies to implicitly change, because each of these invokes very negative consequences. The nature of the svn:external-like feature makes avoiding those negative consequences very difficult.
Properly handling the dependencies between projects involves addressing those dynamics along with the base problem, and the tools and techniques lead down a different path. An example that should be considered is Ivy, which helps in a manner similar to Maven but without the many downsides. I am investigating Ivy, coupled with Ant, as my short-term solution to the Java build problem. Long term, I am looking to incorporate the core concepts and features into an open-source tool that facilitates a multiplatform solution.
I don't think this is an anti-pattern at all. I did a few quick searches on google and came up with basically nothing... nobody is complaining that using svn:externals is bad or harmful. Of course there are some caveats that you have to be aware of... and it's not something that you should just sprinkle heavily into all of your repositories... but as for the original quotation, that's just his personal (and subjective) opinion. He never really discussed svn:externals, except to condemn them as an anti-pattern. Such sweeping statements without any support or at least reasoning as to how the person came to make the statement are always suspect.
That said, there are some issues with using externals. Like Mike answered, they can be very helpful for pointing to stable branches of released software... especially software that you already control. We use them internally in a number of projects for utility libraries and such. We have a small group that enhances and works on the utility library base, but that base code is shared across a number of projects. We don't want various teams just checking in utility project code and we don't want to deal with a million branches, so for us svn:externals works very well. For some people, they may not be the answer. However, I would strongly disagree with the statement "Please don't use..." and that these tools represent an anti-pattern.
The main risk with using svn:externals is that the referenced repository will be changed in a way that breaks your code or introduces a security vulnerability. If the external repository is also under your control, then this may be acceptable.
Personally, I only use svn:externals to point to "stable" branches of a repository that I own.
An old thread, but I want to address the concern that a changing external could break your code. As pointed out previously, this is most often due to an incorrect usage of the external property. External references should, in almost all instances, point to a specific revision number in the external repository URI. This ensures that the external will never change unless you change it to point to a different revision number.
For some of our internal libraries, which we use as externals in our end-user projects, I've found it useful to create a tag of the library at Major.Minor version, where we enforce no breaking changes. With a four-point versioning scheme (Major.Minor.BugFix.Build), we allow the tag to be kept current with BugFix.Build changes (again, enforcing no breaking changes). This allows us to use an external reference to the tag without a revision number. In the case of major or other breaking changes, a new tag is created.
Externals themselves aren't bad, but that doesn't stop people from creating bad implementations of them. It doesn't take much research, just a little bit of reading through some documentation, to learn how to use them safely and effectively.
If plain external is an anti-pattern because it can break your repository, then one with explicit revision should'nt.
Excerpt from svn book:
An externals definition is a mapping of a local directory to the URL**—and possibly a particular revision—**of a versioned resource.
I think it's all depend your purpose of using the feature, it is not an anti-pattern by itself.
There are definite flaws in subversion externals, but we seem to use them reasonably successfully for including libraries (both our own and vendor) that the current project depends on. So I don't see them as an "anti-pattern". The important usage points for me are:
- They point to a specific revision or tag (never the head) of the other project.
- They are inserted into the current project well away from its own source code etc (e.g. in a subdirectory called "support files").
- They refer only to the other projects "interface" files (e.g. include folder) and binary libraries (i.e. we don't get the full source of the other project).
I too would be interested in any major risks of this arrangement, and better approaches.
Saying that a is b does not make a a b unless you say why this is so.
The main flaw I see with external references in subversion is that you're not guaranteed that the repository is present when you update your working copy.
Subversion external references can be used, and abused, and the feature itself is nothing but just that, a feature. It cannot be said to be a pattern, nor a antipattern.
I've read the answer by the person you quote, and I must say that I disagree. If your project requires files version XYZ from a repository, an external subversion reference can easily give you that.
Yes, you can use it wrong by not specifically specifying which version of that reference you need. Will that give you problems? Likely!
Is it an antipattern? Well, it depends. If you follow the link given by the author of the text you quote, ie. here, then no. That something can be used to provide a bad solution does not make the entire method of doing so an antipattern. If that was the rule, then I would say that programming languages by and large are antipatterns, because in every programming language you can make bad solutions.
참고URL : https://stackoverflow.com/questions/338824/are-subversion-externals-an-antipattern
'Nice programing' 카테고리의 다른 글
| svg 배경 이미지 위치는 background-position : left center에도 불구하고 항상 Internet Explorer에서 중앙에 위치합니다. (0) | 2020.11.06 |
|---|---|
| Sierra의 보안 / 코드 로그인 : 키 체인은 액세스 제어 설정 및 권한에 대한 UI 프롬프트를 무시합니다. (0) | 2020.11.06 |
| Linq to SQL은 요점을 놓치지 않습니까? (0) | 2020.11.06 |
| svn의 마지막 변경 사항보기 (0) | 2020.11.06 |
| WCF가 보안되지 않거나 잘못 보안 된 오류 오류를 제공함 (0) | 2020.11.06 |