Mon entreprise (appelons-les Acme Technology) possède une bibliothèque d'environ un millier de fichiers source provenant à l'origine de son groupe de recherche Acme Labs, incubés dans un groupe de développement pendant quelques années, et plus récemment, fournis à une poignée de clients sous non-divulgation. Acme s'apprête à publier peut-être 75% du code à la communauté open source. Les 25% restants seraient publiés plus tard, mais pour l'instant, soit ils ne sont pas prêts à être utilisés par le client, soit ils contiennent du code lié aux futures innovations dont ils ont besoin pour rester hors de la portée des concurrents.
Le code est actuellement formaté avec #ifdefs qui permet à la même base de code de fonctionner avec les plates-formes de pré-production qui seront disponibles pour les chercheurs universitaires et un éventail beaucoup plus large de clients commerciaux une fois qu'il sera ouvert, tout en étant en même temps disponible pour l'expérimentation et le prototypage et les tests de compatibilité ascendante avec la future plateforme. Garder une base de code unique est considéré comme essentiel pour l'économie (et la santé mentale) de mon groupe qui aurait du mal à maintenir deux copies en parallèle.
Les fichiers de notre base actuelle ressemblent à ceci:
> // 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
> }
Et nous aimerions les convertir en quelque chose comme:
> // GPL Copyright (C) Acme Technology Labs 2012, Some rights reserved.
> // Acme appreciates your interest in its technology, please contact [email protected]
> // for technical support, and www.acme.com/emergingTech for updates and RSS feed.
>
> ... Usual header stuff...
>
> void initTechnologyLibrary() {
> nuiInterface(on);
> }
Existe-t-il un outil, une bibliothèque d'analyse ou un script populaire qui peut remplacer le droit d'auteur et supprimer non seulement #ifdefs, mais des variantes comme #if défini (UNDER_RESEARCH), etc.?
Le code est actuellement dans Git et serait probablement hébergé quelque part qui utilise Git. Existerait-il un moyen de lier les référentiels en toute sécurité afin que nous puissions réintégrer efficacement nos améliorations avec les versions open source? Des conseils sur d'autres pièges sont les bienvenus.
la source
Réponses:
Il semble que ce ne serait pas trop difficile d'écrire un script pour analyser les préprocesseurs, les comparer à une liste de constantes définies (
UNDER_RESEARCH
,FUTURE_DEVELOPMENT
, etc.) et, si la directive peut être évaluée à false GIVEN ce qui est défini, tout supprimer jusqu'à au suivant#endif
.En Python, je ferais quelque chose comme,
Je suis sûr qu'il existe des façons plus élégantes de le faire, mais c'est rapide et sale et semble faire le travail.
la source
Je pensais à passer votre code à travers le préprocesseur pour ne développer que les macros, ne produisant ainsi que la partie intéressante du
#ifdef
s.Quelque chose comme ça devrait fonctionner:
Mais:
-CC
pour (en quelque sorte) les conserver, mais vous devrez alors supprimer l'ancien avis de copyright#include
les s sont également développés, vous vous retrouverez donc avec un gros fichier contenant tout le contenu des fichiers d'en-tête inclusIl existe peut-être un moyen de limiter les macros développées; cependant ma suggestion ici est de diviser les choses, au lieu de faire un traitement (potentiellement dangereux) sur les fichiers (au fait, comment prévoyez-vous de les conserver après? par exemple réintroduire du code de la version opensource dans votre source fermée?).
C'est-à-dire, essayez de mettre le code que vous souhaitez ouvrir dans des bibliothèques externes autant que possible, puis utilisez-les comme vous le feriez avec n'importe quelle autre bibliothèque, en l'intégrant à d'autres bibliothèques de sources fermées "personnalisées".
Cela peut prendre un peu plus de temps au début pour comprendre comment restructurer les choses, mais c'est certainement la bonne façon d'y parvenir.
la source
J'ai une solution mais cela demandera un peu de travail
pypreprocessor est une bibliothèque qui fournit un préprocesseur de style c pur pour python qui peut également être utilisé comme GPP (General Purpose Pre-Processor) pour d'autres types de code source.
Voici un exemple de base:
Le préprocesseur est extrêmement simple. Il passe à travers la source et commente conditionnellement la source en fonction de ce qui est défini.
Les définitions peuvent être définies via les instructions #define dans la source ou en les définissant dans la liste pypreprocessor.defines.
La définition des paramètres d'entrée / sortie vous permet de définir explicitement quels fichiers sont ouverts / fermés afin qu'un seul préprocesseur puisse être configuré pour traiter par lots un grand nombre de fichiers si vous le souhaitez.
En définissant le paramètre removeMeta sur True, le préprocesseur doit extraire automatiquement toutes les instructions du préprocesseur en ne laissant que le code post-traité.
Remarque: Habituellement, cela n'a pas besoin d'être défini explicitement car python a supprimé automatiquement le code commenté lors de la compilation en bytecode.
Je ne vois qu'un seul cas de bord. Parce que vous cherchez à prétraiter la source C, vous souhaiterez peut-être définir les définitions de processeur de manière explicite (c'est-à-dire via pypreprocessor.defines) et lui dire d'ignorer les instructions #define dans la source. Cela devrait l'empêcher de supprimer accidentellement les constantes que vous pouvez utiliser dans le code source de votre projet. Il n'y a actuellement aucun paramètre pour définir cette fonctionnalité mais il serait trivial de l'ajouter.
Voici un exemple trivial:
Puis la source:
Remarque: Évidemment, vous devrez trouver un moyen de définir les fichiers d'entrée / sortie, mais cela ne devrait pas être trop difficile.
Divulgation: je suis l'auteur original de pypreprocessor.
En plus: je l'ai écrit à l'origine comme une solution au problème de maintenance redouté de python 2k / 3x. Mon approche était de faire le développement 2 et 3 dans les mêmes fichiers sources et d'inclure / exclure simplement les différences en utilisant les directives du préprocesseur. Malheureusement, j'ai découvert à la dure qu'il est impossible d'écrire un vrai préprocesseur pur (c'est-à-dire qu'il ne nécessite pas c) en python car le lexer signale les erreurs de syntaxe dans le code incompatible avant que le préprocesseur ait la chance de s'exécuter. Quoi qu'il en soit, il est toujours utile dans un large éventail de circonstances, y compris la vôtre.
la source
Ce serait probablement une bonne idée de
1. ajoutez des balises de commentaire comme:
2. Écrire un script pour que le générateur open source passe par tous les fichiers et remplace le texte entre les balises COPYRIGHT-BEGIN-TAG et COPYRIGHT-ENG-TAG
la source
Je ne vais pas vous montrer un outil pour convertir votre base de code, de nombreuses réponses l'ont déjà fait. Je réponds plutôt à votre commentaire sur la façon de gérer les branches pour cela.
Vous devriez avoir 2 branches:
Les préprocesseurs ne devraient pas exister. Vous avez deux versions différentes. Et une base de code plus propre dans l'ensemble.
Vous avez peur de conserver deux copies en parallèle? Ne vous inquiétez pas, vous pouvez fusionner!
Si vous apportez des modifications à la branche communautaire, fusionnez-les simplement dans la branche professionnelle. Git gère ça très bien.
De cette façon, vous conservez 2 copies maintenues de votre base de code. Et en publier un pour l'open source est facile comme bonjour.
la source