Si Java est un langage à usage général et que la construction d'un programme peut être décrite en utilisant le langage Java, pourquoi n'est-ce pas la meilleure façon d'écrire des fichiers de construction et à la place nous utilisons des outils comme Ant, Maven et Gradle? Cela ne serait-il pas plus simple et supprimerait-il également la nécessité d'apprendre un autre langage de programmation? (BTW - cette question peut également être appliquée à d'autres langues, comme C #)
java
c#
builds
build-system
vainolo
la source
la source
Réponses:
Outil spécifique pour un but spécifique
Verbosité
Les langages à usage général sont souvent trop verbeux. Si je devais gérer une build en Java, je serais très déprimé très rapidement par la taille de la bête. Cependant, il pourrait facilement être gérable à l'aide d'un DSL écrit en Java. Et dans une certaine mesure, c'est ainsi que vous pouvez voir Gradle (pour Groovy) et Buildr (pour Ruby).
Difficulté
Les langages à usage général sont difficiles. Eh bien, je ne pense pas que la programmation soit difficile et ne puisse être reprise par personne, mais le fait est que votre ingénieur en construction n'est pas nécessairement votre programmeur!
Objectif
C'est plus ou moins à l'intersection de la difficulté et de la verbosité . Un langage est conçu dans un but, et nous parlons ici de quelque chose de très spécifique. Alors pourquoi voudriez-vous ou voudriez-vous utiliser un langage à usage général ? Pour les builds, vous avez besoin de:
Vous n'avez pas vraiment besoin de beaucoup plus.
Bien sûr, c'est ennuyeux lorsque votre système de construction semble ne pas être suffisamment flexible pour le cas d'utilisation spécial que vous recherchez, mais c'est probablement bien mieux que l'alternative pour la plupart des gens.
C'est probablement pourquoi il y a une polarité entre les personnes qui préfèrent les systèmes de construction déclaratifs à la plupart des onces programmables: je suppose qu'un développeur pourrait avoir une tendance naturelle à chercher des moyens de sortir de la boîte.
Attendez, avons-nous vraiment besoin d'un outil?
Une autre question connexe serait: avons-nous vraiment besoin d'un outil de construction? Le fait qu'ils existent dans toutes les langues n'est-il pas le signe qu'ils comblent une lacune qui ne devrait même pas être là en premier lieu?
Certaines langues ne nécessitent pas nécessairement un outil de construction. Par exemple, la plupart des langages de script n'en ont pas besoin et se résolvent au moment du chargement. Ou prenez Go, dont le compilateur gérera tout pour vous, ce qui est un joli contrepoint: et si un compilateur comme gcc n'avait soudainement pas besoin d'un tas de drapeaux, d'un éditeur de liens et d'un makefile pour tout mourir ensemble? Ou si javac n'avait pas besoin d'un build.xml ou pom.xml pour lui dire quoi faire? La gestion des dépendances ne devrait-elle pas faire directement partie des outils du langage, car les dépendances font partie du programme final?
Cela semble sûrement une approche beaucoup plus simple pour l'utilisateur (le constructeur). Bien que l'on puisse dire qu'ils font juste sous le capot et enlèvent votre choix et vos opportunités d'influencer ce processus de construction (mais alors vous espérez qu'un tel outil autorise des extensions de compilateur et des choses similaires). De plus, nous avions l'habitude de voir les outils et la langue comme deux choses distinctes, donc il peut sembler impur de les avoir soudainement si étroitement couplés.
Je ne pense pas que le langage que vous utilisez pour créer vos programmes soit le problème. C'est le langage que vous utilisez pour programmer, sa plate-forme de base et ses outils qui devraient être importants, et nous progressons toujours à cet égard.
Personnellement, j'ai utilisé make / gmake / autotools / pmk et j'en suis content pour C, et j'ai commencé avec Java quand tout ce que nous avions était make, puis ant, et maintenant je préfère généralement Maven à toutes ces alternatives. Bien que je puisse voir la valeur dans gradle, buildr et autres, mais j'aime la prévalence de maven jusqu'à présent, jusqu'à ce qu'un changement plus important se produise. De plus, j'aime le fait qu'il soit rigide, mais vous laisse toujours la possibilité de contourner cela si nécessaire. Que ce ne soit pas facile est une bonne chose.
C'est un outil de construction. Apprenez simplement à l'embrasser et ne le combattez pas. C'est une bataille perdue. Ou du moins une très très longue.
la source
Java
est un impératif langue,Ant
,Maven
, etc. sont déclaratives langues:Les langues de construction le disent au constructeur ce qui doit être fait, d' où cela doit être pris, etc. Le moteur qui exécute la construction (qui est écrit dans un langage impératif, comme @ElliottFrisch l'a noté), lit ces instructions et les remplit.
Les langages déclaratifs peuvent sembler plus appropriés dans les scénarios de génération, car les tâches de génération sont généralement les mêmes partout, et elles sont considérées comme plus faciles à gérer et à lire sous cette forme que sous forme de code à part entière.
la source
Si vous regardez les caractéristiques d'un système de construction typique, vous trouvez:
Si vous envisagez d'écrire une série de fichiers de construction en utilisant un langage (Java / C # / Python / etc), vers la troisième ou la quatrième itération, vous vous contenterez (a) de conserver la plupart des données et des commandes externes en tant que données dans quelque chose comme XML (b) écrire le "moteur de construction" dans votre langue préférée.
Vous trouverez également utile de traiter certaines des données de votre XML comme un langage interprété, pour déclencher diverses fonctionnalités dans le moteur de génération. Vous pouvez également interpréter certaines macros ou effectuer des substitutions de chaînes dans les données.
En d'autres termes, vous finiriez avec Make, ou Ant, ou Rake, ou MsBuild. Un langage impératif pour ce qu'il fait bien, et des structures de données pour décrire ce que vous voulez faire, désormais généralement en XML.
la source
Un certain nombre de facteurs comptent contre l'utilisation de Java / C ++ / C # dans ces cas.
Tout d'abord, vous devez compiler votre script de génération avant de pouvoir l'exécuter pour créer votre application. Comment spécifieriez-vous les packages, drapeaux, versions de compilateur, chemins d'outils nécessaires pour construire votre script de construction? Certes, vous pouvez trouver un moyen de le contourner, mais il est beaucoup plus simple d'avoir soit un langage qui n'a pas besoin de cette étape de construction (par exemple python) ou un langage que votre outil de construction comprend nativement.
Deuxièmement, les fichiers de construction sont lourds de données alors que Java / C ++ / C # sont beaucoup plus axés sur l'écriture de code et d'algorithmes. Java et ses amis n'ont pas une représentation très succincte de toutes les données que vous souhaitez stocker.
Troisièmement, Java et ses amis ont besoin de beaucoup de passe-partout pour être valides. Le fichier de construction devrait être à l'intérieur d'une méthode à l'intérieur d'une classe avec toutes ses importations. Lorsque vous utilisez un langage de script ou un langage personnalisé, vous pouvez éviter tout ce passe-partout et simplement avoir les détails de construction eux-mêmes.
la source
Effectivement! Pourquoi ne pas utiliser un puissant et expressif langage pour un problème plus complexe qu'on ne le pense souvent (au départ)? Surtout quand les personnes confrontées au problème sont déjà compétentes avec une telle langue. (La construction est le problème des programmeurs et est le mieux résolu par les programmeurs.)
Je me suis aussi posé cette question il y a des années et j'ai décidé que Java est un bon langage pour définir des builds, en particulier pour des projets Java. Et, en conséquence, j'ai commencé à faire quelque chose à ce sujet.
AVERTISSEMENT : Dans cette réponse, je fais la promotion d' iwant , un système de build que je développe. Mais comme il s'agit de toute façon d'une discussion d'opinion, je suis sûr que ça va.
Je ne m'étendrai pas sur les avantages de Java (puissance et expressivité) ou iwant en particulier. Si vous êtes intéressé, vous pouvez en lire plus sur la page iwant .
Au lieu de cela, je considérerai pourquoi Java (et d'autres GPL) est si facilement rejeté comme impropre à la construction. De nombreuses réponses et commentaires sont de bons exemples d'une telle réflexion. Examinons certains des arguments typiques:
"Java est impératif, mais les builds sont mieux définis de manière déclarative" , pourraient-ils dire.
Vrai. Mais lorsque vous utilisez un langage comme métalangage pour une DSL interne , ce qui compte vraiment, c'est sa syntaxe . Même un langage impératif comme Java peut être trompé pour être déclaratif. S'il semble et se sent déclaratif, il est (à des fins pratiques) déclaratif. Par exemple:
Ceci est un véritable exemple du projet de démonstration d'iwant .
En fait, comparez cela à certains systèmes de construction soi-disant déclaratifs qui exposent leurs utilisateurs à des verbes impératifs tels que "tester" ou "compiler". La déclaration ci-dessus ne contient que des noms, pas de verbes. La compilation et le test sont des tâches implicitement gérées par iwant afin d'accorder à l'utilisateur les noms qu'il souhaite. Ce n'est pas la langue. C'est ainsi que vous l'utilisez.
"Java est verbeux"
Oui, beaucoup de code Java est verbeux. Mais encore une fois, ce n'est pas la langue, c'est la façon dont vous l'utilisez. Si une implémentation est verbeuse, il suffit de l'encapsuler derrière une belle abstraction. De nombreuses GPL fournissent des mécanismes adéquats pour cela.
Imaginez simplement l'extrait Java ci-dessus écrit en XML. Remplacez les parenthèses par des équerres et déplacez-les. Et puis dupliquez chaque mot-clé comme une balise de fermeture! Java en tant que syntaxe n'est pas verbeux.
(Je sais, comparer à XML, c'est comme prendre des bonbons à un bébé, mais tant de builds se trouvent être définis en XML.)
"Vous devrez compiler votre script de construction"
Ceci est un point valable. Néanmoins, ce n'est qu'un problème technique mineur à résoudre. J'aurais pu le résoudre en utilisant beanshell ou un autre interprète. Au lieu de cela, je l'ai résolu en le traitant comme un autre problème de construction et en amorçant iwant avec un simple shell ou script ant qui compile et exécute un simple bootstrapper Java.
"Java a passe-partout"
Vrai. Vous devez importer des classes, vous devez mentionner "public", "class" et ainsi de suite. Et ici, de simples DSL externes marquent une première victoire facile.
Et si votre projet est si banal que ce passe-partout est important, bravo. Votre problème n'est pas difficile et peu importe comment vous le résolvez.
Mais de nombreux projets nécessitent bien plus que la compilation, le rapport de couverture et le packaging. Si le passe-partout de Java est acceptable pour les problèmes des clients, pourquoi ne pas créer des problèmes? Pourquoi fabriquer des chaussures uniquement pour les enfants des autres?
la source
Une chose que je ne pense pas que les autres réponses aient abordée est que les limitations et la transparence de ces langages de construction sont une partie énorme de ce qui les rend utiles. Prenons Maven, par exemple. Oui, il exécute des builds mais il définit également des dépendances. Cela permet à une génération Maven de supprimer ces dépendances et de regarder leurs dépendances, etc.
Demandez-vous si cela a été fait directement avec Java. L'outil de génération verrait qu'il existe une dépendance. Il faudrait ensuite dérouler une autre application Java et l'exécuter pour déterminer quelles sont ses dépendances. Mais pour Maven, il regarde simplement les déclarations de dépendance. Le fichier de construction maven est transparent. Un langage complet de Turing est intrinsèquement non transparent et est donc inférieur à certaines fins telles que celle-ci.
la source