ฉันจะจัดการเผยแพร่ซอร์สโค้ดโอเพนซอร์สได้ดีที่สุดจากรหัสการวิจัยที่เป็นความลับของ บริษัท ของฉันอย่างไร


13

บริษัท ของฉัน (เรียกพวกเขาว่า Acme Technology) มีห้องสมุดประมาณหนึ่งพันไฟล์ต้นฉบับซึ่งเดิมมาจากกลุ่มการวิจัยของ Acme Labs ซึ่งได้รับการบ่มเพาะในกลุ่มพัฒนาสองสามปีที่ผ่านมาและได้มอบให้กับลูกค้าภายใต้ ไม่เปิดเผย. แอคพร้อมที่จะเปิดตัวโค้ด 75% ให้กับชุมชนโอเพนซอร์ส อีก 25% จะเปิดตัวในภายหลัง แต่สำหรับตอนนี้ยังไม่พร้อมสำหรับการใช้งานของลูกค้าหรือมีรหัสที่เกี่ยวข้องกับนวัตกรรมในอนาคตที่พวกเขาต้องการให้พ้นจากคู่แข่ง

ปัจจุบันรหัสนี้ได้รับการจัดรูปแบบด้วย #ifdefs ที่อนุญาตให้ใช้รหัสฐานเดียวกันเพื่อทำงานกับแพลตฟอร์มการผลิตล่วงหน้าที่จะมีให้สำหรับนักวิจัยมหาวิทยาลัยและลูกค้าเชิงพาณิชย์ในวงกว้างมากขึ้นเมื่อมันเปิดแหล่งที่มาขณะที่ในเวลาเดียวกัน พร้อมสำหรับการทดลองและการสร้างต้นแบบและการทดสอบความเข้ากันได้กับแพลตฟอร์มในอนาคต การรักษาฐานรหัสเดียวถือเป็นสิ่งจำเป็นสำหรับเศรษฐศาสตร์ (และความมีสติ) ของกลุ่มของฉันซึ่งจะมีช่วงเวลาที่ยากลำบากในการรักษาสำเนาสองชุดในแบบคู่ขนาน

ไฟล์ในฐานปัจจุบันของเรามีลักษณะดังนี้:

> // 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);
> }

มีเครื่องมือแยกวิเคราะห์ไลบรารีหรือสคริปต์ยอดนิยมที่สามารถแทนที่ลิขสิทธิ์และตัดทอนไม่ได้เป็นเพียง #ifdefs เท่านั้น แต่ยังมีรูปแบบต่างๆเช่น #if ที่กำหนดไว้ (UNDER_RESEARCH) หรือไม่?

รหัสนี้อยู่ใน Git และน่าจะโฮสต์อยู่ที่ไหนสักแห่งที่ใช้ Git จะมีวิธีเชื่อมโยงที่เก็บข้อมูลอย่างปลอดภัยเข้าด้วยกันหรือไม่ คำแนะนำเกี่ยวกับข้อผิดพลาดอื่น ๆ ยินดีต้อนรับ


13
codebase นี้กำลังกรีดร้องสำหรับสาขาต่างๆ
Florian Margaine

ตัวอย่างของการใช้สาขาเพื่อจุดประสงค์นี้จะได้รับการต้อนรับมากที่สุด
DeveloperDon

คำตอบ:


6

ดูเหมือนว่ามันจะไม่เป็นเรื่องยากเกินไปที่จะเขียนสคริปต์เพื่อแยก preprocessors เปรียบเทียบพวกเขาไปยังรายการของค่าคงที่ที่กำหนดไว้ (กUNDER_RESEARCH, FUTURE_DEVELOPMENTฯลฯ ) และถ้าคำสั่งที่สามารถประเมินเพื่อที่กำหนดเท็จสิ่งที่กำหนดลบทุกอย่างขึ้น #endifถัดไป

ใน Python ฉันจะทำสิ่งที่ชอบ

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 ก็มีการขยายเช่นกันดังนั้นคุณจะจบลงด้วยไฟล์ขนาดใหญ่ที่มีเนื้อหาทั้งหมดของไฟล์ส่วนหัวที่รวมอยู่
  • คุณจะสูญเสียมาโคร "มาตรฐาน"

