1Config::Model(3)      User Contributed Perl Documentation     Config::Model(3)
2
3
4

NAME

6       Config::Model - Create tools to validate, migrate and edit
7       configuration files
8

VERSION

10       version 2.136
11

SYNOPSIS

13   Perl program to use an existing model
14        use Config::Model qw(cme);
15        # load, modify and save popcon configuration file
16        cme('popcon')->modify("PARTICIPATE=yes");
17
18   Command line to use an existing model
19        # with App::Cme
20        cme modify popcon 'PARTICIPATE=yes'
21
22   Perl program with a custom model
23        use Config::Model;
24
25        # create new Model object
26        my $model = Config::Model->new() ; # Config::Model object
27
28        # create config model. A more complex model should be stored in a
29        # file in lib/Config/Model/models. Then, run cme as explained below
30        $model ->create_config_class (
31          name => "MiniModel",
32          element => [ [qw/foo bar baz/ ] => { type => 'leaf', value_type => 'uniline' }, ],
33          rw_config => { backend => 'IniFile', auto_create => 1,
34                         config_dir => '.', file => 'mini.ini',
35                       }
36        ) ;
37
38        # create instance (Config::Model::Instance object)
39        my $instance = $model->instance (root_class_name => 'MiniModel');
40
41        # get configuration tree root
42        my $cfg_root = $instance -> config_root ; # C::M:Node object
43
44        # load some dummy data
45        $cfg_root -> load("bar=BARV foo=FOOV baz=BAZV") ;
46
47        # write new ini file
48        $instance -> write_back;
49
50        # now look for new mini.ini file un current directory
51
52   Create a new model file and use it
53        $ mkdir -p lib/Config/Model/models/
54        $ echo "[ { name => 'MiniModel', \
55                    element => [ [qw/foo bar baz/ ] => { type => 'leaf', value_type => 'uniline' }, ], \
56                    rw_config => { backend => 'IniFile', auto_create => 1, \
57                                   config_dir => '.', file => 'mini.ini', \
58                                 } \
59                  } \
60                ] ; " > lib/Config/Model/models/MiniModel.pl
61        # require App::Cme
62        $ cme modify -try MiniModel -dev bar=BARV foo=FOOV baz=BAZV
63        $ cat mini.ini
64
65       Note that model creation is easier running "cme meta edit" with
66       App::Cme and Config::Model::Itself.
67

DESCRIPTION

69       Config::Model enables a project developer to provide an interactive
70       configuration editor (graphical, curses based or plain terminal) to
71       users.
72
73       To provide these tools, Config::Model needs:
74
75       ·   A description of the structure and constraints of the project's
76           configuration (fear not, a GUI is available with App::Cme)
77
78       ·   A module to read and write configuration data (aka a backend
79           class).
80
81       With the elements above, Config::Model generates interactive
82       configuration editors (with integrated help and data validation).
83       These editors can be graphical (with Config::Model::TkUI), curses based
84       (with Config::Model::CursesUI) or based on ReadLine.
85
86       Smaller models targeted for configuration upgrades can also be created:
87
88       ·   only upgrade and migration specifications are required
89
90       ·   unknown parameters can be accepted
91
92       A command line is provided to perform configuration upgrade with a
93       single command.
94
95   How does this work ?
96       Using this project, a typical configuration editor/validator/upgrader
97       is made of 3 parts :
98
99         GUI <--------> |---------------|
100         CursesUI <---> | |---------|   |
101                        | | Model   |   |
102         ShellUI <----> | |---------|   |<-----read-backend------- |-------------|
103                        |               |----write-backend-------> | config file |
104         FuseUI <-----> | Config::Model |                          |-------------|
105                        |---------------|
106
107       1.  A reader and writer that parse the configuration file and transform
108           its data into a tree representation within Config::Model. The
109           values contained in this configuration tree can be written back in
110           the configuration file(s).
111
112       2.  A validation engine which is in charge of validating the content
113           and structure of configuration stored in the configuration tree.
114           This validation engine follows the structure and constraint
115           declared in a configuration model. This model is a kind of schema
116           for the configuration tree.
117
118       3.  A user interface to modify the content of the configuration tree. A
119           modification is validated immediately by the validation engine.
120
121       The important part is the configuration model used by the validation
122       engine. This model can be created or modified with a graphical editor
123       (Config::Model::Iself).
124

