Cross package maker. DEB/RPM generation or conversion. Derived from jordansissel/fpm.

⌈⌋ branch:  cross package maker


Check-in [40a7170c71]

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
SHA1:40a7170c71195eaabe91bfc68049ba17df5a950b
Date: 2015-01-21 21:55:13
User: mario
Comment:Fix default attributes filtering. Rework map_phar() classmap building to avoid chdir().
Tags And Properties
  • branch=trunk inherited from [5980cef12a]
  • sym-trunk inherited from [5980cef12a]
Context
2015-01-21
21:58
[f28593b104] Reinstate RPM support. Fix lesser than dependency versions. Consolidate package_typ() for prior use (::filter abbrv). Keep @in_bundle again. Use RPM "php-composer(vnd/pkg)" dependencies now for :rpm, together with a self-provides "php-composer(@in_bundle) = @version". Alternatives for literal package names not supported by RPMbuild (4.11). (user: mario, tags: trunk)
21:55
[40a7170c71] Fix default attributes filtering. Rework map_phar() classmap building to avoid chdir(). (user: mario, tags: trunk)
13:10
[5c62338e56] Implement classmap builder directly in -t phar plugin. (Original implementation and tokenizer alternative in Canonic_Autoloader.) (user: mario, tags: trunk)
Changes

Changes to lib/fpm/package/phar.rb.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
..
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88

89
90
91
92
93
94
95
96
...
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128

# api: fpm
# title: PHP Phar target
# description: Chains to PHP for creating a .phar (native/tar/zip) archive
# type: package
# category: target
# version: 0.2
# state: very alpha
# license: MITL
# author: mario#include-once:org
# 
# This packaging target generates simple PHP Phar assemblies. With its
# default stub assuming `__init__.php` for CLI applications, and `index.php`
# as web router. A custom --phar-stub can be set of course.
................................................................................
      :srcdir => staging_path,
      #:nocase => attributes[:phar_nocase],
      :stub   => attributes[:phar_stub_given?] ? staging_path + "/" + attributes[:phar_stub] : "",
      :sign   => attributes[:phar_sign],
    }
    
    # Retain package meta information, either from fpm attributes, or collected :attr hash (src module, formerly :meta)
    p[:meta] = attrs.merge({
      "id" => @name,
      "version" => @version.to_s,
      "epoch" => @epoch.to_s,
      "iteration" => @iteration.to_s,
      "architecture" => @architecture,
      "category" => @category == "none" ? nil : @category,
      "author" => @maintainer,
      "url" => @url,
      "license" => @license,

    }).delete_if{ |k,v| v.nil? || v==""}
    
    # Match format specifier/extension onto type/settings
    fmt = (attributes[:phar_format] + output_path).downcase
    fmt, enc = fmt.match(/zip|phaz|tar|t[gb]z|pz/).to_s||"phar", fmt.match(/gz|bz2/).to_s
    map_keys = [:stdext, :format, :filegz, :extout, :hullgz]
    map = {
        # fmt,  enc          extension   format        per-file-gz   extns ← archive-compr
................................................................................
    }
    opt = map[[fmt,enc]] || map[ext2map[fmt]] || map[["phar", ""]]
    p.merge! Hash[map_keys.zip opt]

    # Have PHP generate the package
    p[:tmpf] = ::Dir::Tmpname.create(['_\$fpm_phar_', p[:stdext]]) {}
    phargen = template_dir + "/phar.php"
    safesystem("php", "-dphar.readonly=0", "-derror_reporing=~0", "-ddisplay_errors=1", phargen, JSON.generate(p))

    #-- but might end up with suffix, for whole-archive ->compress()ion
    FileUtils.mv(p[:tmpf] + p[:extout], output_path)
    File.unlink(p[:tmpf]) if File.exists?(p[:tmpf])
  end

end # class FPM::Package::Phar






|







 







|





|



>
|







 







|







1
2
3
4
5
6
7
8
9
10
11
12
13
14
..
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
...
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129

# api: fpm
# title: PHP Phar target
# description: Chains to PHP for creating a .phar (native/tar/zip) archive
# type: package
# category: target
# version: 0.3
# state: very alpha
# license: MITL
# author: mario#include-once:org
# 
# This packaging target generates simple PHP Phar assemblies. With its
# default stub assuming `__init__.php` for CLI applications, and `index.php`
# as web router. A custom --phar-stub can be set of course.
................................................................................
      :srcdir => staging_path,
      #:nocase => attributes[:phar_nocase],
      :stub   => attributes[:phar_stub_given?] ? staging_path + "/" + attributes[:phar_stub] : "",
      :sign   => attributes[:phar_sign],
    }
    
    # Retain package meta information, either from fpm attributes, or collected :attr hash (src module, formerly :meta)
    defaults = {
      "id" => @name,
      "version" => @version.to_s,
      "epoch" => @epoch.to_s,
      "iteration" => @iteration.to_s,
      "architecture" => @architecture,
      "category" => @category,
      "author" => @maintainer,
      "url" => @url,
      "license" => @license,
    }.delete_if{ |k,v| ["", nil, "default", "http://example.com/no-uri-given"].include? v }
    p[:meta] = attrs.merge(defaults).delete_if{ |k,v| v.empty? }
    
    # Match format specifier/extension onto type/settings
    fmt = (attributes[:phar_format] + output_path).downcase
    fmt, enc = fmt.match(/zip|phaz|tar|t[gb]z|pz/).to_s||"phar", fmt.match(/gz|bz2/).to_s
    map_keys = [:stdext, :format, :filegz, :extout, :hullgz]
    map = {
        # fmt,  enc          extension   format        per-file-gz   extns ← archive-compr
................................................................................
    }
    opt = map[[fmt,enc]] || map[ext2map[fmt]] || map[["phar", ""]]
    p.merge! Hash[map_keys.zip opt]

    # Have PHP generate the package
    p[:tmpf] = ::Dir::Tmpname.create(['_\$fpm_phar_', p[:stdext]]) {}
    phargen = template_dir + "/phar.php"
    safesystem("php", "-dphar.readonly=0", "-derror_reporting=~0", "-ddisplay_errors=1", phargen, JSON.generate(p))

    #-- but might end up with suffix, for whole-archive ->compress()ion
    FileUtils.mv(p[:tmpf] + p[:extout], output_path)
    File.unlink(p[:tmpf]) if File.exists?(p[:tmpf])
  end