อาจมีวิธี จำกัด แมโครที่ขยาย แต่ข้อเสนอแนะของฉันที่นี่คือการแยกสิ่งต่าง ๆ แทนที่จะทำการประมวลผล (อาจเป็นอันตราย) ในไฟล์ (โดยวิธีคุณวางแผนที่จะรักษามันไว้หลังจากนั้นอย่างไรเช่นการนำรหัสจากรุ่น opensource กลับไปสู่แหล่งข้อมูลปิดของคุณ?)

นั่นคือลองวางโค้ดที่คุณต้องการเปิดโอเพนซอร์สในไลบรารีภายนอกให้มากที่สุดจากนั้นใช้มันตามที่คุณต้องการกับไลบรารี่อื่น ๆ รวมกับไลบรารี่แบบ "กำหนดเอง" อื่น ๆ

ในตอนแรกอาจใช้เวลานานขึ้นเล็กน้อยในการหาวิธีการปรับโครงสร้างสิ่งต่าง ๆ แต่เป็นวิธีที่เหมาะสมในการทำสิ่งนี้ให้สำเร็จ


ฉันได้พิจารณาแล้วว่าอาจมีบางอย่างที่สามารถทำได้กับตัวประมวลผลล่วงหน้าเพื่อเลือกบล็อกที่เราจะยังไม่วางจำหน่าย รหัสมีความซับซ้อนและเราอาจต้องการความคิดเห็นมากกว่า แต่น้อยกว่าข้อเสนอแนะของคุณคุ้มค่าที่จะมีในรายการระดมสมอง คำถามเกี่ยวกับ WRT เกี่ยวกับวิธีที่เราวางแผนที่จะรักษาแหล่งที่มาและย้ายรหัสไปข้างหลังและส่งต่อไปยังชุมชนนั้นจำเป็นต้องมีการวางแผนเพิ่มเติม การนำรหัสไปใช้ในรหัสกรรมสิทธิ์ทำให้เกิดคำถามที่ดีขึ้น
DeveloperDon

2

ฉันมีทางออก แต่มันต้องใช้งานเล็กน้อย

pypreprocessorเป็นไลบรารี่ที่ให้ preprocessor c-style แท้สำหรับ python ที่สามารถใช้เป็น GPP (General Purpose Pre-Processor) สำหรับโค้ดประเภทอื่น

นี่คือตัวอย่างพื้นฐาน:

from pypreprocessor import pypreprocessor

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

ตัวประมวลผลล่วงหน้านั้นง่ายมาก มันทำให้การส่งผ่านแหล่งที่มาและแสดงความคิดเห็นตามเงื่อนไขออกมาจากสิ่งที่กำหนดไว้

การกำหนดสามารถตั้งค่าผ่านคำสั่ง#defineในแหล่งที่มาหรือโดยการตั้งค่าเหล่านั้นในรายการ pypreprocessor.defines

การตั้งค่าพารามิเตอร์อินพุต / เอาต์พุตอนุญาตให้คุณกำหนดไฟล์ที่กำลังเปิด / ปิดอย่างชัดเจนเพื่อให้ผู้ประมวลผลล่วงหน้าคนเดียวสามารถตั้งค่าการประมวลผลแบบแบ็ตช์เป็นไฟล์จำนวนมากหากต้องการ

การตั้งค่าพารามิเตอร์ removeMeta เป็น True ตัวประมวลผลล่วงหน้าควรแยกคำสั่ง preprocessor ใด ๆ และทั้งหมดออกโดยอัตโนมัติเหลือเพียงโค้ดที่ประมวลผลแล้ว

หมายเหตุ: โดยปกติสิ่งนี้ไม่จำเป็นต้องตั้งค่าอย่างชัดเจนเนื่องจากไพ ธ อนลบรหัสความคิดเห็นโดยอัตโนมัติในระหว่างการคอมไพล์ไปยัง bytecode