Question you may ask yourself

126   Don't we already have some configuration validation tools ?
127       You're probably thinking of tools like webmin. Yes, these tools exist
128       and work fine, but they have their set of drawbacks.
129
130       Usually, the validation of configuration data is done with a script
131       which performs semantic validation and often ends up being quite
132       complex (e.g. 2500 lines for Debian's xserver-xorg.config script which
133       handles "xorg.conf" file).
134
135       In most cases, the configuration model is expressed in instructions
136       (whatever programming language is used) and interspersed with a lot of
137       processing to handle the actual configuration data.
138
139   What's the advantage of this project ?
140       Config::Model projects provide a way to get a validation engine where
141       the configuration model is completely separated from the actual
142       processing instructions.
143
144       A configuration model can be created and modified with the graphical
145       interface provide by Config::Model::Itself. The model is saved in a
146       declarative form (currently, a Perl data structure). Such a model is
147       easier to maintain than a lot of code.
148
149       The model specifies:
150
151       ·   The structure of the configuration data (which can be queried by
152           generic user interfaces)
153
154       ·   The properties of each element (boundaries check, integer or
155           string, enum like type, default value ...)
156
157       ·   The targeted audience (beginner, advanced, master)
158
159       ·   The on-line help
160
161       So, in the end:
162
163       ·   Maintenance and evolution of the configuration content is easier
164
165       ·   User sees a *common* interface for *all* programs using this
166           project.
167
168       ·   Upgrade of configuration data is easier and sanity check is
169           performed during the upgrade.
170
171       ·   Audit of configuration is possible to check what was modified by
172           the user compared to default values
173
174   What about the user interface ?
175       Config::Model interface can be:
176
177       ·   a shell-like interface (plain or based on Term::ReadLine).
178
179       ·   Graphical with Config::Model::TkUI (Perl/Tk interface).
180
181       ·   based on curses with Config::Model::CursesUI. This interface can be
182           handy if your X server is down.
183
184       ·   Through a virtual file system where every configuration parameter
185           is mapped to a file.  (Linux only)
186
187       All these interfaces are generated from the configuration model.
188
189       And configuration model can be created or modified with a graphical
190       user interface (with "cme meta edit" once Config::Model::Itself is
191       installed)
192
193   What about configuration data storage ?
194       Since the syntax of configuration files vary wildly form one
195       application to another, people who want to use this framework may have
196       to provide a dedicated parser/writer.
197
198       To help with this task, this project provides writer/parsers for common
199       format: INI style file and perl file. With the additional
200       Config::Model::Backend::Augeas, Augeas library can be used to read and
201       write some configuration files. See http://augeas.net for more details.
202
203   Is there an example of a configuration model ?
204       The "example" directory contains a configuration model example for
205       "/etc/fstab" file. This example includes a small program that use this
206       model to show some ways to extract configuration information.
207

Mailing lists

209       For more question, please send a mail to:
210
211        config-model-users at lists.sourceforge.net
212

Suggested reads to start

214   Beginners
215       ·   Config::Model::Manual::ModelCreationIntroduction
216
217       ·   Config::Model::Cookbook::CreateModelFromDoc
218
219   Advanced
220       ·   Config::Model::models::Itself::Class: This doc and its siblings
221           describes all parameters available to create a model. These are the
222           parameters available in the GUI launched by "cme meta edit"
223           command.
224
225       ·   Config::Model::Manual::ModelCreationAdvanced
226
227   Masters
228       use the source, Luke
229

