Difference between revisions of "User:Nathan M. Swan/DPM Proposal"

From D Wiki
Jump to: navigation, search
Line 1: Line 1:
 
WORK IN PROGRESS, IGNORE FOR NOW
 
WORK IN PROGRESS, IGNORE FOR NOW
  
This is a proposal for <code>'''dpm'''</code>, a '''D package manager'''. The eventual goal is to get this accepted into the standard distribution of D, so I don't want to start working on this until I get feedback from the community.
+
This is a proposal for <code>'''dpm'''</code>, a '''D package manager'''. The eventual goal is to get this accepted into the standard distribution of D, so I don't want to start working on any code until I get feedback from the community.
 +
 
 +
It has these conflicting principles:
 +
* ease of use. If the package manager is complicated, you might as well use <code>git</code> and <code>make</code> alone.
 +
* almost backwards compatibility. Platforms are only as good as the software that uses them; therefore, it should be really easy to <code>dpm</code>-ize packages.
 +
* Turing-complete customization. D projects are full of automatic C binders, documentation generators, and other useful stuff that the package manager shouldn't get in the way of.
  
 
== Scenarios ==
 
== Scenarios ==
I want it to cover the largest range of use cases as possible, so it should be extendable, but the basic use case should be easy. These are the three main UXs:
+
These are the main scenarios:
 
+
* A package user installing/managing packages they import/run
* Install a package
+
* A package creator creating/configuring packages they wrote
* Update a package
+
* A build script doing things with the source/binary/headers/docs/whatever.
* Create a package
 
 
 
