aboutsummaryrefslogtreecommitdiff
path: root/bdep/ci-parsers.cxx
blob: 2d19c4b8e5679c86a35a23872b3dba609eb56218 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
// file      : bdep/ci-parsers.cxx -*- C++ -*-
// copyright : Copyright (c) 2014-2019 Code Synthesis Ltd
// license   : MIT; see accompanying LICENSE file

#include <sstream>

#include <bdep/utility.hxx> // trim()

#include <bdep/ci-parsers.hxx>

#include <bdep/ci-options.hxx> // bdep::cli namespace

namespace bdep
{
  namespace cli
  {
    using namespace std;
    using namespace butl;

    void parser<ci_override>::
    parse (ci_override& r, bool& xs, scanner& s)
    {
      auto add = [&r] (string&& n, string&& v)
      {
        r.push_back (
          manifest_name_value {move (n),
                               move (v),
                               0, 0, 0, 0, 0, 0, 0}); // Locations, etc.
      };

      string o (s.next ());

      if (!s.more ())
        throw missing_value (o);

      string v (s.next ());

      if (o == "--build-email")
      {
        add ("build-email", move (v));
      }
      else if (o == "--builds")
      {
        add ("builds", move (v));
      }
      else if (o == "--override")
      {
        // Validate that the value has the <name>:<value> form.
        //
        // Note that the value semantics will be verified later, with the
        // package_manifest::verify_overrides() called on the final list.
        //
        size_t p (v.find (':'));

        if (p == string::npos)
          throw invalid_value (o, v, "missing ':'");

        string vn (v, 0, p);
        string vv (v, p + 1);

        // Let's trim the name and value in case they are copied from a
        // manifest file or similar.
        //
        trim (vn);
        trim (vv);

        if (vn.empty ())
          throw invalid_value (o, v, "empty value name");

        add (move (vn), move (vv));
      }
      else if (o == "--overrides-file")
      {
        // Parse the manifest file into the value list.
        //
        // Note that the values semantics will be verified later (see above).
        //
        try
        {
          ifdstream is (v);

          // In case we end up throwing invalid_value exception, its
          // description will mention the file path as an option value.
          // That's why we pass the empty name to the parser constructor not
          // to mention it twice.
          //
          manifest_parser p (is, "" /* name */);

          parse_manifest (p, r);
          is.close ();
        }
        catch (const manifest_parsing& e)
        {
          throw invalid_value (o,
                               v,
                               string ("unable to parse: ") + e.what ());
        }
        catch (const io_error& e)
        {
          // Sanitize the exception description.
          //
          ostringstream os;
          os << "unable to read: " << e;
          throw invalid_value (o, v, os.str ());
        }
      }
      else if (o == "--overrides") // Fake option.
      {
        throw unknown_option (o);
      }
      else
      {
        assert (false); // No other option is expected.
      }

      xs = true;
    }
  }
}