Şirketimin gizli araştırma kodundan açık kaynak kodlu sürümler çıkarmayı en iyi nasıl yapabilirim?


13

Şirketim (onlara Acme Technology diyelim) başlangıçta Acme Labs araştırma grubundan gelen, birkaç yıl boyunca bir geliştirme grubunda inkübe edilen ve daha yakın zamanda bir avuç müşteriye sağlanan yaklaşık bin kaynak dosyadan oluşan bir kütüphaneye sahip ifşa. Acme, kodun belki de% 75'ini açık kaynak topluluğuna bırakmaya hazırlanıyor. Diğer% 25 daha sonra piyasaya sürülecek, ancak şimdilik ya müşteri kullanımına hazır değil ya da rakiplerin elinden uzak tutmak için gelecekteki yeniliklerle ilgili kod içeriyor.

Kod şu anda, aynı kod tabanının üniversite araştırmacıları ve açık kaynak koduna girildikten sonra çok daha fazla ticari müşteri için kullanılabilecek üretim öncesi platformlarla çalışmasına izin veren #ifdefs ile biçimlendirilmiştir. gelecekteki platformla deneme ve prototip oluşturma ve ileri uyumluluk testi için kullanılabilir. Tek bir kod tabanı tutmak, iki kopyayı paralel olarak tutmakta zorlanacak olan grubumun ekonomisi (ve akıl sağlığı) için gerekli kabul edilir.

Mevcut tabanımızdaki dosyalar şöyle görünür:

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

Ve bunları şöyle bir şeye dönüştürmek istiyoruz:

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

Telif hakkı yerine yalnızca #ifdefs değil, #if tanımlı (UNDER_RESEARCH) gibi varyasyonları değiştirebilen bir araç, ayrıştırma kitaplığı veya popüler komut dosyası var mı?

Kod şu anda Git'te ve büyük olasılıkla Git kullanan bir yerde barındırılıyor. Açık kaynak sürümleriyle iyileştirmelerimizi verimli bir şekilde yeniden entegre edebilmemiz için depoları güvenli bir şekilde birbirine bağlamanın bir yolu var mı? Diğer tuzaklar hakkında tavsiye edilir.


13
Bu kod tabanı dallar için çığlık atıyor.
Florian Margaine

Bu amaçla dalların kullanımına bir örnek memnuniyetle karşılanacaktır.
DeveloperDon

Yanıtlar:


6

O preprocessors ayrıştırmak için bir senaryo yazmak çok zor olmaz gibi tanımlanmış sabitleri (listesine karşılaştırmak, görünüyor UNDER_RESEARCH, FUTURE_DEVELOPMENTyönerge tanımlanmış ne yanlış verilmiş, yukarı kaldırma herşey için değerlendirilebilir eğer, vb) ve, bir sonrakine #endif.

Python'da şöyle bir şey yaparım,

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')

Eminim bunu yapmanın daha zarif yolları vardır, ancak bu hızlı ve kirli ve işi bitirmiş gibi görünüyor.


Vay canına, teşekkürler. İyi bir filtre yapmak için potansiyel olarak çok fazla mantık var ve örneğinizi takdir ediyorum. Yeniden kullanım için bir şey bulmayı umuyorum ve geliştirme makinem büyük bir bellekle hızlı, bu nedenle performans telif hakkı ve tanımlar için ayrı filtreler çalıştırmak veya tanım filtresini bir kereden fazla çalıştırmak için çok büyük bir endişe değil. Aslında, gelecekteki birden çok projeyi belirleyen anahtar kelimeler ve açık kaynaklı yayınlanmayacak, ancak yine de dahili olarak ve müşterileri erken benimseyerek kullanılan birkaç geçmiş projeyle ilgili birden fazla tanımımız var.
DeveloperDon

3

Kodunuzu yalnızca makroları genişletmek için önişlemciden geçirmeyi düşünüyordum, böylece s'deki ilginç kısmı çıkardı #ifdef.

