0

This is related to a former question about CPAN::Meta::Spec, which doesn't seem to be designed for what I thought I could use it.

My use case

I have different Perl apps containing of a lot of packages themself, depending on some home grown system wide utility stuff and of course 3rd party packages. Those apps might provide different features depending on runtime config and depending on those features, dependencies are different. Additionally, if automated tests are available, those might introduce dependencies as well and in the most current example those dependencies where available in ActiveState Perl 5.22 on Windows by default already, where on Ubuntu 16.04 those needed to be installed using APT.

My own apps and utility stuff are maintained using Subversion and the repos at least partly publicly available to customers as well. 3rd party packages are preferred to be maintained by the package manager of the OS like APT or the Perl distribution, like PPM for ActiveState Perl on Windows. Only if some dependency is not available that way, CPAN comes into play.

What I would like to achieve...

...is describing my apps and system wide utility stuff with their dependencies in a way that allows me to distinguish e.g. runtime from development or tests and being able to distinguish optional features and their dependencies. Additionally, I would like to maintain some repos where e.g. my own apps and system wide utilities can be downloaded from.

What I don't want...

...is to maintain at multiple places each and every individual package I'm using somewhere, because that doesn't make much sense to me. APT is not necessarily installing individual Perl packages, but instead some higher level distribution containing multiple of those, a complete app for example. If dependencies are introduced, developers need to check anyway if those are available on all platforms of interest, which is not necessarily the case, and how those are distributed on each platform, e.g. APT, PPM or CPAN. So dependencies on individual packages can not be introduced easily without checking how those packages are distributed on which platform. Therefore it seems enough for my needs to manage dependencies ABOVE a package level, which is what mostly gets maintained on platforms anyway.

Additionally, this is how e.g. Maven and Gradle work: One doesn't depend on individual classes like org.apache.commons.lang3.AnnotationUtils or org.apache.commons.io.ByteOrderMark, but on distributions containing those classes like Apache Commons Lang and Apache Commons IO in some specific version. While individual classes are imported in some class in the end, the project description and its dependencies itself doesn't contain that level of detail. I don't see why I should dive deeper in Perl if it works for Java pretty well and if I need to check at distribution level anyway if Perl-dependencies can be fulfilled at all.

What I need

So, what I need is some spec/DSL to describe my project with some name, version number, its dependencies and most likely different repos where to get things from. Such a repo would be my own SVN-repos or concepts like APT or PPM, at best even with additional repos for those, if one decides to host such. In the end, some tools like Ansible should be used to install some app of mine while being able to deal with dependencies automatically, using plugins or additional tools or whatever, based on the specs in each app/project.

What I've found so far

For Perl this lead me to cpanm, cpanfile and CPAN::Meta::Spec, both being able to distinguish runtime from test, support optional features etc. The latter can even model different repos. But both only seem to support dependencies on package instead of some higher distribution level. One might be able to work around this using some packages acting as placeholder for distributions, though. E.g. by creating sysutils.pm containing package sysutils; and defining some version only. Apps could then depend on that package using the above formats.

Downsides recognized so far

But people e.g. recommend to not write CPAN::Meta::Spec manually, but use some build and authoring tools instead. The problem with those is that some/most are considered deprecated by the linked blog post itself or other sources and some examples even are providing manually written CPAN::Meta::Spec to those tools in the end only. And if not, they sometimes simply expect infos of CPAN::Meta::Spec in some custom configuration format, which seems not as well defined as the spec itself. So why use those tools at all instead of writing the spec manually?

Even the CPAN::Meta::Spec itself seems to be problematic, as the most current version 2 seems to prefer JSON for some undocumented reason. That is a bad decision for manually writing and maintaining that spec of course, because JSON lacks comments, which is a no-go for any kind of description maintained by humans in my opinion.

Questions

  1. So, which format/spec can I use to manually describe some abstract distribution using some name and version, including it's optional features and dependencies? Pretty much what seems to be possible with CPAN::Meta::Spec already, only that package level dependencies seem too low level for me currently.

  2. Which tool should be used to resolve dependencies based on the former spec and supports different source-repos for dependencies like APT, PPM and SVN?

  3. With things like Ansible coming into play, is it worth it to maintain some Perl-specific description at all anymore or should one simply use Ansible to describe dependencies and let Ansible provide all of those using plugins or whatever?