STOP

231       The documentation below is quite detailed and is more a reference doc
232       regarding "Config::Model" class.
233
234       For an introduction to model creation, please check:
235       Config::Model::Manual::ModelCreationIntroduction
236

Storage backend, configuration reader and writer

238       See Config::Model::BackendMgr for details
239

Validation engine

241       "Config::Model" provides a way to get a validation engine from a set of
242       rules. This set of rules is called the configuration model.
243

User interface

245       The user interface uses some parts of the API to set and get
246       configuration values. More importantly, a generic user interface needs
247       to analyze the configuration model to be able to generate at run-time
248       relevant configuration screens.
249
250       A command line interface is provided in this module. Curses and Tk
251       interfaces are provided by Config::Model::CursesUI and
252       Config::Model::TkUI.
253

Constructor

255        my $model = Config::Model -> new ;
256
257       creates an object to host your model.
258
259   Constructor parameters
260       log_level
261           Specify minimal log level. Default is "WARN". Can be "INFO",
262           "DEBUG" or "TRACE" to get more logs. Can also be "ERROR" to get
263           less traces.
264
265           This parameter is used to override the log level specified in log
266           configuration file.
267

Configuration Model

269       To validate a configuration tree, we must create a configuration model
270       that defines all the properties of the validation engine you want to
271       create.
272
273       The configuration model is expressed in a declarative form (i.e. a Perl
274       data structure which should be easier to maintain than a lot of code)
275
276       Each configuration class may contain a set of:
277
278       ·   node elements that refer to another configuration class
279
280       ·   value elements that contain actual configuration data
281
282       ·   list or hash elements that also contain several node or value
283           elements
284
285       The structure of your configuration tree is shaped by the a set of
286       configuration classes that are used in node elements,
287
288       The structure of the configuration data must be based on a tree
289       structure. This structure has several advantages:
290
291       ·   Unique path to get to a node or a leaf.
292
293       ·   Simpler exploration and query
294
295       ·   Simple hierarchy. Deletion of configuration items is simpler to
296           grasp: when you cut a branch, all the leaves attaches to that
297           branch go down.
298
299       But using a tree has also some drawbacks:
300
301       ·   A complex configuration cannot be mapped on a simple tree.  Some
302           more relation between nodes and leaves must be added.
303
304       ·   A configuration may actually be structured as a graph instead as a
305           tree (for instance, any configuration that maps a service to a
306           resource). The graph relation must be decomposed in a tree with
307           special reference relations that complete the tree to form a graph.
308           See "Value Reference" in Config::Model::Value
309
310       Note: a configuration tree is a tree of objects. The model is declared
311       with classes. The classes themselves have relations that closely match
312       the relation of the object of the configuration tree. But the class
313       need not to be declared in a tree structure (always better to reuse
314       classes). But they must be declared as a DAG (directed acyclic graph).
315       See also Directed acyclic graph on Wikipedia
316       <http://en.wikipedia.org/wiki/Directed_acyclic_graph">More on DAGs>
317
318       Each configuration class declaration specifies:
319
320       ·   The "name" of the class (mandatory)
321
322       ·   A "class_description" used in user interfaces (optional)
323
324       ·   Optional include specification to avoid duplicate declaration of
325           elements.
326
327       ·   The class elements
328
329       Each element specifies:
330
331       ·   Most importantly, the type of the element (mostly "leaf", or
332           "node")
333
334       ·   The properties of each element (boundaries, check, integer or
335           string, enum like type ...)
336
337       ·   The default values of parameters (if any)
338
339       ·   Whether the parameter is mandatory
340
341       ·   Targeted audience (beginner, advance, master), i.e. the level of
342           expertise required to tinker a parameter (to hide expert parameters
343           from newbie eyes)
344
345       ·   On-line help (for each parameter or value of parameter)
346
347       See Config::Model::Node for details on how to declare a configuration
348       class.
349
350       Example:
351
352        $ cat lib/Config/Model/models/Xorg.pl
353        [
354          {
355            name => 'Xorg',
356            class_description => 'Top level Xorg configuration.',
357            include => [ 'Xorg::ConfigDir'],
358            element => [
359                        Files => {
360                                  type => 'node',
361                                  description => 'File pathnames',
362                                  config_class_name => 'Xorg::Files'
363                                 },
364                        # snip
365                       ]
366          },
367          {
368            name => 'Xorg::DRI',
369            element => [
370                        Mode => {
371                                 type => 'leaf',
372                                 value_type => 'uniline',
373                                 description => 'DRI mode, usually set to 0666'
374                                }
375                       ]
376          }
377        ];
378

Configuration instance methods

380       A configuration instance is created from a model and is the starting
381       point of a configuration tree.
382
383   instance
384       An instance must be created with a model name (using the root class
385       name) or an application name (as shown by "cme "list"" command).
386
387       For example:
388
389        my $model = Config::Model->new() ;
390        $model->instance( application => 'approx');
391
392       Or:
393
394        my $model = Config::Model->new() ;
395        # note that the model class is slightly different compared to
396        # application name
397        $model->instance( root_class_name => 'Approx');
398
399       A custom configuration class can also be used with "root_class_name"
400       parameter:
401
402        my $model = Config::Model->new() ;
403        # create_config_class is described below
404        $model ->create_config_class (
405          name => "SomeRootClass",
406          element => [ ...  ]
407        ) ;
408
409        # instance name is 'default'
410        my $inst = $model->instance (root_class_name => 'SomeRootClass');
411
412       You can create several separated instances from a model using "name"
413       option:
414
415        # instance name is 'default'
416        my $inst = $model->instance (
417          root_class_name => 'SomeRootClass',
418          name            => 'test1'
419        );
420
421       Usually, model files are loaded automatically using a path matching
422       "root_class_name" (e.g. configuration class "Foo::Bar" is stored in
423       "Foo/Bar.pl". You can choose to specify the file containing the model
424       with "model_file" parameter. This is mostly useful for tests.
425
426       The "instance" method can also retrieve an instance that has already
427       been created:
428
429        my $inst = $model->instance( name => 'test1' );
430
431   get_instance
432       Retrieve an existing instance using its name.
433
434        my $inst = $model->get_instance('test1' );
435
436   has_instance
437       Check if an instance name already exists
438
439         my $maybe = $model->has_instance('test1');
440
441   cme
442       This method is syntactic sugar for short program. It creates a new
443       "Config::Model" object and returns a new instance. See "instance" for
444       the parameters.
445

Configuration class

447       A configuration class is made of series of elements which are detailed
448       in Config::Model::Node.
449
450       Whatever its type (node, leaf,... ), each element of a node has several
451       other properties:
452
453       level
454           Level is "important", "normal" or "hidden".
455
456           The level is used to set how configuration data is presented to the
457           user in browsing mode. "Important" elements are shown to the user
458           no matter what. "hidden" elements are well, hidden. Their purpose
459           is explained with the warp notion.
460
461       status
462           Status is "obsolete", "deprecated" or "standard" (default).
463
464           Using a deprecated element raises a warning. Using an obsolete
465           element raises an exception.
466
467       description
468           Description of the element. This description is used while
469           generating user interfaces.
470
471       summary
472           Summary of the element. This description is used while generating a
473           user interfaces and may be used in comments when writing the
474           configuration file.
475
476       class_description
477           Description of the configuration class. This description is used
478           while generating user interfaces.
479
480       generated_by
481           Mention with a descriptive string if this class was generated by a
482           program.  This parameter is currently reserved for
483           Config::Model::Itself model editor.
484
485       include
486           Include element description from another class.
487
488             include => 'AnotherClass' ,
489
490           or
491
492             include => [qw/ClassOne ClassTwo/]
493
494           In a configuration class, the order of the element is important.
495           For instance if "foo" is warped by "bar", you must declare "bar"
496           element before "foo".
497
498           When including another class, you may wish to insert the included
499           elements after a specific element of your including class:
500
501             # say AnotherClass contains element xyz
502             include => 'AnotherClass' ,
503             include_after => "foo" ,
504             element => [ bar => ... , foo => ... , baz => ... ]
505
506           Now the element of your class are:
507
508             ( bar , foo , xyz , baz )
509
510           Note that include may not clobber an existing element.
511
512       include_backend
513           Include read/write specification from another class.
514
515             include_backend => 'AnotherClass' ,
516
517           or
518
519             include_backend => [qw/ClassOne ClassTwo/]
520
521       Note that include may not clobber an existing read/write specification.
522
523   create_config_class
524       This method creates configuration classes. The parameters are described
525       above and are forwarded to Config::Model::Node constructor. See
526       "Configuration class declaration" in Config::Model::Node for more
527       details on configuration class parameters.
528
529       Example:
530
531         my $model = Config::Model -> new ;
532
533         $model->create_config_class
534         (
535          config_class_name => 'SomeRootClass',
536          description       => [ X => 'X-ray' ],
537          level             => [ 'tree_macro' => 'important' ] ,
538          class_description => "SomeRootClass description",
539          element           => [ ... ]
540         ) ;
541
542       For convenience, "level" and "description" parameters can also be
543       declared within the element declaration:
544
545         $model->create_config_class
546         (
547          config_class_name => 'SomeRootClass',
548          class_description => "SomeRootClass description",
549          'element'
550          => [
551               tree_macro => { level => 'important'},
552               X          => { description => 'X-ray', } ,
553             ]
554         ) ;
555

Load predeclared model

557       You can also load predeclared model.
558
559   load( <model_name> )
560       This method opens the model directory and execute a ".pl" file
561       containing the model declaration,
562
563       This perl file must return an array ref to declare models. E.g.:
564
565        [
566         [
567          name => 'Class_1',
568          element => [ ... ]
569         ],
570         [
571          name => 'Class_2',
572          element => [ ... ]
573         ]
574        ];
575
576       do not put "1;" at the end or "load" will not work
577
578       When a model name contain a "::" (e.g "Foo::Bar"), "load" looks for a
579       file named "Foo/Bar.pl".
580
581       This method also searches in "Foo/Bar.d" directory for additional model
582       information.  Model snippet found there are loaded with
583       augment_config_class.
584
585       Returns a list containing the names of the loaded classes. For
586       instance, if "Foo/Bar.pl" contains a model for "Foo::Bar" and
587       "Foo::Bar2", "load" returns "( 'Foo::Bar' , 'Foo::Bar2' )".
588
589   augment_config_class (name => '...', class_data )
590       Enhance the feature of a configuration class. This method uses the same
591       parameters as create_config_class. See "Model Plugin" in
592       Config::Model::Manual::ModelCreationAdvanced for more details on
593       creating model plugins.
594

Model query

596   model
597       Returns a hash containing the model declaration of the passed model
598       name. Do not modify the content of the returned data structure.
599
600        my $cloned = $model->model('Foo');
601
602   get_model_clone
603       Like "model", returns a hash containing the model declaration of the
604       passed model name, this time in a deep clone of the data structure.
605
606        my $cloned = $model->get_model_clone('Foo');
607
608   generate_doc ( top_class_name , directory , [ \%done ] )
609       Generate POD document for configuration class top_class_name and all
610       classes used by top_class_name, and write them in specified directory.
611
612       "\%done" is an optional reference to a hash used to avoid writing twice
613       the same documentation when this method is called several times.
614
615   get_element_model( config_class_name , element)
616       Return a hash containing the model declaration for the specified class
617       and element.
618
619   get_element_name( class => Foo )
620       Get all names of the elements of class "Foo".
621
622   get_element_property
623       Returns the property of an element from the model.
624
625       Parameters are:
626
627       class
628       element
629       property
630
631   list_class_element
632       Returns a string listing all the class and elements. Useful for
633       debugging your configuration model.
634

Error handling

636       Errors are handled with an exception mechanism.
637
638       When a strongly typed Value object gets an authorized value, it raises
639       an exception. If this exception is not caught, the programs exits.
640
641       See Config::Model::Exception for details on the various exception
642       classes provided with "Config::Model".
643

Logging

645       See "Logging" in cme
646
647   initialize_log4perl
648       This method can be called to load Log::Log4perl configuration from
649       "~/.log4config-model", or from "/etc/log4config-model.conf" files or
650       from default configuration <https://github.com/dod38fr/config-
651       model/blob/master/lib/Config/Model/log4perl.conf>.
652
653       Accepts "verbose" parameter with a list of log classes that are added
654       to the log4perl configuration read above.
655
656       For instance, with "verbose => 'Loader'", log4perl is initialised with
657
658        log4perl.logger.Verbose.Loader = INFO, PlainMsgOnScreen
659
660       Likewise, with "verbose => [ 'Loader', 'Foo' ]", log4perl is
661       initialised with:
662
663        log4perl.logger.Verbose.Loader = INFO, PlainMsgOnScreen
664        log4perl.logger.Verbose.Foo    = INFO, PlainMsgOnScreen
665
666       Currently, this module supports only "Loader" as verbose parameters.
667

BUGS

669       Given Murphy's law, the author is fairly confident that you will find
670       bugs or miss some features. Please report them to
671       https://github.com/dod38fr/config-model/issues The author will be
672       notified, and then you'll automatically be notified of progress on your
673       bug.
674

FEEDBACK

676       Feedback from users are highly desired. If you find this module useful,
677       please share your use cases, success stories with the author or with
678       the config-model- users mailing list.
679

PROJECT FOUNDER

681       Dominique Dumont, "ddumont@cpan.org"
682

CREDITS

684       In alphabetical order:
685
686         Harley Pig
687
688         Ilya Arosov
689
690         Jose Luis Perez Diez
691
692         Krzysztof Tyszecki
693
694         Mathieu Arnold
695
696         Mohammad S Anwar
697

LICENSE

699           Copyright (c) 2005-2016 Dominique Dumont.
700
701           Config-Model is free software; you can redistribute it and/or
702           modify it under the terms of the GNU Lesser General Public License as
703           published by the Free Software Foundation; either version 2.1 of
704           the License, or (at your option) any later version.
705
706           Config-Model is distributed in the hope that it will be useful,
707           but WITHOUT ANY WARRANTY; without even the implied warranty of
708           MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
709           Lesser Public License for more details.
710
711           You should have received a copy of the GNU Lesser General Public License
712           along with Config-Model; if not, write to the Free Software
713           Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
714           02110-1301 USA
715

SEE ALSO

717       Config::Model::Instance,
718
719       <https://github.com/dod38fr/config-model/wiki>
720
721       <https://github.com/dod38fr/config-model/wiki/Creating-models>
722
723   Model elements
724       The arrow shows inheritance between classes
725
726       ·   Config::Model::Node <- Config::Model::AnyThing
727
728       ·   Config::Model::HashId <- Config::Model::AnyId <-
729           Config::Model::AnyThing
730
731       ·   Config::Model::ListId <- Config::Model::AnyId <-
732           Config::Model::AnyThing
733
734       ·   Config::Model::Value <- Config::Model::AnyThing
735
736       ·   Config::Model::CheckList <- Config::Model::AnyThing
737
738       ·   Config::Model::WarpedNode <- Config::Model::AnyThing
739
740   command line
741       cme.
742
743   Read and write backends
744       ·   Config::Model::Backend::Fstab <- Config::Model::Backend::Any
745
746       ·   Config::Model::Backend::IniFile <- Config::Model::Backend::Any
747
748       ·   Config::Model::Backend::PlainFile <- Config::Model::Backend::Any
749
750       ·   Config::Model::Backend::ShellVar <- Config::Model::Backend::Any
751
752   Model utilities
753       ·   Config::Model::Annotation
754
755       ·   Config::Model::BackendMgr: Used by "Config::Model::Node" object
756
757       ·   Config::Model::Describe
758
759       ·   Config::Model::Dumper
760
761       ·   Config::Model::DumpAsData
762
763       ·   Config::Model::IdElementReference
764
765       ·   Config::Model::Iterator
766
767       ·   Config::Model::Loader
768
769       ·   Config::Model::ObjTreeScanner
770
771       ·   Config::Model::Report
772
773       ·   Config::Model::Searcher: Search element in configuration model.
774
775       ·   Config::Model::SimpleUI
776
777       ·   Config::Model::TreeSearcher: Search string or regexp in
778           configuration tree.
779
780       ·   Config::Model::TermUI
781
782       ·   Config::Model::Iterator
783
784       ·   Config::Model::ValueComputer
785
786       ·   Config::Model::Warper
787
788   Test framework
789       ·   Config::Model::Tester
790

AUTHOR

792       Dominique Dumont
793
795       This software is Copyright (c) 2005-2019 by Dominique Dumont.
796
797       This is free software, licensed under:
798
799         The GNU Lesser General Public License, Version 2.1, February 1999
800

SUPPORT

802   Websites
803       The following websites have more information about this module, and may
804       be of help to you. As always, in addition to those websites please use
805       your favorite search engine to discover more resources.
806
807       ·   Search CPAN
808
809           The default CPAN search engine, useful to view POD in HTML format.
810
811           <http://search.cpan.org/dist/Config-Model>
812
813       ·   AnnoCPAN
814
815           The AnnoCPAN is a website that allows community annotations of Perl
816           module documentation.
817
818           <http://annocpan.org/dist/Config-Model>
819
820       ·   CPAN Ratings
821
822           The CPAN Ratings is a website that allows community ratings and
823           reviews of Perl modules.
824
825           <http://cpanratings.perl.org/d/Config-Model>
826
827       ·   CPANTS
828
829           The CPANTS is a website that analyzes the Kwalitee ( code metrics )
830           of a distribution.
831
832           <http://cpants.cpanauthors.org/dist/Config-Model>
833
834       ·   CPAN Testers
835
836           The CPAN Testers is a network of smoke testers who run automated
837           tests on uploaded CPAN distributions.
838
839           <http://www.cpantesters.org/distro/C/Config-Model>
840
841       ·   CPAN Testers Matrix
842
843           The CPAN Testers Matrix is a website that provides a visual
844           overview of the test results for a distribution on various
845           Perls/platforms.
846
847           <http://matrix.cpantesters.org/?dist=Config-Model>
848
849       ·   CPAN Testers Dependencies
850
851           The CPAN Testers Dependencies is a website that shows a chart of
852           the test results of all dependencies for a distribution.
853
854           <http://deps.cpantesters.org/?module=Config::Model>
855
856   Bugs / Feature Requests
857       Please report any bugs or feature requests by email to "ddumont at
858       cpan.org", or through the web interface at
859       <https://github.com/dod38fr/config-model/issues>. You will be
860       automatically notified of any progress on the request by the system.
861
862   Source Code
863       The code is open to the world, and available for you to hack on. Please
864       feel free to browse it and play with it, or whatever. If you want to
865       contribute patches, please send me a diff or prod me to pull from your
866       repository :)
867
868       <http://github.com/dod38fr/config-model>
869
870         git clone git://github.com/dod38fr/config-model.git
871
872
873
874perl v5.30.0                      2019-08-04                  Config::Model(3)
Impressum