Böyle bir şey işe yaramalı:

gcc -E yourfile.c

Fakat:

  • Tüm yorumları kaybedeceksiniz. Bunları -CCkorumak için kullanabilirsiniz (ancak), yine de eski telif hakkı bildirimini kaldırmanız gerekir
  • #includes de genişletilir, böylece içerilen başlık dosyalarının tüm içeriğini içeren büyük bir dosya elde edersiniz
  • "Standart" makroları kaybedeceksiniz.

Hangi makroların genişletileceğini sınırlamanın bir yolu olabilir; ancak buradaki önerim, dosyalar üzerinde (potansiyel olarak tehlikeli) işlem yapmak yerine işleri bölmektir (bu arada, bunları nasıl sürdürmeyi planlıyorsunuz? örneğin, kodu açık kaynaklı sürümden kapalı kaynağınıza yeniden ekleyin?).

Yani, açmak istediğiniz kodu harici kitaplıklara olabildiğince koymayı deneyin, sonra bunları diğer "özel" kapalı kaynak kitaplıklarla entegre ederek diğer kitaplıklarda olduğu gibi kullanın.

İlk başta bir şeylerin nasıl yeniden yapılandırılacağını bulmak biraz daha uzun sürebilir, ancak bunu başarmanın kesinlikle doğru yolu.


Henüz serbest bırakmayacağımız blokları seçici bir şekilde ortadan kaldırmak için önişlemci ile yapılabilecek bir şey olup olmadığını düşünmüştüm. Kod karmaşıktır ve muhtemelen daha az değil, daha fazla yoruma ihtiyacımız olacaktır, ancak öneriniz kesinlikle beyin fırtınası listesinde bulunmaya değer. WRT, kaynağı nasıl koruyacağımızı ve kodu topluluğa geri ve ileri nasıl taşıyacağımızı planlıyor, daha fazla planlama gerekiyor. Kodu tescilli koda getirmek bazı iyi soruları gündeme getirir.
DeveloperDon

2

Bir çözümüm var ama biraz iş gerektirecek

pypreprocessor , diğer kaynak kodu türleri için GPP (Genel Amaçlı Ön İşlemci) olarak da kullanılabilen, python için saf bir c tarzı ön işlemci sağlayan bir kütüphanedir.

İşte temel bir örnek:

from pypreprocessor import pypreprocessor

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

Önişlemci son derece basittir. Kaynaktan bir geçiş yapar ve tanımlanmış olana bağlı olarak kaynağı koşullu olarak yorumlar.

Tanımlar , kaynaktaki #define ifadeleri aracılığıyla veya pypreprocessor.defines listesinde ayarlanarak ayarlanabilir.

Giriş / çıkış parametrelerini ayarlamak, hangi dosyaların açıldığını / kapatıldığını açıkça tanımlamanızı sağlar, böylece tek bir önişlemci istenirse çok sayıda dosyayı toplu olarak işleyecek şekilde ayarlanabilir.

RemoveMeta parametresini True olarak ayarladığınızda, önişlemci, önceden işlenen kodu bırakarak tüm önişlemci deyimlerini otomatik olarak ayıklamalıdır.

Not: Python, bayt koduna derleme sırasında yorumlanmış kodu otomatik olarak kaldırdığı için genellikle bunun açıkça ayarlanması gerekmez.

Sadece bir kenar durumu görüyorum. C kaynağını ön işlemek istediğiniz için, işlemci tanımlarını açıkça (yani pypreprocessor.defines aracılığıyla) ayarlamak ve kaynaktaki #define ifadelerini yoksaymasını isteyebilirsiniz . Bu, projenizin kaynak kodunda kullanabileceğiniz sabitleri yanlışlıkla kaldırmasını engellemelidir. Şu anda bu işlevi ayarlamak için herhangi bir parametre yoktur, ancak eklemek önemsiz olacaktır.

İşte önemsiz bir örnek:

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()