Thanks for your suggestions!

Thorsten Schöning
  • 3,501
  • 2
  • 25
  • 46
  • "some/most are considered deprecated" - this is irrelevant. Don't use Module::Build or Module::Install, information is provided for them for the benefit of people still using them. There are many other options which are actively used and maintained. – Grinnz Feb 02 '19 at 20:41
  • The real question is how you expect to use this metadata. CPAN::Meta::Spec and META.json are designed for consumption by PAUSE and CPAN installers. If you will not be using a CPAN installer, then there is no reason for you to use it, though you could certainly use it as inspiration. cpanfile on the other hand is a format designed for specifying Perl module dependencies and can be read by anything using Module::CPANfile, hence why I recommended it previously. – Grinnz Feb 02 '19 at 20:42
  • 1
    Additionally cpanm (dev versions only) and carton recognize some options you can apply to cpanfile requirements to install from a specific URL, this may be of use. [The carton docs mention it](https://metacpan.org/pod/Carton#Specifying-a-CPAN-distribution) and I have an [open pull request](https://github.com/miyagawa/cpanminus/pull/579) to document it for cpanm. – Grinnz Feb 02 '19 at 20:48
  • Re "*Pretty much what seems to be possible with CPAN::Meta::Spec already, apart from package level dependencies.*", You are mistaken. CPAN::Meta::Spec is entirely about defining dependencies on packages. The catch is, it's about defining dependencies on Perl (CPAN) packages. You obviously want dependencies on some other type of package. This brings us to the key question: What kind of packages are you talking about? We can't tell you how to define optional dependencies in a system if you don't specify what system. – ikegami Feb 02 '19 at 21:03
  • @Grinnz `dist` and `url` in deed look interesting. Do you know of any support for package manager like `APT` or `PPM` currently? Might be possible to implement it like with `url`? – Thorsten Schöning Feb 03 '19 at 13:51
  • @ikegami My quoted sentence doesn't say that `CPAN::Meta::Spec` doesn't provide package level dependencies, but that I don't want to model dependencies at that low level only. I want to model dependencies on what `CPAN::Meta::Spec` calls a distribution, but of course for Perl, because that is what e.g. APT, PPM and even CPAN-clients install at the end, not individual packages. I prefer APT and PPM instead of CPAN and therefore need to decide at their level what my dependencies are. – Thorsten Schöning Feb 03 '19 at 13:58
  • @ikegami There is no e.g. PAUSE for APT mapping individual Perl packages to distributions and additionally the developer needs to decide currently how a distribution is available at all. It might be using APT, it might be some SNAP, it might be PPM, it might be not at all on Windows because of XS in use and code doesn't compile on Windows or whatever. So simply specifying a dependency on `Some::Foo::Bar::Package` alone won't help me deciding if that is available using APT or whatever. – Thorsten Schöning Feb 03 '19 at 14:01
  • @ikegami If it's available using APT, the distribution name for that is my dependency in my opinion. Have a look at the following APT-distribution, which contains a lot of individual Perl packages. I would like to manage the dependency at that level, simply because I know all necessary things are available using APT, APT handles transitive dependencies itself etc. https://packages.ubuntu.com/xenial/all/carton/filelist – Thorsten Schöning Feb 03 '19 at 14:03
  • Re "*I want to model dependencies on what CPAN::Meta::Spec calls a distribution*", Ok, undeleted my answer since that's exactly what it covers. I thought I wanted something else. – ikegami Feb 03 '19 at 17:00
  • @ThorstenSchöning Apt or RPM would be a more appropriate tool for what it sounds like you want to do, since they are capable of depending on versions of other deb or rpm packages. Using these has nothing to do with CPAN::Meta::Spec or cpanfiles, you would use whatever tools are appropriate for that ecosystem and create a deb/rpm for each distribution involved. – Grinnz Feb 03 '19 at 17:40
  • @Grinnz The point is that APT doesn't always provide the Perl packages I need, only mostly, sometimes I need to use CPAN instead. APT doesn't work on Windows for ActiveState PPM, sometimes I need CPAN on Windows as well, and it doesn't integrate with simple e.g. SVN checkouts. I need something able to integrate all of those and because CPAN is used sometimes, I know it has specs describing dependencies and my apps are Perl already anway, I thought I focus on the specs and tools of the CPAN ecosystem first. – Thorsten Schöning Feb 04 '19 at 10:32

1 Answers1

1

I want to model dependencies on what CPAN::Meta::Spec calls a distribution

When using ExtUtils::MakeMaker, META_MERGE gives you access to fields from the META spec that allow you to specify the information you want to specify. The following snippet from DateTime::Format::Atom demonstrates this:

META_MERGE  => {
   'meta-spec' => { version => 2 },

   prereqs => {
      configure => {
         requires => {
            'ExtUtils::MakeMaker'       => 6.74,
         },
      },
      runtime => {
         requires => {
            'strict'                    => 0,
            'version'                   => 0,
            'warnings'                  => 0,
            'DateTime'                  => 0,
            'DateTime::Format::RFC3339' => 0,
         },
      },
      test => {
         requires => {
            'Test::More'                => 0,
         },
      },
      develop => {
         requires => {
            'FindBin'                   => 0,
            'Pod::Coverage'             => 0.18,
            'Test::Pod::Coverage'       => 1.08,
         },
      },
   },
},

Consult this for the full prereqs spec.


But both only seem to support dependencies on package instead of some higher distribution level."

You're making a fuss about nothing. It doesn't matter that you have to use Foo::Bar instead of Foo-Bar.

ikegami
  • 367,544
  • 15
  • 269
  • 518
  • I don't see with your example how exactly it allows me to depend on APT RPM-packages I already know the name of or distributions placed within some SVN-Repos? You are still relying on e.g. `PAUSE` mapping individual Perl packages to some distribution known to CPAN, but there is nothing I know of doing such mapping for APT-packages. Additionally, what does using `MakeMaker` make easier compared to writing `META.*` manually? Does it handle installing dependencies and acts as a CPAN-client as well? Don't have the feeling and I don't need makefiles,, APT and PPM should handle such things. – Thorsten Schöning Feb 03 '19 at 17:28
  • Re "*I don't see with your example how exactly it allows me to depend on APT RPM-packages*", It doesn't. You said you wanted "to model dependencies on what CPAN::Meta::Spec calls a distribution". apt distros aren't CPAN distros. – ikegami Feb 03 '19 at 17:34
  • Re "*what does using `MakeMaker` make easier compared to writing `META.*` manually?*", Do you realize that `cpan` doesn't install modules? It's really just a dependency walker and a downloader. It calls the distro's `Makefile.PL` or `Build.PL` to do the actual testing and installing. MakeMaker a module installer. Creating `META.*` is just a little favour it does for you. If you want to do it manually, have fun. – ikegami Feb 03 '19 at 17:42
  • APT-distros and CPAN-distros are conceptually the same thing compared to Perl-packages managed as dependency by CPAN::Meta::Spec, which are one level below distros. And because CPAN knows distros, APT knows distros and even SVN might know a distro based e.g. on its URL, but neither APT nor SVN know Perl-packages, I want to model dependencies on distro-level. – Thorsten Schöning Feb 03 '19 at 17:47
  • 1
    Re "*APT-distros and CPAN-distros are conceptually the same thing*", No, not at all. They're not the same format, nor are they found in the same place. CPAN and APT are two completely separate systems with their own tools and distros. – ikegami Feb 03 '19 at 23:01
  • You shouldn't take the quote out of it's context. I clearly say `compared to Perl-packages` and APT- and CPAN-distros simply are conceptually(!) the same level above those packages, have pretty much the same design goals and purpose. I didn't made any of your other claims. – Thorsten Schöning Feb 08 '19 at 08:42
  • Recommendation for software applications are off-topic – ikegami Feb 08 '19 at 09:09