pax_global_header00006660000000000000000000000064147204101010014500gustar00rootroot0000000000000052 comment=795ce83af2f1955b56d67935341a54e0023c9522 cme-1.041/000077500000000000000000000000001472041010100122515ustar00rootroot00000000000000cme-1.041/.gitignore000066400000000000000000000000341472041010100142360ustar00rootroot00000000000000App-Cme-* .build wr_root *~ cme-1.041/.travis.yml000066400000000000000000000005751472041010100143710ustar00rootroot00000000000000# see https://travis-ci.community/t/older-perl-version-stopped-working/4294 dist: trusty language: perl perl: - "5.28" - "5.24" - "5.22" - "5.20" - "5.18" - "5.16" - "5.14" install: - cpanm --quiet --notest Dist::Zilla - "dzil authordeps --missing | cpanm --notest " - "dzil listdeps --missing | cpanm --notest " script: - dzil smoke --release --author cme-1.041/CONTRIBUTING.md000066400000000000000000000044371472041010100145120ustar00rootroot00000000000000# How to contribute # ## Ask questions ## Yes, asking a question is a form of contribution that helps the author to improve documentation. Feel free to ask questions by sending a mail to [the author](mailto:ddumont@cpan.org) ## Log a bug ## Please report issue on[cme issue tracker](https://github.com/dod38fr/cme-perl/issues). ## Source code structure ## The main parts of this modules are: * `bin/cme`: mostly cme command documentation * `contrib/bash_completion.cme`: the file that enable user to type 'cme[TAB]' and get the list of available sub-commands. See bash man page for more details on bash completion * `lib/App/Cme/Command/**.pm`: implementation of cme sub-commands * `t`: test files. Run the tests with `prove -l t` ## Edit source code from github ## If you have a github account, you can clone a repo and prepare a pull-request. You can: * run `git clone https://github.com/dod38fr/cme-perl` * edit files * run `prove -l t` to run non-regression tests There's no need to worry about `dzil`, `Dist::Zilla` or `dist.ini` files. These are useful to prepare a new release, but not to fix bugs. ## Edit source code from Debian source package ## You can also prepare a patch using Debian source package: For instance: * download and unpack `apt-get source cme` * jump in `cd cme-1.xxx` * useful to create a patch later: `git init` * commit all files: `git add -A ; git commit -m"committed all"` * edit files * run `prove -l t` to run non-regression tests * run `git diff` and send the output to the [author](mailto:ddumont@cpan.org) ## Edit source code from Debian source package or CPAN tarball ## Non Debian users can also prepare a patch using CPAN tarball: * Download tar file from http://search.cpan.org * unpack tar file with something like `tar axvf App-Cme-1.xxx.tar.gz` * jump in `cd App-Cme-1.xxx` * useful to create a patch later: `git init` * commit all files: `git add -A ; git commit -m"committed all"` * edit files * run `prove -l t` to run non-regression tests * run `git diff` and send the output to the [author](mailto:ddumont@cpan.org) ## Provide feedback ## Feedback is important. Please take a moment to rate, comment or add stars to this project: * [cme github](https://github.com/dod38fr/cme-perl) or [cme cpan ratings](http://cpanratings.perl.org/rate/?distribution=App-Cme) cme-1.041/Changes000066400000000000000000000256121472041010100135520ustar00rootroot00000000000000{{$NEXT}} 1.041 2024-11-23 New feature: * run: allow to use a value from config tree in commit message Bug fix: * run: fix ignored commit data in YAML script * run: fix crash with YAML script without default value Doc: * run: update doc on YAML scripts 1.040 2024-01-17 Bug fix: * fix deprecation warning 1.039 2023-12-09 New feature: * tkui: open write widget with "cme edit --open-item "" Bug fix: * cme run: improve heuristic to detect plain Perl script 1.038 2022-03-13 Bug fix: * run command: substitution of variable in commit message 1.037 2022-02-05 New feature: * allow code section in scripts * allow 'run' script in YAML or Perl format Misc changes: * remove "use XXX" from test script 1.036 2022-01-12 Bug fix: * fix test broken by output change in Config::Model 2.148 Misc changes: * tests requires Config::Model 2.148 1.035 2022-01-09 Bug fix: * fix postderef syntax with perl 5.20 * fix (run): --no-commit option * fix (run): do not try to commit when no changes are done * fix (test): broken by Config::Model 2.145 1.034 2021-10-30 New feature: * add use_backend_argument_as_config_file param to app files Misc changes: * require perl 5.20 * update copyright year * refactored following perlcritic advices 1.033 2021-09-19 Bug fix: * fix (fix command): display node name when needed * remove duplicate option definition * fix (run command): fix override of --commit option * fix force-load doc Dependency changes: * rm test dependency on Probe::Perl 1.032 2020-07-17 cme improvements: * cme warnings are now shown with log4perl in blue (the shown color depends on Log4Perl configuration) Doc improvements: * improve update command doc (Thanks Ross Vandegrift) * add contributor section in cme doc * run command: fix typos in synopsis comments 1.031 2020-01-12 Bug fix: * fix warning about deprecated -root parameter Misc: * suggest Config::Model::CursesUI instead of recommend * recommend Config::Model::TkUI >= 1.370 1.030 2019-09-11 Improve output of cme: * show more information when running "cme help" 1.029 2018-08-20 Bug fixes: * fix options diplayed by bash completion Smoke test fixes: * fix extra \n in output for perl < 5.18 1.028 2018-06-20 Documentation improvements: * add bugs section in cme doc * improve doc of modify command Improve output of cme: * check and modify commands are now silent when no problem is found. * run and modify commands show detailed script actions on configuration data in verbose mode * dump command: indicate -format choices in usage output * check command: show progress messages only in verbose mode. * fix command: show "running fix" message only in verbose mode * common: remove using xxx model message Bash completion fixes: * remove obsolete -backend option * fix bash completion of run command Other: * requires Config::Model 2.124 * run: allow untracked files when committing * cme: Simplify verbose option 1.027 2018-04-05 Improve cme run script: * add error message when application param is missing * leave capture parameters alone * add syntax for multi-line instructions * replace_var sub accepts several variabless * fix error message when run is called without argument Other: * Using cme option '-file' with value '-' is deprecated * update copyright year in dist.ini 1.026 2017-12-18 New experimental feature: * By default, Shellvar backend from Config::Model 2.116 keeps parameter order when writing back configuration data. This broke cme test that check that data is written with canonical order * add -canonical option to let data be written back according to model order (i.e. the previous behavior of shellvar backend) * Fix test broken by new ShellVar behavior (using -canonical option) * Depends on Config::Model 2.116 (for -canonical option) On-going deprecation of obscure multi backend feature * cme: remove obsolete -backend option (since only one backend can now be available, there's no need to an option to choose an alternative backend) 1.025 2017-12-14 Some new features for the rather new 'run' subcommand: * add -cat option option to show the script * -doc option also shows commit message New feature for the older 'dump' subcommand * -format accepts yaml or yml * -format value is now case insensitive * accept -format cds (alias to cml) Misc: * improve doc of modify command 1.024 2017-10-22 Some new features for the rather new 'run' subcommand: * add --no-commit option (Debian #877986) * add --commit option * can now specify default value for script args Other bug fixes: * run: remove warning about Log4Perl initialisation * run: fix option description * cme: update Log4Perl init in doc 1.023 2017-09-10 Bug fixes: * add missing backup option to read/write commands (like cme edit, fix, modify ...) * die if both require_config_file and require_backend_argument are set in app file (in Config/Model/[system|user|application].d) 1.022 2017-06-21 Bug fixes for smoke test failures: * test failure exit code to be != 0 * work-around test issue with perl < 5,18 1.021 2017-06-18 Bug fixes: * try to smoke test failures: convert cme test to use App::Cmd::Tester * remove deprecated arg '~~' from doc 1.020 2017-06-05 Improvements for all commands : * allow backend_argument (used by systemd) * unknown options trigger a warning Bug fixes: * all: fix bash completion of -file option * cme run: fix bash_completion of -doc option * cme allow non_upstream_default mode * all: remove -dev option which raises security issues. Use 'perl -Ilib -S cme' for the same effect 1.019 2017-04-30 This release brings some improvements: * run: allow to use command args in var: lines * cme: add '-verbose [ info | debug | trace ]' option to get debug logs Other bug fixes: * do not replace hash variable in run script 1.018 2017-04-07 This release improve 'cme run' command to make it more useful: * add -list option * can compute script variables (var: section) * can use environment variables * add possibility for scritps to provide their own doc displayed with 'cme run xxx -doc' * die when if a script variable is not defined * look for system scripts in /usr/share/ * add bash completion for cme run command Other changes: * save option can now be used with all subcommand 1.017 2017-03-05 This release bring a new cme sub-command to let you create small configuration scripts: cme run Misc: * update © years 1.016 2016-12-12 Bug fix: * check command: propagate -force option to skip load check * dump command must always be in quiet mode 1.015 2016-10-14 Bug fix: * cme: support utf8 in command args (Debian #839593) 1.014 2016-09-24 Improvements: * run deep_check when running commands check, edit, modify, shell (requires Config::Model 2.089) * improved error msg for unknown app (Closes Debian #836794) Bug fix: * cme: fix -strack-trace option 1.013 2016-07-10 Usability improvements: * clarify doc of -strict option (check cmd) * fix typo in pod doc (tx Thomas Schmitt) * suggest 'cme fix' when 'cme check' finds warnings * add CONTRIBUTE.md 1.012 2016-05-29 Bug fix: * edit command degrades gracefully when recommended packages are not isntalled * shell command degrades gracefully without Term::ReadLine 1.011 2016-04-21 New functionality: * dump command can dump any config file(s) in YAML, JSON or Perl format. 1.010 2016-01-30 New functionality: * Can read configuration directory from application file, e.g. user.d/ssh. This will help reuse Model between applications (e.g. systemd and systemd --user). This requires Config::Model 2.077 Bug fix: * cme list: fix -dev option option (Debian #813188) 1.009 2016-01-02 Bug fix release: * remove warning about missing config file. It's better to let the read/write backend handle bogus config file * update command: improved messages shown to user * list command: now work with -dev option 1.008 2015-11-14 Bug fix release: * fix -save option with modify command * fix -try-app-as-model option 1.007 2015-10-25 Usability improvements: * cme: added -file option to replace '~~' argument * bash_completion: added update sub command Doc fixes: * cme: fixed synopsis * cme: added update doc 1.006 2015-07-19 Doc fix release: * cme edit doc: don't abuse L<> tag which are change in "the xxx manpage" * cme list: improve help shown to user * cme help: transform pod to text to avoid showing pod markup * cme fix: corrected small mistakes in doc * cme check: added another example in pod doc 1.005 2015-05-25 * all: fixed confusing unwarranted warning message (about ~~ argument) 1.004 2015-05-25 Mostly a bug fix release. Please use now github to report issues on cme ( https://github.com/dod38fr/cme-perl/issues ) * metadata: * switched bugtracker to github's * fixed repo and website urls (Tx xtaran) * all: add a warning if conf file is not found (may mean a missing ~~ argument). (I'd welcome ideas on how to replace this iffy ~~ argument) * dump command: + added possibility to select a node to dump * fixed -dumptype which is not mandatory * test can run with local cme or system cme to fix debian continuous integrations tests 1.003 2015-04-26 Bug fix release: * Common: pass cme messages through on_message_cb * update: call C::M::Instance->update (require Config::Model 2.068) * remove debug call to YYY 1.002 2015-01-10 * gen-class-pod: * fix doc and missing command arguments * update: + added -edit option to run editor after an update * fix typo in pod doc * dist.ini: updated © to 2015 1.001 2014-11-29 * require Config::Model 2.063 (to avoid bash_completion clash) * improved messages printed by update command * added 'gen-class-pod' alias for gen_class_pod * bash_completion: + added help version commands update in hard-coded list of commands * fixed syntax error 0.001 2014-11-25 First release of App::Cme. These are the changes done to cme compared to the old cme shipped with Config::Model 2.061: * Cme has been re-written with App::Cmd - old mechanism for cme extension is removed. Extensions support is provided by App::Cmd + added gen_class_pod and update commands + added -quiet option to suppress progress messages * fix mistached options wrt available commands in bash_completion * added -root-dir option (used for tests) cme-1.041/MANIFEST.SKIP000066400000000000000000000001651472041010100141510ustar00rootroot00000000000000^debian/ ~$ \.ptkdb$ \.old$ dist.ini libconfig _build \.orig$ ^MYMETA.yml$ blib wr_root \.rej$ README.build-from-git cme-1.041/README.install.pod000066400000000000000000000015411472041010100153600ustar00rootroot00000000000000=head1 Installation =head2 Debian or Ubuntu L is provided as Debian package. Just type sudo apt-get install cme Or use your favorite installer =head2 Fedora or RedHat L is now packaged by RedHat. Type: sudo yum install perl-App-Cme =head2 Mac OSX L is provided as ppm package by L: =over =item * Install L =item * Update your $PATH variable to run ActiveState's perl =item * Run ppm to install L =back =head2 Windows You can also install L from L. See the instructions for Mac OSX for details. =head2 Other systems For other systems, you should install L from CPAN: cpanp install App::Cme cme-1.041/README.pod000066400000000000000000000045701472041010100137200ustar00rootroot00000000000000=begin html =end html =head1 cme - Check or edit configuration data L provides a command to check or edit configuration data with L. L and L are quite modular: the configuration data that you can edit depend on the other C distributions installed on your system. For instance, to configure L or L, you need to install L. Then you can check your ssh configuration with this command: $ cme check ssh and you can modify it with: $ cme edit ssh The L contains a L L provides several commands. The most important are : =over =item check To check the content of the configuration file of an application. =item fix To fix the warnings of the configuration file. =item edit To launch cme interactive editor. This editor contains documentation and sanity checks to help user configure correctly their application. =back L user interface can be: =over =item * Graphical if L is installed. =item * a shell-like interface (plain or based on L). =item * based on curses if L is installed. =back By default, C will try to launch a GUI. =head2 Installation See L. Perl developers can also L =head2 What does "cme" means ? Nothing fancy: "Config Model Editor". The idea was to L. =head2 More information See =over =item * L man page =item * L (i.e. the wiki tab above) =item * L =item * The list of available models, interfaces and known configuration syntaxes: https://github.com/dod38fr/config-model/wiki/Available-models-and-backends =back cme-1.041/bin/000077500000000000000000000000001472041010100130215ustar00rootroot00000000000000cme-1.041/bin/cme000077500000000000000000000252651472041010100135250ustar00rootroot00000000000000#!/usr/bin/env perl # PODNAME: cme # ABSTRACT: Check or edit configuration data with Config::Model # see perlunicook use utf8; # so literals and identifiers can be in UTF-8 use v5.12; # or later to get "unicode_strings" feature use strict; # quote strings, declare variables use warnings; # on by default use warnings qw(FATAL utf8); # fatalize encoding glitches use open qw(:std :utf8); # undeclared streams in UTF-8 use charnames qw(:full :short); # unneeded in v5.16 use App::Cme; App::Cme->run; __END__ =pod =head1 SYNOPSIS # general synopsis cme [ global_options ] command application [ options ] [ file ] [ modification_instructions ] # edit dpkg config with GUI (and Config::Model::Dpkg) cme edit dpkg # read data from arbitrary file (for model read from alternate file) cme check dpkg-copyright -file path/to/file # edit /etc/sshd_config (with Config::Model::OpenSsh) sudo cme edit sshd # edit ~/.ssh/config (with Config::Model::OpenSsh) cme edit ssh # just check the validity of a file. Both commands are equivalent cme check multistrap file.conf cme check multistrap -file file.conf # check dpkg files, update deprecated parameters and save cme migrate dpkg # like migrate, but also apply all suggested fixes cme fix dpkg # modify configuration with command line cme modify dpkg source 'format="(3.0) quilt"' # likewise with an application that accepts file override cme modify dpkg-copyright 'Comment="Modified with cme"' # edit a file (file name specification is mandatory here) cme edit multistrap my.conf # map conf data to a fuse file system cme fusefs multistrap my.conf -d fuse_dir # likewise for dpkg data cme fusefs dpkg -d fuse_dir # list all available applications (depends on your installation) cme list =head1 DESCRIPTION Depending on the command described below, C program will use Config::Model configuration descriptions to check or modify or fix configuration files. The 3rd parameter specify the application you want to work on. Most of the time, the relevant configuration file(s) will be found by cme. This is the most simple case. For instance: sudo cme check popcon Some application like C have no constraint on the configuration file name and will require you to specify your configuration file name: cme check multistrap raspbian.conf or cme check multistrap -file raspbian.conf =head1 Configuration file specification The configuration of an application can take different forms. Either several files (like debian packages), a single file with a predefined file (popcon), or a single file with an arbitrary file name (multistrap). When needed the configuration file name is specified as the 3rd command argument, i.e. C. This applies if the application requires a configuration file name (like multistrap), or if the application allows configuration file override. =head1 Main commands This section describes the main commands shipped with cme. Other Config::Model extensions can bring more command. Run C to get the list of available commands on your system. =head2 list Show a list all applications where a model is available. This list depends on installed Config::Model modules. =head2 edit Edit a configuration. By default, a Tk GUI will be opened If L is installed. See L. =head2 shell Edit the configuration with a shell like interface. See L. =head2 check Checks the content of the configuration file of an application. See L. =head2 migrate Update deprecated parameters (old value are saved to new parameters) and save the new configuration. See L. =head2 fix Migrate data and fix warnings. See L. =head2 modify Modify a configuration file with the values passed on the command line. See L. =head2 update Update the content of the configuration file from external data. Currently, only dpkg-copyright model support update sub command. See L. =head2 search Search configuration data for a specific string. See L. =head2 fusefs Map the configuration file content to a FUSE virtual file system on a directory specified with option C<-fuse-dir>. Modifications done in the fuse file system are saved to the configuration file when the C is run. =head1 Global options The following options are available for all commands: =over =item -create Perform the operation even if the configuration file is missing. This may be used to create a minimal configuration file. This option is disabled by default as a missing configuration file often indicates an error during the installation of the application. =item -file For model that support it, specify an alternate file to read and write the configuration. You can use this option for model that require the target file to be specified (e.g. multitrap model), but file can in this case be also specified with the 4th command argument. E.g. these 2 commands have the same effect: cme check multistrap foo.conf cme check multistrap -file foo.conf =item -force-load Load file even if error are found in data. Bad data are discarded =item -canonical Write config data back using model order. By default, write items back using the order found in the configuration file. This feature is experimental and not supported by all backends. =item -backup Create a backup of configuration files before saving. By default, C will be appended to the backup file. I.e. C will be backed up as C. You can specify an alternate suffix. For instance C<-backup dpkg-old>. =item -save Force a save even if no change was done. Useful to reformat the configuration file. =item -strict When set, cme will exit 1 if warnings are found during check (of left after fix) =item -verbose Show more information about what's going on. =item -quiet Suppress all output except error messages. =back =head1 Advanced options =over =item -model-dir Specify an alternate directory to find model files. Mostly useful for tests. =item -root-dir Specify a pseudo root directory to read and write the configuration files. (Actual default directory and file names depends on the model (See C<-model> option). For instance, if you specify C<~/mytest>, the C files will be written in C<~/mytest/etc/ssh/> directory. =item -stack-trace Provides a full stack trace when exiting on error. =item -try-app-as-model When set, try to load a model using directly the application name specified as 3rd parameter on the command line. Experimental. =back =head1 Embedding cme You can use cme from another program by using C<-ui simple> option. This way you will be able to send command on the standard input of C and get the results from the standard output. =head1 Logging All Config::Model logging is now based on L. Logging can be configured in the following files: =over =item * ~/.log4config-model =item * /etc/log4config-model.conf =back A sample of a C<.log4config-model> is provided in contrib directory in C distribution of on L Without these files, the following Log4perl config is used: log4perl.rootLogger=WARN, Screen log4perl.logger.Model.Legacy = INFO, SimpleScreen log4perl.additivity.Model.Legacy = 0 log4perl.appender.Screen = Log::Log4perl::Appender::Screen log4perl.appender.Screen.stderr = 0 log4perl.appender.Screen.layout = Log::Log4perl::Layout::PatternLayout log4perl.appender.Screen.layout.ConversionPattern = %M %m (line %L)%n log4perl.appender.SimpleScreen = Log::Log4perl::Appender::Screen log4perl.appender.SimpleScreen.stderr = 0 log4perl.appender.SimpleScreen.layout = Log::Log4perl::Layout::PatternLayout log4perl.appender.SimpleScreen.layout.ConversionPattern = %p: %m%n log4perl.oneMessagePerAppender = 1 Log4perl uses the following categories: =over =item Anything =item Anything::Change Trace change notification through configuration tree and instance. =item Backend =item Backend::Debian::Dpkg =item Backend::Debian::Dpkg::Control =item Backend::Debian::Dpkg::Copyright =item Backend::Fstab =item Backend::IniFile =item Backend::PlainFile =item Backend::ShellVar =item Backend::Yaml =item FuseUI =item Instance =item Loader =item Model::Searcher =item Tree::Element::CheckList =item Tree::Element::Id =item Tree::Element::Id::Hash =item Tree::Element::Id::List =item Tree::Element::Value =item Tree::Element::Value::Dependency =item Tree::Node =item Tree::Node::Warped =item ValueComputer =item Warper =item Iterator =item Model =back More categories will come. =head1 EXIT CODE cme exits 0 when no errors are found. Exit 1 otherwise. =head1 BUGS =head2 Files may be re-ordered C imposes a specific ordering of the parameters of a configuration file. This ordering is derived from the documentation of the configuration, like L. C writes back files using this ordering. Thus, the diff between the original configuration files and the new version of the file may be more important than expected when C is used the first time. =head2 Comments may be dropped Comments are not supported in some applidations (like the one that use YAML in configuration files). Comments are dropped when using C to edit or modify such files. For more details, see L page. =head2 Configuration models can lag behind the target application If a configuration model is not up-to-date, you will get errors complaining about unknown parameters. In such a case, please file a bug on L or fix the model and send a pull request. You can see this L to learn how to fix a model. =head1 FOR MORE INFORMATION For more information, please check: =over =item * config-model wiki: L =item * Blogs about this project: L =back =head1 CONTRIBUTORS In alphabetical order: Ross Vandegrift =head1 FEEDBACKS Feedback from users are highly desired. If you find this module useful, please share your use cases, success stories with the author. =head1 SEE ALSO L, L, L, L, L, L, L =cut cme-1.041/build-from-git.md000066400000000000000000000031151472041010100154140ustar00rootroot00000000000000# How to build App::Cme from git repository `App::Cme` is build with [Dist::Zilla](http://dzil.org/). This pages details how to install the tools and dependencies required to build this module. ## Install tools and dependencies ### Debian, Ubuntu and derivatives Run $ sudo apt install libdist-zilla-perl libdist-zilla-app-command-authordebs-perl $ dzil authordebs --install $ sudo apt build-dep cme The [libdist-zilla-app-command-authordebs-perl package](https://tracker.debian.org/pkg/libdist-zilla-app-command-authordebs-perl) is quite recent (uploaded on Dec 2016 in Debian/unstable) and may not be available yet on your favorite distribution. ### Other systems Run $ cpamn Dist::Zilla $ dzil authordeps -missing | cpanm --notest $ dzil listdeps --missing | cpanm --notest NB: The author would welcome pull requests that explains how to install these tools and dependencies using native package of other distributions. ## Build App::Cme Run dzil build or dzil test `dzil` may complain about missing `EmailNotify` or `Twitter` plugin. You may ignore this or edit [dist.ini](dist.ini) to comment out the last 2 sections. These are useful only to the author when releasing a new version. `dzil` may also return an error like `Cannot determine local time zone`. In this case, you should specify explicitely your timezone in a `TZ` environement variable. E.g run `dzil` this way: TZ="Europe/Paris" dzil test The list of possible timezones is provided by [DateTime::TimeZone::Catalog](https://metacpan.org/pod/DateTime::TimeZone::Catalog) documentation. cme-1.041/contrib/000077500000000000000000000000001472041010100137115ustar00rootroot00000000000000cme-1.041/contrib/bash_completion.cme000066400000000000000000000102601472041010100175440ustar00rootroot00000000000000# cme(1) completion -*- shell-script -*- # # # This file is part of App::Cmd::Cme # # This software is Copyright (c) 2011, 2014 by Dominique Dumont # # This is free software, licensed under: # # The GNU Lesser General Public License, Version 2.1, February 1999 # global_options='--force-load --create --trace --quiet --file --verbose --canonical' _cme_models() { MODELS=$(perl -MConfig::Model::Lister -e'print Config::Model::Lister::models;') COMPREPLY=( $( compgen -W "$MODELS" -- $cur ) ) } _cme_appli() { MODELS=$(perl -MConfig::Model::Lister -e'print Config::Model::Lister::applications;') COMPREPLY=( $( compgen -W "$MODELS" -- $cur ) ) } _cme_commands() { # use perl so that plugged in subcommand (like meta) are listed SUBCMDS=$(perl -MApp::Cme -e'print join("\n", grep {not /-/} App::Cme->new->command_names);') COMPREPLY=( $( compgen -W "$SUBCMDS" -- $cur ) ) } _cme_cmd_run() { vendor_scripts=$(perl -MConfig::Model::Lister -E 'my $p = $INC{"Config/Model/Lister.pm"}; $p =~ s/Lister.pm/scripts/; say $p') if [[ $COMP_CWORD -eq 2 ]] ; then scripts=$(find ~/.cme/scripts/ /etc/cme/scripts $vendor_scripts -type f ! -name '*~' -printf '%f\n' 2>/dev/null) COMPREPLY=( $( compgen -W "-list $scripts" -- $cur ) ) elif [[ $prev == '-arg' ]]; then script=$(find ~/.cme/scripts/ /etc/cme/scripts $vendor_scripts -type f -name ${COMP_WORDS[2]}) var=$( perl -E 'my @v; while(<>) { push @v, /\$(\w+)/g }; my %map = map { ($_ => 1)} @v; print map { "$_= " } sort keys %map;' $script); COMPREPLY=( $( compgen -W "$var" -- $cur ) ) elif [[ $prev != '-list' ]]; then COMPREPLY=( $( compgen -W "--arg --doc --commit --no-commit --cat $global_options" -- $cur ) ) fi } _cme_handle_app_arg() { [[ $COMP_CWORD -eq 3 ]] && _cme_${COMP_WORDS[2]} 2> /dev/null ; } _cme_handle_cmd_arg() { [[ $COMP_CWORD -ge 2 ]] && _cme_cmd_${COMP_WORDS[1]} 2> /dev/null ; } _cme() { local cur COMPREPLY=() _get_comp_words_by_ref -n : cur prev if [[ $COMP_CWORD -eq 1 ]] ; then _cme_commands elif _cme_handle_cmd_arg; then TRASH=1; # bash does not support empty then/elif elif [[ $COMP_CWORD -eq 2 ]] ; then _cme_appli elif ! _cme_handle_app_arg; then case $prev in --ui) COMPREPLY=( $( compgen -W 'tk curses shell' -- $cur ) ) ;; --dumptype) COMPREPLY=( $( compgen -W 'full preset custom' -- $cur ) ) ;; --format) COMPREPLY=( $( compgen -W 'yaml json perl cml' -- $cur ) ) ;; --model-dir|-root-dir|-fuse-dir) _filedir -d ;; --file) _filedir ;; *) case ${COMP_WORDS[1]} in check) COMPREPLY=( $( compgen -W "$global_options --strict" -- $cur ) ) ;; dump) COMPREPLY=( $( compgen -W "$global_options --dumptype --format" -- $cur ) ) ;; edit) COMPREPLY=( $( compgen -W "$global_options --ui --open-item" -- $cur ) ) ;; fix) COMPREPLY=( $( compgen -W "$global_options --from --filter" -- $cur ) ) ;; fusefs) COMPREPLY=( $( compgen -W "$global_options --fuse-dir --dfuse --dir-char" -- $cur ) ) ;; migrate) COMPREPLY=( $( compgen -W "$global_options" -- $cur ) ) ;; update) COMPREPLY=( $( compgen -W "$global_options" -- $cur ) ) ;; # modify completion could be much more elaborate... modify) COMPREPLY=( $( compgen -W "$global_options --save --backup --format" -- $cur ) ) ;; run) COMPREPLY=( $( compgen -W "$global_options --doc --cat --no-commit" -- $cur ) ) ;; search) COMPREPLY=( $( compgen -W "$global_options --search --narrow-search" -- $cur ) ) ;; esac esac fi } complete -F _cme cme cme-1.041/dist.ini000066400000000000000000000026141472041010100137200ustar00rootroot00000000000000name = App-Cme author = Dominique Dumont license = LGPL_2_1 copyright_holder = Dominique Dumont copyright_year = 2014-2022 [MetaResources] homepage = https://github.com/dod38fr/config-model/wiki bugtracker.mailto = ddumont at cpan.org bugtracker.web = https://github.com/dod38fr/cme-perl/issues repository.url = https://github.com/dod38fr/cme-perl.git repository.web = http://github.com/dod38fr/cme-perl repository.type = git [Prereqs] perl = 5.020 [NextRelease] format = %v%T %{yyyy-MM-dd}d ; use 'V=2.234 dzil release' to override version number [Git::NextVersion] [Git::Check] allow_dirty = dist.ini allow_dirty = Changes [Git::Commit] [Git::Tag] [Git::Push] [MetaJSON] [AutoPrereqs] skip = ^[a-z\d]+$ skip = ExtUtils::testlib skip = Exporter skip = Tk skip = CursesUI ; not detected by dzil authordep. ; See Dist::Zilla::App::Command::authordeps man page ; authordep Pod::Weaver::Section::Support ; authordep Pod::Elemental::Transformer::List [Prereqs / RuntimeRequires] ; module used only in cme are not found... Path::Tiny = 0 [Prereqs / RuntimeRecommends] Config::Model::TkUI = 1.370 [Prereqs / RuntimeSuggests] Config::Model::CursesUI = 0 [@Filter] -bundle = @Basic -remove = Readme -remove = MakeMaker [ModuleBuild] mb_version = 0.34 [PkgVersion] [PodWeaver] [Prepender] ;-- see https://metacpan.org/pod/Dist::Zilla::Plugin::Signature [Signature] cme-1.041/lib/000077500000000000000000000000001472041010100130175ustar00rootroot00000000000000cme-1.041/lib/App/000077500000000000000000000000001472041010100135375ustar00rootroot00000000000000cme-1.041/lib/App/Cme.pm000066400000000000000000000003221472041010100145760ustar00rootroot00000000000000package App::Cme ; use strict; use warnings; use 5.10.1; # See App::Cmd for explanations on this file use App::Cmd::Setup -app; 1; # ABSTRACT: Configuration data checker or editor based on Config::Model cme-1.041/lib/App/Cme/000077500000000000000000000000001472041010100142435ustar00rootroot00000000000000cme-1.041/lib/App/Cme/Command/000077500000000000000000000000001472041010100156215ustar00rootroot00000000000000cme-1.041/lib/App/Cme/Command/check.pm000066400000000000000000000051071472041010100172370ustar00rootroot00000000000000# ABSTRACT: Check the configuration of an application package App::Cme::Command::check ; use strict; use warnings; use 5.10.1; use App::Cme -command ; use base qw/App::Cme::Common/; use Config::Model::ObjTreeScanner; sub validate_args { my ($self, $opt, $args) = @_; $self->check_unknown_args($args); $self->process_args($opt,$args); return; } sub opt_spec { my ( $class, $app ) = @_; return ( [ "strict!" => "cme will exit 1 if warnings are found during check" ], $class->cme_global_options, ); } sub usage_desc { my ($self) = @_; my $desc = $self->SUPER::usage_desc; # "%c COMMAND %o" return "$desc [application] [ config_file ]"; } sub description { my ($self) = @_; return $self->get_documentation; } sub execute { my ($self, $opt, $args) = @_; my ($model, $inst, $root) = $self->init_cme($opt,$args); my $check = $opt->{force_load} ? 'no' : 'yes' ; say "Loading data..." if $opt->{verbose}; Config::Model::ObjTreeScanner->new( leaf_cb => sub { }, check => $check, )->scan_node( undef, $root ); say "Checking data.." if $opt->{verbose}; $root->dump_tree( mode => 'full' ); # light check (value per value) $root->deep_check; # consistency check say "Check done." if $opt->{verbose}; my $ouch = $inst->has_warning; if ( $ouch ) { my $app = $inst->application; warn "you can try 'cme fix $app' to fix the warnings shown above\n"; die "Found $ouch warnings in strict mode\n" if $opt->{strict}; } return; } 1; __END__ =head1 SYNOPSIS # standard usage cme check popcon # read data from arbitrary file (with Config::Model::Dpkg) cme check dpkg-copyright path/to/file =head1 DESCRIPTION Checks the content of the configuration file of an application. Prints warnings and errors on STDOUT. Example: cme check fstab Some applications allows one to override the default configuration file. For instance, with Debian copyright model, you can run cme on a different file: cme check dpkg-copyright foobar or directly check copyright data on STDIN: curl http://metadata.ftp-master.debian.org/changelogs/main/f/frozen-bubble/unstable_copyright \ | cme check dpkg-copyright - =head1 Common options See L. =head1 options =over =item -strict When set, cme exits 1 if warnings are found. By default, C exits 0 when warnings are found. =back =head1 EXIT CODE cme exits 0 when no errors are found. Exit 1 otherwise. If C<-strict> option is set, cme exits 1 when warnings are found. =head1 SEE ALSO L =cut cme-1.041/lib/App/Cme/Command/dump.pm000066400000000000000000000057371472041010100171400ustar00rootroot00000000000000# ABSTRACT: Dump the configuration of an application package App::Cme::Command::dump ; use strict; use warnings; use 5.10.1; use App::Cme -command ; use base qw/App::Cme::Common/; use Config::Model::ObjTreeScanner; use YAML::PP qw/Dump/; use JSON; use Data::Dumper; sub validate_args { my ($self, $opt, $args) = @_; $self->check_unknown_args($args); $opt->{quiet} = 1; # don't want to mess up yaml output $self->process_args($opt,$args); return; } sub opt_spec { my ( $class, $app ) = @_; return ( [ "dumptype=s" => "Dump all values (full) or only customized values", { regex => qr/^(?:full|custom|non_upstream_default)$/, default => 'custom' } ], [ "format=s" => "dump using specified format (yaml json perl cml)", { regex => qr/^(?:json|ya?ml|perl|cml|cds)$/i, default => 'yaml' }, ], $class->cme_global_options, ); } sub usage_desc { my ($self) = @_; my $desc = $self->SUPER::usage_desc; # "%c COMMAND %o" return "$desc [application] [ config_file ] [ -dumptype full|custom ] [ path ]"; } sub description { my ($self) = @_; return $self->get_documentation; } sub execute { my ($self, $opt, $args) = @_; my ($model, $inst, $root) = $self->init_cme($opt,$args); my $target_node = $root->grab(step => "@$args", type => 'node'); my $dump_string; my $format = $opt->{format}; my $mode = $opt->{dumptype} || 'custom'; if ($format =~ /cml|cds/i) { $dump_string = $target_node->dump_tree( mode => $mode ); } else { my $perl_data = $target_node->dump_as_data( ordered_hash_as_list => 0, mode => $mode ); $dump_string = $format =~ /ya?ml/i ? Dump($perl_data) : $format =~ /json/i ? encode_json($perl_data) : Dumper($perl_data) ; # Perl data structure } print $dump_string ; return; } 1; __END__ =head1 SYNOPSIS # dump ~/.ssh/config in cme syntax # (this example requires Config::Model::OpenSsh) $ cme dump -format cml ssh Host:"*" - Host:"*.debian.org" User=dod - =head1 DESCRIPTION Dump configuration content on STDOUT with YAML format. By default, dump only custom values, i.e. different from application built-in values or model default values. You can use the C<-dumptype> option for other types of dump: -dumptype [ full | custom | non_upstream_default ] Choose to dump every values (full), or only customized values (default) C is like C mode, but value identical with application default are omitted. But this should seldom happen. By default, dump in yaml format. This can be changed in C, C, C (aka L format, C is also accepted) with C<-format> option. =head1 Common options See L. =head1 SEE ALSO L =cut cme-1.041/lib/App/Cme/Command/edit.pm000066400000000000000000000076771472041010100171250ustar00rootroot00000000000000# ABSTRACT: Edit the configuration of an application package App::Cme::Command::edit ; use strict; use warnings; use 5.10.1; use App::Cme -command ; use base qw/App::Cme::Common/; use Config::Model::ObjTreeScanner; sub validate_args { my ($self, $opt, $args) = @_; $self->check_unknown_args($args); $self->process_args($opt,$args); return; } sub opt_spec { my ( $class, $app ) = @_; return ( [ "ui|if=s" => "user interface type. Either tk, curses, shell" ], [ "backup:s" => "Create a backup of configuration files before saving." ], [ "open-item=s" => "open a specific item of the configuration" ], $class->cme_global_options, ); } sub usage_desc { my ($self) = @_; my $desc = $self->SUPER::usage_desc; # "%c COMMAND %o" return "$desc [application] [ file ] [ -ui tk|curses|shell ] [ -open-item xxx ] "; } sub description { my ($self) = @_; return $self->get_documentation; } sub execute { my ($self, $opt, $args) = @_; my ($model, $inst, $root) = $self->init_cme($opt,$args); my $has_tk = eval { require Config::Model::TkUI; 1; }; my $has_curses = eval { require Config::Model::CursesUI; 1; }; my $ui_type = $opt->{ui}; if ( not defined $ui_type ) { if ($has_tk) { $ui_type = 'tk'; } elsif ($has_curses) { warn "You should install Config::Model::TkUI for a ", "more friendly user interface\n"; $ui_type = 'curses'; } else { warn "You should install Config::Model::TkUI or ", "Config::Model::CursesUI ", "for a more friendly user interface\n"; $ui_type = 'shell'; } } $root->deep_check; if ( $ui_type eq 'shell' ) { require Config::Model::TermUI; $self->run_shell_ui('Config::Model::TermUI', $inst) ; } elsif ( $ui_type eq 'curses' ) { die "cannot run curses interface: ", "Config::Model::CursesUI is not installed, please use shell or simple UI\n" unless $has_curses; my $err_file = '/tmp/cme-error.log'; print "In case of error, check $err_file\n"; open( my $fh, ">", $err_file ) || die "Can't open $err_file: $!\n"; open(STDERR, ">&", $fh)|| die "Can't open STDERR:$!\n"; my $dialog = Config::Model::CursesUI->new(); # engage in user interaction $dialog->start($model); close($fh); } elsif ( $ui_type eq 'tk' ) { die "cannot run Tk interface: Config::Model::TkUI is not installed, please use curses or shell or simple ui\n" unless $has_tk; $self ->run_tk_ui ( $inst, $opt); } else { die "Unsupported user interface: $ui_type\n"; } return; } 1; __END__ =head1 SYNOPSIS # edit dpkg config with GUI (requires Config::Model::Dpkg) cme edit dpkg # force usage of simple shell like interface cme edit dpkg-copyright --ui shell # edit /etc/sshd_config (requires Config::Model::OpenSsh) sudo cme edit sshd # edit ~/.ssh/config (requires Config::Model::OpenSsh) cme edit ssh # edit a file (file name specification is mandatory here) cme edit multistrap my.conf =head1 DESCRIPTION Edit a configuration. By default, a Tk GUI will be opened if C is installed. You can choose another user interface with the C<-ui> option: =over =item * C: provides a Tk graphical interface (If C is installed). =item * C: provides a curses user interface (If L is installed). =item * C: provides a shell like interface. See L for details. This is equivalent to running C command. =back =head1 Common options See L. =head1 options =over =item -open-item Open a specific item of the configuration when opening the editor. Trying to open a non-existing item triggers an error. =back =head1 SEE ALSO L =cut cme-1.041/lib/App/Cme/Command/fix.pm000066400000000000000000000047331472041010100167540ustar00rootroot00000000000000# ABSTRACT: Fix the configuration of an application package App::Cme::Command::fix ; use strict; use warnings; use 5.10.1; use App::Cme -command ; use base qw/App::Cme::Common/; use Config::Model::ObjTreeScanner; sub validate_args { my ($self, $opt, $args) = @_; $self->check_unknown_args($args); $self->process_args($opt,$args); return; } sub opt_spec { my ( $class, $app ) = @_; return ( [ "from=s@" => "fix only a subset of a configuration tree" ], [ "backup:s" => "Create a backup of configuration files before saving." ], [ "filter=s" => "pattern to select the element name to be fixed"], $class->cme_global_options, ); } sub usage_desc { my ($self) = @_; my $desc = $self->SUPER::usage_desc; # "%c COMMAND %o" return "$desc [application] [ file ]"; } sub description { my ($self) = @_; return $self->get_documentation; } sub execute { my ($self, $opt, $args) = @_; my ($model, $inst, $root) = $self->init_cme($opt,$args); my @fix_from = $opt->{from} ? @{$opt->{from}} : ('') ; foreach my $path (@fix_from) { my $node_to_fix = $inst->config_root->grab($path); my $msg = "cme: running fix on ".$inst->name." configuration"; $msg .= "from node ". $node_to_fix->name if $path; say $msg. "..." if $opt->{verbose}; $node_to_fix->apply_fixes($opt->{fix_filter}); } $self->save($inst,$opt) ; return; } 1; __END__ =head1 SYNOPSIS # fix dpkg (this example requires Config::Model::Dpkg) cme fix dpkg =head1 DESCRIPTION Checks the content of the configuration file of an application (and show warnings if needed), update deprecated parameters (old value are saved to new parameters) and fix warnings are fixed. The configuration is saved if anything was changed. If no changes are done, the file is not saved. =head1 Common options See L. =head1 options =over =item from Use option C<-from> to fix only a subset of a configuration tree. Example: cme fix dpkg -from 'control binary:foo Depends' This option can be repeated: cme fix dpkg -from 'control binary:foo Depends' -from 'control source Build-Depends' =item filter Filter the leaf according to a pattern. The pattern is applied to the element name to be fixed Example: cme fix dpkg -from control -filter Build # will fix all Build-Depends and Build-Depend-Indep or cme fix dpkg -filter Depend =back =head1 SEE ALSO L, L =cut cme-1.041/lib/App/Cme/Command/fusefs.pm000066400000000000000000000054341472041010100174600ustar00rootroot00000000000000# ABSTRACT: Edit the configuration of an application with fuse package App::Cme::Command::fusefs ; use strict; use warnings; use 5.10.1; use App::Cme -command ; use base qw/App::Cme::Common/; use Config::Model::ObjTreeScanner; sub validate_args { my ($self, $opt, $args) = @_; $self->check_unknown_args($args); $self->process_args($opt,$args); my $has_fuse = eval { require Config::Model::FuseUI; 1; }; die "could not load Config::Model::FuseUI. Is Fuse installed ?\n" unless $has_fuse; my $fd = $opt->{fuse_dir}; die "Directory $fd does not exists\n" unless -d $fd; return; } sub opt_spec { my ( $class, $app ) = @_; return ( [ "fuse-dir=s" => "Directory where the virtual file system will be mounted", {required => 1} ], [ "dfuse!" => "debug fuse problems" ], [ "dir-char=s" => "string to replace '/' in configuration parameter names"], [ "backup:s" => "Create a backup of configuration files before saving." ], $class->cme_global_options, ); } sub usage_desc { my ($self) = @_; my $desc = $self->SUPER::usage_desc; # "%c COMMAND %o" return "$desc [application] [file ] -fuse-dir xxx [ -dir-char x ] "; } sub description { my ($self) = @_; return $self->get_documentation; } sub execute { my ($self, $opt, $args) = @_; my ($model, $inst, $root) = $self->init_cme($opt,$args); my @extra; if (my $dc = $opt->{dir_char}) { push @extra, dir_char_mockup => $dc; } my $fuse_dir = $opt->{fuse_dir}; print "Mounting config on $fuse_dir in background.\n", "Use command 'fusermount -u $fuse_dir' to unmount\n"; my $ui = Config::Model::FuseUI->new( root => $root, mountpoint => $fuse_dir, @extra, ); # now fork my $pid = fork; if ( defined $pid and $pid == 0 ) { # child process, just run fuse and wait for exit $ui->run_loop( debug => $opt->{fuse_debug} ); $self->save($inst,$opt); } # parent process simply exits return; } 1; __END__ =head1 SYNOPSIS =head1 DESCRIPTION Map the configuration file content to a FUSE virtual file system on a directory specified with option C<-fuse-dir>. Modifications done in the fuse file system are saved to the configuration file when C<< fusermount -u >> is run. =head1 Common options See L. =head1 options =over =item -fuse-dir Mandatory. Directory where the virtual file system will be mounted. =item -dfuse Use this option to debug fuse problems. =item -dir-char Fuse will fail if an element name or key name contains '/'. You can specify a substitution string to replace '/' in the fused dir. Default is C<< >>. =back =head1 SEE ALSO L =cut cme-1.041/lib/App/Cme/Command/gen_class_pod.pm000066400000000000000000000020101472041010100207500ustar00rootroot00000000000000# ABSTRACT: Generates pod doc from model files package App::Cme::Command::gen_class_pod ; use strict; use warnings; use 5.10.1; use App::Cme -command ; use Config::Model::Utils::GenClassPod; sub command_names { my $self = shift ; return ( 'gen-class-pod' , $self->SUPER::command_names ); } sub description { return << "EOD" Generate pod documentation from configuration models found in ./lib directory EOD } sub execute { my ($self, $opt, $args) = @_; gen_class_pod(@$args); return; } 1; =head1 SYNOPSIS cme gen-class-pod [ Foo ... ] =head1 DESCRIPTION This command scans C<./lib/Config/Model/models/*.d> and generate pod documentation for each file found there using L You can also pass one or more class names. C will write the documentation for each passed class and all other classes used by the passed classes. =head1 SEE ALSO L, L =cut cme-1.041/lib/App/Cme/Command/list.pm000066400000000000000000000026701472041010100171370ustar00rootroot00000000000000# ABSTRACT: List applications handled by cme package App::Cme::Command::list ; use strict; use warnings; use 5.10.1; use App::Cme -command ; use Config::Model::Lister; sub description { return << "EOD" Show a list all applications where a model is available. This list depends on installed Config::Model modules. Applications are divided in 3 categories: - system: for system wide applications (e.g. daemon like sshd) - user: for user applications (e.g. ssh configuration) - application: misc application like multistrap or Debian packaging EOD } sub opt_spec { my ( $class, $app ) = @_; return ( [ "dev!" => "list includes a model under development"], ); } my %help = ( system => "system configuration files. Use sudo to run cme", user => "user configuration files", application => "miscellaneous application configuration", ); sub execute { my ($self, $opt, $args) = @_; my ( $categories, $appli_info, $appli_map ) = Config::Model::Lister::available_models($opt->dev()); foreach my $cat ( qw/system user application/ ) { my $names = $categories->{$cat} || []; next unless @$names; print $cat," ( ",$help{$cat}," ):\n ", join( "\n ", @$names ), "\n"; } return; } 1; =head1 SYNOPSIS cme list =head1 DESCRIPTION Show a list all applications where a model is available. This list depends on installed Config::Model modules. =head1 SEE ALSO L =cut cme-1.041/lib/App/Cme/Command/migrate.pm000066400000000000000000000026521472041010100176140ustar00rootroot00000000000000# ABSTRACT: Migrate the configuration of an application package App::Cme::Command::migrate ; use strict; use warnings; use 5.10.1; use App::Cme -command ; use base qw/App::Cme::Common/; use Config::Model::ObjTreeScanner; sub validate_args { my ($self, $opt, $args) = @_; $self->check_unknown_args($args); $self->process_args($opt,$args); return; } sub opt_spec { my ( $class, $app ) = @_; return ( [ "backup:s" => "Create a backup of configuration files before saving." ], $class->cme_global_options, ); } sub usage_desc { my ($self) = @_; my $desc = $self->SUPER::usage_desc; # "%c COMMAND %o" return "$desc [application] [file ]"; } sub description { my ($self) = @_; return $self->get_documentation; } sub execute { my ($self, $opt, $args) = @_; my ($model, $inst, $root) = $self->init_cme($opt,$args); $root->migrate; $self->save($inst,$opt) ; return; } 1; __END__ =head1 SYNOPSIS # check dpkg files, update deprecated parameters and save cme migrate dpkg =head1 DESCRIPTION Checks the content of the configuration file of an application (and show warnings if needed), update deprecated parameters (old value are saved to new parameters) and save the new configuration. See L. For more details, see L =head1 Common options See L. =head1 SEE ALSO L =cut cme-1.041/lib/App/Cme/Command/modify.pm000066400000000000000000000055141472041010100174530ustar00rootroot00000000000000# ABSTRACT: Modify the configuration of an application package App::Cme::Command::modify ; use strict; use warnings; use 5.10.1; use App::Cme -command ; use base qw/App::Cme::Common/; use Config::Model::ObjTreeScanner; use Config::Model qw/initialize_log4perl/; sub validate_args { my ($self, $opt, $args) = @_; $self->check_unknown_args($args); $self->process_args($opt,$args); $self->usage_error("No modification instructions given on command line") unless @$args or $opt->{save}; return; } sub opt_spec { my ( $class, $app ) = @_; return ( [ "backup:s" => "Create a backup of configuration files before saving." ], $class->cme_global_options, ); } sub usage_desc { my ($self) = @_; my $desc = $self->SUPER::usage_desc; # "%c COMMAND %o" return "$desc [application] [file ] instructions"; } sub description { my ($self) = @_; return $self->get_documentation; } sub execute { my ($self, $opt, $args) = @_; $opt->{_verbose} = 'Loader' if $opt->{verbose}; my ($model, $inst, $root) = $self->init_cme($opt,$args); # needed to create write_back subs $root->dump_tree() if $opt->{save} and not @$args; $root->load("@$args"); $root->deep_check; # consistency check $self->save($inst,$opt) ; return; } 1; __END__ =head1 SYNOPSIS # modify configuration with command line cme modify dpkg source 'format="(3.0) quilt"' =head1 DESCRIPTION Modify a configuration file with the values passed on the command line. These command must follow the syntax defined in L (which is similar to the output of L command) Example: cme modify dpkg 'source format="(3.0) quilt"' cme modify multistrap my_mstrap.conf 'sections:base source="http://ftp.fr.debian.org"' Some application like dpkg-copyright allows you to override the configuration file name. You must then use C<-file> option: cme modify dpkg-copyright -file ubuntu/copyright 'Comment="Silly example"' Finding the right instructions to perform a modification may be difficult when starting from scratch. To get started, you can run C command to get the content of your configuration in the syntax accepted by C: $ cme dump ssh -format cml Host:"*" - Host:"alioth.debian.org" User=dod - Host:"*.debian.org" IdentityFile:="~/.ssh/id_debian" User=dod - Then you can use this output to create instruction for a modification: $ cme modify ssh 'Host:"*" User=dod' Changes applied to ssh configuration: - Host:"*" User has new value: 'dod' =head1 Common options See L. =head1 options =over =item -savek Force a save even if no change was done. Useful to reformat the configuration file. =item -verbose Show effect of the modify instructions. =back =head1 SEE ALSO L =cut cme-1.041/lib/App/Cme/Command/run.pm000066400000000000000000000543751472041010100170010ustar00rootroot00000000000000# ABSTRACT: Run a cme script package App::Cme::Command::run ; use strict; use warnings; use v5.20; use File::HomeDir; use Path::Tiny; use Config::Model; use Log::Log4perl qw(get_logger :levels); use YAML::PP; use Encode qw(decode_utf8); use App::Cme -command ; use base qw/App::Cme::Common/; use feature qw/postderef signatures/; no warnings qw/experimental::postderef experimental::signatures experimental::smartmatch/; my $__test_home = ''; # used only by tests ## no critic (Subroutines::ProhibitUnusedPrivateSubroutines) sub _set_test_home { $__test_home = shift; return;} my $home = $__test_home || File::HomeDir->my_home; my @script_paths = map {path($_)} ( "$home/.cme/scripts", "/etc/cme/scripts/", ); push @script_paths, path($INC{"Config/Model.pm"})->parent->child("Model/scripts") ; sub opt_spec { my ( $class, $app ) = @_; return ( [ "arg=s@" => "script argument. run 'cme run