PreviousUpNext

15.4.737  src/lib/core/internal/versiontool.pkg

## versiontool.pkg
## Author: Matthias Blume (blume@tti-c.org)


#   A CM tool for automatically generating file version.pkg
#   from a template, incorporating current version and release.




###      "The good Christian should beware of mathematicians
###       and all those who make empty prophecies.  The danger
###       already exists that mathematicians have made a covenant
###       with the devil to darken the spirit and confine man in
###       the bonds of Hell."
###
###                             -- St. Augustine (354-430)


stipulate
    package fil =  file__premicrothread;                                # file__premicrothread  is from   src/lib/std/src/posix/file--premicrothread.pkg
herein

    package version_tool {
      with
        bump_release
            =
            REF (null_or::not_null (winix__premicrothread::process::get_env "VERSIONTOOL_BUMP_RELEASE"));

        fun get_version file
            =
            {   s =  fil::open_for_read  file;
                #
                case (fil::read_line  s)
                    #
                    THE l
                        =>
                        {   fil::close_input  s;
                            #
                            fl = string::tokens
                                     (\\ c =  char::is_space c   or   c == '.')
                                     l;

                            map
                                (\\ f =  the_else (int::from_string f, 0))
                                fl;
                        };

                    NULL => [0, 0];
                esac;
            }
            except
                _ = [0, 0];

        fun get_release file
            =
            {   s = fil::open_for_read  file;
                #
                case (fil::read_line  s)
                    #
                    THE l => { fil::close_input  s;   int::from_string l; };
                    NULL  => { fil::close_input  s;   NULL; };
                esac;
            }
            except
                _ = NULL;

        fun put_release (file, r)
            =
            {   s = fil::open  file;
                #
                fil::write (s, int::to_string r + "\n");

                fil::close  s;
            };

        fun bump_release_fn (file, r)
            =
            if   *bump_release
            then
                 put_release (file, r + 1);
            fi;

        fun gen { template, target, vfile, release }
            =
            {   version  =  get_version vfile;
                #
                version' =  case release
                                  NULL  =>  version;
                                  THE r =>  version @ [r];
                            esac;

                vstring =  string::join ", " (map int::to_string version');

                ss =  fil::open_for_read  template;
                ts =  fil::open  target;

                fun loop ()
                    =
                    case (fil::read_one  ss)
                        #
                        THE '%'
                            =>
                            case (fil::read_one  ss)
                                #
                                THE 'V' =>  {   fil::write (ts, vstring);
                                                loop ();
                                            };

                                THE 'F' =>  {   fil::write (ts, winix__premicrothread::path::file target);
                                                fil::write (ts, " generated from");
                                                loop ();
                                            };

                                THE c =>    {   fil::write_one (ts, c);
                                                loop ();
                                            };
                                NULL  =>        fil::write_one (ts, '%');
                            esac;

                        THE c => {   fil::write_one (ts, c);
                                     loop ();
                                 };

                        NULL => ();
                    esac;

               loop ();
               fil::close_input ss;
               fil::close ts;
            };

        tool = "versiontool";
        ilk  = "version";

        kw_target      = "target";
        kw_versionfile = "versionfile";
        kw_releasefile = "releasefile";

        keywords = [kw_target, kw_versionfile, kw_releasefile];

        fun versiontoolrule
                { spec: tools::Spec,
                  native2pathmaker,
                  context: tools::Rulecontext,
                  default_ilk_of,
                  sysinfo
                }
            :
            tools::Partial_Expansion
            =
            {   fun dogen (targetpp, versionfilepp, releasefilepp) ()
                    =
                    {   templatep = tools::srcpath (spec.make_path ());
                        targetp   = tools::srcpath targetpp;
                        target    = tools::native_spec targetp;
                        template  = tools::native_spec templatep;
                        vfile     = tools::native_pre_spec versionfilepp;
                        rfile     = tools::native_pre_spec releasefilepp;
                        release   = get_release rfile;

                        fun newer_than_target f
                            =
                            tools::outdated tool ([target], f);

                        if   list::exists newer_than_target [template, vfile, rfile]
                        then
                             gen { template, target, vfile, release };
                        fi;

                       bump_release_fn (rfile, the_else (release, -1));

                       ( { source_files =>  [ (targetp, { share       => sharing_mode::DONT_CARE,
                                                      setup       =>  (NULL, NULL),
                                                      split       =>  NULL,
                                                      noguid      =>  FALSE,
                                                      local       =>  FALSE,
                                                      controllers =>  []
                                                    }
                                          )
                                        ],
                           makelib_files  => [],
                           sources  => [ (templatep, { ilk,
                                                       derived => spec.derived }
                                         )
                                       ]
                         },
                         []
                       );
                    };

                fun complain l
                    =
                    raise exception tools::TOOL_ERROR { tool, msg => cat l };


                case spec.opts

                     NULL
                         =>
                         complain ["missing parameters"];

                     THE to
                         =>
                         {   my { matches, restoptions }
                                 =
                                 tools::parse_options { tool, keywords, options  => to };

                             fun match kw
                                 =
                                 case (matches kw)

                                      NULL
                                          =>
                                          complain ["missing parameter \"", kw, "\""];

                                      THE [tools::STRING { make_path, ... } ]
                                          =>
                                          make_path ();

                                      _   =>
                                          complain ["invalid parameter \"", kw, "\""];
                                 esac;

                             context (dogen (   match kw_target,
                                                match kw_versionfile,
                                                match kw_releasefile
                                            )
                                     );
                         };
                esac;
            };
      do
            bump_release = bump_release;
                                                               my _ = 
            tools::note_ilk (ilk, versiontoolrule);
      end;
    };
end;


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext