회사의 기밀 연구 코드에서 오픈 소스 코드 릴리스를 관리하는 가장 좋은 방법은 무엇입니까?


13

내 회사 (Acme Technology라고 함)에는 Acme Labs 연구 그룹에서 유래 한 약 1,000 개의 소스 파일 라이브러리가 있으며 개발 그룹에서 몇 년 동안 인큐베이션되었으며 최근에는 소수의 고객에게 제공되었습니다. 비공개. Acme는 코드의 75 %를 오픈 소스 커뮤니티에 공개 할 준비를하고 있습니다. 나머지 25 %는 나중에 출시되지만 현재는 고객이 사용할 준비가되지 않았거나 미래의 혁신과 관련된 코드를 포함하여 경쟁 업체의 손에 닿지 않아야합니다.

이 코드는 현재 #ifdef로 포맷되어 있으며, 동일한 코드 기반이 사전 제작 플랫폼에서 작동 할 수있게되며, 동시에 오픈 소스에 들어가면 대학 연구원 및 훨씬 광범위한 상업 고객이 이용할 수 있습니다. 미래 플랫폼과의 실험 및 프로토 타입 제작 및 호환성 테스트에 사용할 수 있습니다. 단일 코드 기반을 유지하는 것은 두 사본을 병렬로 유지 관리하는 데 어려움을 겪는 우리 그룹의 경제 및 정신에 필수적입니다.

현재 기본 파일은 다음과 같습니다.

> // Copyright 2012 (C) Acme Technology, All Rights Reserved.
> // Very large, often varied and restrictive copyright license in English and French,
> // sometimes also embedded in make files and shell scripts with varied 
> // comment styles. 
> 
> 
>   ... Usual header stuff...
>
> void initTechnologyLibrary() {
>     nuiInterface(on);
> #ifdef  UNDER_RESEARCH
>     holographicVisualization(on);
> #endif
> }

그리고 우리는 그것들을 다음과 같이 변환하고 싶습니다 :

> // GPL Copyright (C) Acme Technology Labs 2012, Some rights reserved.
> // Acme appreciates your interest in its technology, please contact xyz@acme.com 
> // for technical support, and www.acme.com/emergingTech for updates and RSS feed.
> 
>   ... Usual header stuff...
>
> void initTechnologyLibrary() {
>     nuiInterface(on);
> }

저작권을 대체하고 #ifdef뿐만 아니라 #if defined (UNDER_RESEARCH) 등과 같은 변형을 제거 할 수있는 도구, 구문 분석 라이브러리 또는 널리 사용되는 스크립트가 있습니까?

이 코드는 현재 Git에 있으며 Git을 사용하는 곳에서 호스팅 될 수 있습니다. 개선 사항을 오픈 소스 버전과 효율적으로 다시 통합 할 수 있도록 리포지토리를 안전하게 연결하는 방법이 있습니까? 다른 함정에 대한 조언을 환영합니다.


13
이 코드베이스는 분기를 비명을 지르고 있습니다.
Florian Margaine

이 목적으로 분기를 사용하는 예는 가장 환영받을 것입니다.
DeveloperDon

답변:


6

처리기를 구문 분석하는 스크립트를 작성하기 너무 어렵지 않을 것 같은이 정의 된 상수 (의 목록에 비교 것 UNDER_RESEARCH, FUTURE_DEVELOPMENT지시어가 정의 무슨 거짓을 감안할 때, 최대 제거 모든 것을 평가 될 수있는 경우 등), 다음에 #endif.

파이썬에서는 다음과 같은 일을합니다.

import os

src_dir = 'src/'
switches = {'UNDER_RESEARCH': True, 'OPEN_SOURCE': False}
new_header = """// GPL Copyright (C) Acme Technology Labs 2012, Some rights reserved.
// Acme appreciates your interest in its technology, please contact xyz@acme.com 
// for technical support, and www.acme.com/emergingTech for updates and RSS feed.
"""

filenames = os.listdir(src_dir)
for fn in filenames:
    contents = open(src_dir+fn, 'r').read().split('\n')
    outfile = open(src_dir+fn+'-open-source', 'w')
    in_header = True
    skipping = False
    for line in contents:
        # remove original header
        if in_header and (line.strip() == "" or line.strip().startswith('//')):
            continue
        elif in_header:
            in_header = False
            outfile.write(new_header)

        # skip between ifdef directives
        if skipping:
            if line.strip() == "#endif":
                skipping = False
            continue
        # check
        if line.strip().startswith("#ifdef"):
            # parse #ifdef (maybe should be more elegant)
            # this assumes a form of "#ifdef SWITCH" and nothing else
            if line.strip().split()[1] in switches.keys():
                skipping = True
                continue

        # checking for other forms of directives is left as an exercise

        # got this far, nothing special - echo the line
        outfile.write(line)
        outfile.write('\n')

더 우아한 방법이 있다고 확신하지만 이것은 빠르고 더러워서 작업을 완료하는 것 같습니다.


와우 감사합니다. 좋은 필터를 만들 수있는 많은 논리가 있으며 귀하의 사례에 감사드립니다. 재사용 할 무언가를 찾고 싶습니다. 저의 개발 시스템은 메모리가 빠르기 때문에 저작권과 정의에 대해 별도의 필터를 실행하거나 정의 필터를 두 번 이상 실행하는 것이 성능에 큰 문제가되지 않습니다. 우리는 실제로 여러 미래 프로젝트와 오픈 소스로 출시되지는 않지만 여전히 내부적으로 그리고 고객을 조기에 채택하여 사용되는 몇 가지 과거 프로젝트를 지정하는 키워드와 관련된 여러 정의를 가지고 있습니다.
DeveloperDon

3

매크로 만 확장하기 위해 전처리기를 통해 코드를 전달하여 #ifdefs 의 흥미로운 부분 만 출력하려고 생각했습니다 .

이와 같은 것이 작동해야합니다.

gcc -E yourfile.c

그러나:

  • 모든 의견을 잃게됩니다. 당신은 -CC그것들을 (종류의) 보존하는 데 사용할 수 있지만 여전히 오래된 저작권 표시를 제거해야합니다
  • #includes도 확장되므로 포함 된 헤더 파일의 모든 내용을 포함하는 큰 파일로 끝납니다.
  • "표준"매크로를 잃게됩니다.