Sonra kaynak:

#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

Not: Açıkçası, giriş / çıkış dosyalarını ayarlamak için bir yol bulmanız gerekir, ancak bu çok zor olmamalıdır.

Açıklama: Ben bir önişlemcinin orijinal yazarıyım.


Bir kenara: Başlangıçta korkunç python 2k / 3x bakım sorununa bir çözüm olarak yazdım. Benim yaklaşımım, aynı kaynak dosyalarda 2 ve 3 geliştirme yapmak ve sadece önişlemci direktiflerini kullanarak farklılıkları dahil etmek / hariç tutmak oldu. Ne yazık ki, python'da gerçek bir saf (yani c gerektirmez) önişlemci yazmanın imkansız olduğunu keşfettim çünkü ön işlemcinin çalışma şansı elde etmeden önce lexer sözdizimi hatalarını uyumsuz kodda işaretliyor. Her iki durumda da, sizinkiler de dahil olmak üzere çok çeşitli koşullar altında hala yararlıdır.


Bu kayalar. Başka bir şey, hariç tutmak istediğimiz kodlu ve kodsuz dosyaları işleyen, farklarını alan, sonra farklı satırları orijinalden çıkaran üç yollu fark gibi bir şey yapamazdık.
DeveloperDon

@DeveloperDon Yep, genel fikir bu. Bununla başa çıkmanın birkaç farklı yolu vardır, bu, kesin yayın döngüsünü nasıl yönetmeyi planladığınıza bağlıdır. Bu parça, aksi takdirde sıkıcı ve / veya hataya meyilli olabilecek birçok işi otomatik olarak ortadan kaldırır.
Evan Plaice

1

Muhtemelen iyi bir fikir olurdu

1. gibi yorum etiketleri ekleyin:

> // *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. Açık kaynak oluşturucunun tüm dosyaları incelemesi için komut dosyası yazın ve COPYRIGHT-BEGIN-TAG ve COPYRIGHT-ENG-TAG etiketleri arasındaki metni değiştirin


1
Başlangıç ​​etiketine ihtiyacım var mı? Şimdiye kadar tüm kaynak dosyalarımız ilk satırdaki telif hakkı ile başlıyor ve kabuk komut dosyalarımız ikinci satırdaki telif hakkı ile başlıyor. Çok fazla dosya var, bu yüzden mümkün olan en az el düzenlemesini yapmak istiyorum.
DeveloperDon

Bazı dosyaların işlevlerini, parametrelerini ve değer adlarını döndürmek için Doxygen'i kullanabileceğini düşünüyorum. Bu şekilde ayarlanmamış dosyalar için, bu yönde daha fazla yer alan bir seçim yaparsak gerçekten çok fazla düzenleme olabilir.
DeveloperDon

En azýndan bir kez deđiţtirmelisin. telif hakkı politikanız değiştiyse yönetebilirsiniz.
Alex Hashimi

1

Size kod tabanınızı dönüştürmek için bir araç göstermeyeceğim, birçok cevap zaten bunu yaptı. Bunun yerine, bunun için şubelerin nasıl ele alınacağı hakkındaki yorumunuzu yanıtlıyorum.

2 şubeniz olmalıdır:

  • Topluluk (açık kaynak sürümünü böyle söyleyelim)
  • Profesyonel (kapalı kaynak sürümünü böyle söyleyelim)

Önişlemciler mevcut olmamalıdır. İki farklı sürümünüz var. Ve genel olarak daha temiz bir kod tabanı.

İki kopyayı paralel tutmaktan mı korkuyorsunuz? Endişelenme, birleştirebilirsin!

Topluluk şubesinde değişiklik yapıyorsanız, bunları profesyonel şubede birleştirmeniz yeterlidir. Git bunu çok iyi halleder .

Bu şekilde, kod tabanınızın 2 kopyasını saklarsınız. Ve açık kaynak için bir tane bırakmak pasta gibi kolaydır.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.