ฉันเห็นเคสที่ขอบเดียวเท่านั้น เพราะคุณกำลังมองหาที่จะมา C preprocess คุณอาจต้องการที่จะตั้งกำหนดหน่วยประมวลผลอย่างชัดเจน (เช่นผ่าน 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 ในไฟล์ต้นฉบับเดียวกันและเพียงแค่รวม / แยกความแตกต่างโดยใช้คำสั่ง preprocessor แต่น่าเสียดายที่ฉันค้นพบวิธีที่ยากที่จะไม่สามารถเขียนตัวประมวลผลล่วงหน้าที่แท้จริง (เช่นไม่ต้องใช้ c) ในไพ ธ อนเนื่องจากข้อผิดพลาดทางไวยากรณ์ของ lexer ตั้งค่าสถานะในโค้ดที่เข้ากันไม่ได้ก่อนที่ตัวประมวลผลล่วงหน้าจะมีโอกาส ไม่ว่าจะด้วยวิธีใดก็ยังคงมีประโยชน์ภายใต้สถานการณ์ที่หลากหลายรวมถึงของคุณ


หินก้อนนี้ หากไม่มีสิ่งใดที่เราสามารถทำได้สามทางที่แตกต่างกันซึ่งประมวลผลไฟล์ด้วยและไม่มีรหัสที่เราต้องการยกเว้นเอา diff ของพวกเขาแล้วลบบรรทัดที่แตกต่างจากต้นฉบับ
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-TAG และCOPYRIGHT-ENG-TAG


1
ฉันต้องการแท็กเริ่มต้นหรือไม่ จนถึงตอนนี้ไฟล์ต้นฉบับทั้งหมดของเราเริ่มต้นด้วยลิขสิทธิ์ในบรรทัดแรกและเชลล์สคริปต์ของเราเริ่มต้นด้วยลิขสิทธิ์ในบรรทัดที่สอง มีไฟล์จำนวนมากดังนั้นฉันต้องการแก้ไขจำนวนน้อยที่สุดเท่าที่จะเป็นไปได้
DeveloperDon

ฉันคิดว่าไฟล์บางไฟล์อาจใช้ Doxygen เพื่อจำแนกฟังก์ชั่นพารามิเตอร์และชื่อค่าตอบแทน สำหรับไฟล์เหล่านั้นยังไม่ได้ตั้งค่าด้วยวิธีนี้อาจเป็นการแก้ไขจำนวนมากหากเราเลือกตัวเลือกที่ดำเนินการต่อไปในทิศทางนั้น
DeveloperDon

อย่างน้อยคุณต้องเปลี่ยนหนึ่งครั้ง หากนโยบายลิขสิทธิ์ของคุณเปลี่ยนไปคุณสามารถจัดการได้
Alex Hashimi

1

ฉันจะไม่แสดงให้คุณเห็นเครื่องมือในการแปลง codebase ของคุณมีคำตอบมากมายอยู่แล้ว แต่ฉันกำลังตอบความคิดเห็นของคุณเกี่ยวกับวิธีจัดการสาขาสำหรับสิ่งนี้

คุณควรมี 2 สาขา:

  • ชุมชน (เรียกรุ่นโอเพ่นซอร์สแบบนี้)
  • Professional (เรียกรุ่นที่มาปิดแบบนี้)

ตัวประมวลผลล่วงหน้าไม่ควรมีอยู่ คุณมีสองเวอร์ชั่นที่แตกต่างกัน และรหัสฐานที่สะอาดกว่าโดยรวม

คุณกลัวที่จะรักษาสำเนาสองชุดพร้อมกันหรือไม่ ไม่ต้องกังวลคุณสามารถผสาน!

หากคุณกำลังแก้ไขสาขาชุมชนเพียงรวมพวกเขาในสาขาอาชีพ Git จัดการเรื่องนี้ได้ดีจริงๆ

วิธีนี้คุณเก็บรักษา 2 code ของคุณไว้ และการปล่อยหนึ่งสำหรับโอเพนซอร์สนั้นง่ายเหมือนพาย

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.