1 //
2 //      aegis - project change supervisor
3 //      Copyright (C) 2005-2009, 2012 Peter Miller
4 //
5 //      This program is free software; you can redistribute it and/or modify
6 //      it under the terms of the GNU General Public License as published by
7 //      the Free Software Foundation; either version 3 of the License, or
8 //      (at your option) any later version.
9 //
10 //      This program is distributed in the hope that it will be useful,
11 //      but WITHOUT ANY WARRANTY; without even the implied warranty of
12 //      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 //      GNU General Public License for more details.
14 //
15 //      You should have received a copy of the GNU General Public License
16 //      along with this program. If not, see
17 //      <http://www.gnu.org/licenses/>.
18 //
19 
20 #include <common/ac/assert.h>
21 
22 #include <common/nstring/list.h>
23 #include <common/quit.h>
24 #include <common/trace.h>
25 #include <libaegis/arglex2.h>
26 #include <libaegis/attribute.h>
27 #include <libaegis/change.h>
28 #include <libaegis/change/identifier.h>
29 #include <libaegis/help.h>
30 #include <libaegis/sub.h>
31 
32 #include <aede-policy/policy.h>
33 #include <aede-policy/validation/list.h>
34 #include <aede-policy/usage.h>
35 
36 
37 static nstring
project_specific_find(change_identifier & cid,const char * name)38 project_specific_find(change_identifier &cid, const char *name)
39 {
40     pconf_ty *pconf_data = change_pconf_get(cid.get_cp(), 0);
41     assert(pconf_data);
42     attributes_ty *psp =
43         attributes_list_find(pconf_data->project_specific, name);
44     if (!psp)
45         return 0;
46     assert(psp->value);
47     return nstring(psp->value);
48 }
49 
50 
51 
52 void
policy()53 policy()
54 {
55     trace(("policy()\n{\n"));
56     change_identifier chg;
57     validation_list to_do;
58     arglex();
59     while (arglex_token != arglex_token_eoln)
60     {
61         switch (arglex_token)
62         {
63         default:
64             generic_argument(usage);
65             continue;
66 
67         case arglex_token_project:
68         case arglex_token_baseline:
69         case arglex_token_branch:
70         case arglex_token_change:
71         case arglex_token_delta:
72         case arglex_token_delta_date:
73         case arglex_token_delta_from_change:
74         case arglex_token_grandparent:
75         case arglex_token_number:
76         case arglex_token_trunk:
77             chg.command_line_parse(usage);
78             continue;
79 
80         case arglex_token_string:
81             to_do.push_back(validation::factory(arglex_value.alv_string));
82             break;
83         }
84         arglex();
85     }
86 
87     //
88     // If they didn't specify anything in particular,
89     // look in the project attributes.
90     //
91     if (to_do.empty())
92     {
93         nstring s = project_specific_find(chg, "aede-policy");
94         if (!s.empty())
95         {
96             nstring_list names;
97             names.split(s.trim(), " ");
98             for (size_t j = 0; j < names.size(); ++j)
99             {
100                 nstring name = names[j];
101                 to_do.push_back(validation::factory(name.c_str()));
102             }
103         }
104     }
105 
106     //
107     // If they didn't specify anything in particular,
108     // just check that the descriptions have been edited.
109     //
110     if (to_do.empty())
111         to_do.push_back(validation::factory("description"));
112 
113     //
114     // Make sure the change is in the "being developed" state.
115     // The aede-policy command makes no sense in any other state.
116     //
117     // If invoked in the "being integrated" state (common if aede-policy
118     // is invoked by the build command) then we do nothing.  The logic
119     // is that if it got past aede then the policy has changed in the
120     // mean time.
121     //
122     if (chg.get_cp()->is_being_integrated())
123         return;
124     if (!chg.get_cp()->is_being_developed())
125         change_fatal(chg.get_cp(), 0, i18n("bad de state"));
126 
127     //
128     // Perform all of the validations.
129     // If any of them fail, quit with a failure exit status.
130     //
131     bool ok = to_do.run(chg.get_cp());
132     if (!ok)
133         quit(1);
134     trace(("}\n"));
135 }
136 
137 
138 // vim: set ts=8 sw=4 et :
139