확장되는 매크로를 제한하는 방법이있을 수 있습니다. 그러나 여기서 제안하는 것은 파일에 대해 (잠재적으로 위험한) 처리를 수행하는 대신 작업을 분할하는 것입니다 (그런 다음, 파일을 어떻게 유지할 계획입니까?

즉, 오픈 소스하려는 코드를 가능한 한 외부 라이브러리에 넣은 다음 다른 "사용자 정의"폐쇄 소스 라이브러리와 통합하여 다른 라이브러리와 마찬가지로 사용하십시오.

사물을 재구성하는 방법을 파악하는 데 처음에는 시간이 조금 더 걸릴 수 있지만이를 달성하는 올바른 방법입니다.


우리가 아직 발표하지 않은 블록을 선택적으로 제거하기 위해 전처리기로 할 수있는 일이 있는지 여부를 고려했습니다. 코드는 복잡하므로 적은 의견이 아닌 더 많은 의견이 필요할 수 있지만 브레인 스토밍 목록에 제안하는 것이 좋습니다. 소스를 유지하고 코드를 커뮤니티에 앞뒤로 이동시키는 방법에 대한 WRT 질문에는 더 많은 계획이 필요합니다. 독점 코드로 코드를 가져 오면 좋은 의문이 제기됩니다.
DeveloperDon

2

해결책이 있지만 약간의 작업이 필요합니다

pypreprocessor 는 다른 유형의 소스 코드를위한 GPP (General Purpose Pre-Processor)로도 사용될 수있는 파이썬을위한 순수한 c 스타일 전처리기를 제공하는 라이브러리입니다.

기본 예는 다음과 같습니다.

from pypreprocessor import pypreprocessor

pypreprocessor.input = 'input_file.c'
pypreprocessor.output = 'output_file.c'
pypreprocessor.removeMeta = True
pypreprocessor.parse()

전처리 기는 매우 간단합니다. 소스를 통과하고 정의 된 내용에 따라 소스를 조건부로 주석 처리합니다.

소스의 #define 문을 통해 또는 pypreprocessor.defines 목록에서 설정하여 정의를 설정할 수 있습니다 .

입 / 출력 매개 변수를 설정하면 원하는 파일을 일괄 처리하도록 단일 프리 프로세서를 설정할 수 있도록 열고 / 닫는 파일을 명시 적으로 정의 할 수 있습니다.

removeMeta 매개 변수를 True로 설정하면 전처리 기는 후 처리 된 코드 만 남기고 모든 전 처리기 명령문을 자동으로 추출해야합니다.

참고 : 일반적으로 파이썬은 바이트 코드로 컴파일하는 동안 주석 처리 된 코드를 자동으로 제거하기 때문에 명시 적으로 설정할 필요가 없습니다.

하나의 엣지 케이스 만 보입니다. C 소스를 사전 처리하려고하므로 프로세서 정의를 명시 적으로 (예 : pypreprocessor.defines를 통해) 설정하고 소스에서 #define 문 을 무시하도록 지시 할 수 있습니다. 프로젝트 소스 코드에서 사용할 수있는 상수를 실수로 제거하지 못하게해야합니다. 현재이 기능을 설정하는 매개 변수가 없지만 추가하기는 쉽지 않습니다.

다음은 간단한 예입니다.

from pypreprocessor import pypreprocessor

# run the script in 'production' mode
if 'commercial' in sys.argv:
    pypreprocessor.defines.append('commercial')

if 'open' in sys.argv:
    pypreprocessor.defines.append('open')

pypreprocessor.removeMeta = True
pypreprocessor.parse()

그런 다음 소스 :

#ifdef commercial
// Copyright 2012 (C) Acme Technology, All Rights Reserved.
// Very large, often varied and restrictive copyright license in English and French,
// sometimes also embedded in make files and shell scripts with varied 
// comment styles.
#ifdef open
// GPL Copyright (C) Acme Technology Labs 2012, Some rights reserved.
// Acme appreciates your interest in its technology, please contact xyz@acme.com 
// for technical support, and www.acme.com/emergingTech for updates and RSS feed.
#endif

참고 : 입력 / 출력 파일을 설정하는 방법을 정렬해야하지만 그렇게 어렵지는 않습니다.

공개 : 저는 pypreprocessor의 최초 저자입니다.


따로 : 나는 원래 끔찍한 파이썬 2k / 3x 유지 관리 문제에 대한 해결책으로 썼습니다. 내 접근 방식은 동일한 소스 파일에서 2 및 3 개발을 수행했으며 전 처리기 지시문을 사용하여 차이점을 포함 / 제외했습니다. 불행히도, 전처리 기가 실행되기 전에 렉서가 호환되지 않는 코드로 구문 오류를 표시하기 때문에 파이썬에서 진정한 순수 (즉 c를 필요로하지 않음) 전처리기를 작성하는 것이 불가능한 어려운 방법을 발견했습니다. 어느 쪽이든, 그것은 당신을 포함한 다양한 상황에서 여전히 유용합니다.


이 바위. 제외 할 코드가 있거나없는 파일을 처리하는 3 방향 diff와 같은 다른 작업을 수행 할 수없는 경우 diff를 사용한 다음 diffed 행을 원본에서 제거했습니다.
DeveloperDon

@DeveloperDon Yep, 이것이 일반적인 아이디어입니다. 커밋 해제주기를 관리하는 방법에 따라 처리 방법이 다릅니다. 이 작품은 지루하거나 오류가 발생하기 쉬운 많은 작업을 자동화합니다.
Evan Plaice

1

아마 그것은 좋은 생각이 될 것입니다

1. 다음과 같은 주석 태그를 추가하십시오.

> // *COPYRIGHT-BEGIN-TAG*
> // Copyright 2012 (C) Acme Technology, All Rights Reserved.
> // Very large, often varied and restrictive copyright license in English and French,
> // sometimes also embedded in make files and shell scripts with varied 
> // comment styles. 
> // *COPYRIGHT-ENG-TAG*
>   ... Usual header stuff...
>
> void initTechnologyLibrary() {
>     nuiInterface(on);
> #ifdef  UNDER_RESEARCH
>     holographicVisualization(on);
> #endif
> }

2. 오픈 소스 빌더가 모든 파일을 처리하고 COPYRIGHT-BEGIN-TAGCOPYRIGHT-ENG-TAG 태그 사이의 텍스트를 대체하는 스크립트 작성


1
시작 태그가 필요합니까? 지금까지 모든 소스 파일은 첫 번째 줄의 저작권으로 시작하고 셸 스크립트는 두 번째 줄의 저작권으로 시작합니다. 많은 파일이 있으므로 가능한 한 가장 적은 수작업으로 편집하고 싶습니다.
DeveloperDon

일부 파일은 Doxygen을 사용하여 기능, 매개 변수 및 반환 값 이름을 나타낼 수 있다고 생각합니다. 이러한 방식으로 아직 설정되지 않은 파일의 경우 해당 방향으로 추가 선택을하면 실제로 많은 편집 작업이 될 수 있습니다.
DeveloperDon

적어도 한 번 변경해야합니다. 저작권 정책이 변경된 경우이를 관리 할 수 ​​있습니다.
Alex Hashimi

1

코드베이스를 변환하는 도구를 보여주지 않을 것입니다. 많은 답변이 이미 그렇게했습니다. 오히려 분기를 처리하는 방법에 대한 귀하의 의견에 답변하고 있습니다.

당신은 2 가지가 있어야합니다 :

  • 커뮤니티 (이와 같이 오픈 소스 버전으로 전화합시다)
  • 프로페셔널 (이와 같이 비공개 소스 버전이라고하자)

전처리 기가 존재하지 않아야합니다. 두 가지 버전이 있습니다. 그리고 더 깨끗한 코드베이스.

두 개의 사본을 동시에 유지하는 것이 두렵습니까? 걱정하지 마십시오. 병합 할 수 있습니다!

커뮤니티 지점을 수정하는 경우 전문 지점으로 병합하십시오. 힘내 정말 잘 처리합니다 .

이런 식으로 유지 관리되는 코드베이스 사본 2 개를 유지합니다. 오픈 소스 용으로 하나를 공개하는 것은 파이처럼 쉽습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.