end # class FPM::Package::Phar

Changes to templates/phar.php.

1
2
3
4
5

6
7
8
9
10
11
12
..
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
..
78
79
80
81
82
83
84
85
86
87
88
89
90
91


92
93


94
95









96
97
98
99

100
101
102




103
104
105
106
107
108
109
<?php
/**
 * api: php
 * title: Phar generation
 * description: PHP script template to get Phar assembled

 *
 * Used as template php script for -t phar building.
 * Extracts passed Ruby variables as PHP strings, so some
 * need constant(), strlen() or boolean interpretation.
 *
 */

................................................................................
 * Phar meta data
 *  · Use injected JSON blob.
 *  · Contains at least fpm package infos,
 *  · May contain additional fields - attrs{} from `-s src` or `composer` module
 *  · Also build and include a class `map` structure.
 */
if ($meta) {
   map_phar($p, $meta, $srcdir);
   $p->setMetadata($meta);
}


/**
 * Complete packaging
 *  · Set per-file compression
................................................................................
}




/**
 * Traverse Phar entries and augment Phar meta class/function/const `map`,
 * which lists identifiers as: ns\vnd\name => internal-filename.php simply.
 *
 * Needs to manually reread the directory and files, because freshly-built
 * Phars` RecursiveDirectoryIterator + offsetGet() won't function.
 *
 */
function map_phar($p, &$meta, $dir) {


   $meta["map"] = array("class"=>array(), "function"=>array(), "const"=>array());
   chdir($dir);


   foreach (new RegexIterator(new RecursiveIteratorIterator(new RecursiveDirectoryIterator(".")), "~^(?!.*tests?/).+\.php$~") as $fn) {
      $fn = substr($fn, 2);









      $def = new RegexPhpIdentifierDeclarations(file_get_contents($fn));
      foreach ($def->identifiers() as $type=>$list) {
         foreach ($list as $id) {
            $meta["map"][$type][strtolower($id)] = $fn;

         }
      }
   }




}



/**
 * @source  shared.phar
 * @license Public Domain





>







 







|







 







|


|


|
>
>
|
<
>
>
|
<
>
>
>
>
>
>
>
>
>


<
<
>
|
|
|
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
13
..
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
..
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95

96
97
98

99
100
101
102
103
104
105
106
107
108
109


110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
<?php
/**
 * api: php
 * title: Phar generation
 * description: PHP script template to get Phar assembled
 * version: 0.3
 *
 * Used as template php script for -t phar building.
 * Extracts passed Ruby variables as PHP strings, so some
 * need constant(), strlen() or boolean interpretation.
 *
 */

................................................................................
 * Phar meta data
 *  · Use injected JSON blob.
 *  · Contains at least fpm package infos,
 *  · May contain additional fields - attrs{} from `-s src` or `composer` module
 *  · Also build and include a class `map` structure.
 */
if ($meta) {
   $meta["map"] = map_phar($p, $srcdir);
   $p->setMetadata($meta);
}


/**
 * Complete packaging
 *  · Set per-file compression
................................................................................
}




/**
 * Traverse Phar entries and augment Phar meta class/function/const `map`,
 * which lists identifiers as "vnd\pkg\class" => "internal-filename.php".
 *
 * Needs to manually reread the directory and files, because freshly-built
 * Phars` RecursiveDirectoryIterator + offsetGet() return zilch.
 *
 */
function map_phar($p, $dir) {

   // prepare empty map
   $map = array("class"=>array(), "function"=>array(), "const"=>array());

   
   // switch to staging dir, but keep old path as reference
   $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($dir));

   $it = new RegexIterator($it, "~^(?!.*tests?/).+\.php$~");
   
   // only read .php files
   foreach ($it as $fn) {

      // cut off $dir prefix      
      $int_fn = ltrim(substr($fn, strlen($dir)), "/");

      // collect identifiers
      $def = new RegexPhpIdentifierDeclarations(file_get_contents($fn));
      foreach ($def->identifiers() as $type=>$list) {


         $map[$type] = array_merge($map[$type], array_fill_keys($list, $int_fn));
      }
   }

   // prepare for PHP compliant case-insensitive lookups
   $map["class"] = array_change_key_case($map["class"]);
   $map["function"] = array_change_key_case($map["function"]);
   return $map;
}



/**
 * @source  shared.phar
 * @license Public Domain