Where will these "packages" be hosted? Sometime in the future, we would ideally have a central repository that hosts them like [http://www.rubygems.org RubyGems], but for now we will rely on <code>git</code> repositories from anywhere (like Github).
 
  
=== Installing packages ===
+
== Installing packages ==
 +
=== Overview ===
 
You enter the command:
 
You enter the command:
  
 
     $ dpm install <repository> [<version>]
 
     $ dpm install <repository> [<version>]
  
 +
And you can now either run the executable or import/link the library in other projects.
 +
 +
=== Details ===
 
The repository can be a "genuine" or "pseudo" package. A genuine package has been created with <code>'''dpm'''</code>, which means that it simply follows the instructions of the dpm configuration file.
 
The repository can be a "genuine" or "pseudo" package. A genuine package has been created with <code>'''dpm'''</code>, which means that it simply follows the instructions of the dpm configuration file.
  
Pseudo-packages are D code repositories that have yet to use dpm. Because of this, it will open a shell in the top directory of the installed repository, telling the user they will have to install it manually, encouraging them to checkout the READMEs and INSTALLs.
+
Pseudo-packages are D code repositories that have yet to use dpm. Because of this, it will open a shell in the top directory of the installed repository, telling the user they will have to install it manually, encouraging them to checkout the READMEs and INSTALLs it finds.
  
 
Genuine packages have a file <code>dpmconfig.d</code> at the top directory, which contains the code run to install the package. Technically, it can do what it wants, though it most likely will <code>import dpm;</code>, a separate D file compiled alongside it. That file will contain a series of useful functions for making it easy to program the config file, including ways to call common build methods like <code>make</code> or <code>rdmd</code>.
 
Genuine packages have a file <code>dpmconfig.d</code> at the top directory, which contains the code run to install the package. Technically, it can do what it wants, though it most likely will <code>import dpm;</code>, a separate D file compiled alongside it. That file will contain a series of useful functions for making it easy to program the config file, including ways to call common build methods like <code>make</code> or <code>rdmd</code>.
  
=== Updating packages ===
+
== Creating packages ==
Simply uninstalls/reinstalls the package.
+
=== Overview ===
 +
If this is an old project you're migrating over, you enter the command:
 +
 
 +
    $ dpm create template <build type>
 +
 
 +
If this is a new project:
 +
 
 +
    $ dpm create init <make | raw>
  
=== Creating packages ===
+
=== Detail ===
 
Migrating to <code>dpm</code> should be easy. Therefore, users with existing build options shouldn't have to redo it, just have <code>dpmconfig.d</code> call existing build code.
 
Migrating to <code>dpm</code> should be easy. Therefore, users with existing build options shouldn't have to redo it, just have <code>dpmconfig.d</code> call existing build code.
  
There will be a <code>dpm</code> command called <code>create</code>, which has a <code>--template</code> option which automatically generates these templates:
+
There will be a <code>dpm</code> command called <code>create template</code>, which automatically generates these configuration file templates:
 +
 
 +
    Template              Build Script
 +
   
 +
    make              -> make();
 +
    make-install      -> make("install");
 +
    make-make-install  -> make(); make("install");
 +
    rdmd-build        -> rdmd("build.d");
 +
    exec "code"        -> // executes "code"
 +
    empty              -> // does nothing
 +
 
 +
The <code>create init</code> command can happen two ways: a generated Makefile, which has the advantage of not requiring <code>dpm</code>; or a raw file, which builds right from the config file script (with all the lovely <code>dpm.d</code> APIs).
 +
 
 +
The <code>dpm.d</code> API would contain various process-calling convenience functions, directory-scanning functions, and so on. One important function is:
  
     make -> make
+
     void depend(string repo, string version="");
    make-install -> make install
 
    make-make-install -> make; make install
 
    rdmd-build -> rdmd build.d
 
    empty -> does nothing
 
  
There will be an <code>--exec</code> option which directly inserts code into the config file.
+
Which makes <code>dpm</code> install that package if it isn't there already.
  
 +
=== Examples ===
 
Example bare-bones config file:
 
Example bare-bones config file:
 
<syntaxhighlight lang="D">
 
<syntaxhighlight lang="D">
Line 46: Line 69:
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 +
== System Interface ==
 +
TODO
 +
 +
== Central Package Repositories ==
 +
TODO
  
 
=== Repository Resolution ===
 
=== Repository Resolution ===

Revision as of 11:03, 11 December 2012

WORK IN PROGRESS, IGNORE FOR NOW

This is a proposal for dpm, a D package manager. The eventual goal is to get this accepted into the standard distribution of D, so I don't want to start working on any code until I get feedback from the community.

It has these conflicting principles:

  • ease of use. If the package manager is complicated, you might as well use git and make alone.
  • almost backwards compatibility. Platforms are only as good as the software that uses them; therefore, it should be really easy to dpm-ize packages.
  • Turing-complete customization. D projects are full of automatic C binders, documentation generators, and other useful stuff that the package manager shouldn't get in the way of.

Scenarios

These are the main scenarios:

  • A package user installing/managing packages they import/run
  • A package creator creating/configuring packages they wrote
  • A build script doing things with the source/binary/headers/docs/whatever.

Installing packages

Overview

You enter the command:

   $ dpm install <repository> [<version>]

And you can now either run the executable or import/link the library in other projects.

Details

The repository can be a "genuine" or "pseudo" package. A genuine package has been created with dpm, which means that it simply follows the instructions of the dpm configuration file.

Pseudo-packages are D code repositories that have yet to use dpm. Because of this, it will open a shell in the top directory of the installed repository, telling the user they will have to install it manually, encouraging them to checkout the READMEs and INSTALLs it finds.

Genuine packages have a file dpmconfig.d at the top directory, which contains the code run to install the package. Technically, it can do what it wants, though it most likely will import dpm;, a separate D file compiled alongside it. That file will contain a series of useful functions for making it easy to program the config file, including ways to call common build methods like make or rdmd.

Creating packages

Overview

If this is an old project you're migrating over, you enter the command:

   $ dpm create template <build type>

If this is a new project:

   $ dpm create init <make | raw>

Detail

Migrating to dpm should be easy. Therefore, users with existing build options shouldn't have to redo it, just have dpmconfig.d call existing build code.

There will be a dpm command called create template, which automatically generates these configuration file templates:

   Template              Build Script
   
   make               -> make();
   make-install       -> make("install");
   make-make-install  -> make(); make("install");
   rdmd-build         -> rdmd("build.d");
   exec "code"        -> // executes "code"
   empty              -> // does nothing

The create init command can happen two ways: a generated Makefile, which has the advantage of not requiring dpm; or a raw file, which builds right from the config file script (with all the lovely dpm.d APIs).

The dpm.d API would contain various process-calling convenience functions, directory-scanning functions, and so on. One important function is:

   void depend(string repo, string version="");

Which makes dpm install that package if it isn't there already.

Examples

Example bare-bones config file:

import dpm;
void dpm_main() {
    make();
}

System Interface

TODO

Central Package Repositories

TODO

Repository Resolution

The repository can be either a URL to an exact git repository, or a simple package name.

If it's an exact git repository, the version is assumed to be a tag, with a --branch alternative.

A simple package name means it must be downloaded from a central package repository (CPR). It goes through all installed CPRs and makes this HTTP request:

   <cpr, e.g. http://cpr.example.com/cpr_api/>?name=<repository_name>[version=<version>]

The CPR gives the URL of a git repository and --branch/tag as a plain text response (code 200), or it gives a custom error message (code 404). It then treats that as an ordinary git repository.

When a standard CPR is created, it will be builtin as the default CPR. Users can dpm add-cpr <url> or <cod>dpm rm-cpr <url>, as they wish, modifying a config file somewhere.