aboutsummaryrefslogtreecommitdiff
path: root/bdep/config.cxx
blob: f7d74ed32594803fe36e1ef8e70e763e6afe5844 (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
// file      : bdep/config.cxx -*- C++ -*-
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license   : MIT; see accompanying LICENSE file

#include <bdep/config.hxx>

#include <bdep/database.hxx>
#include <bdep/project-odb.hxx>
#include <bdep/diagnostics.hxx>

using namespace std;

namespace bdep
{
  shared_ptr<configuration>
  cmd_config_add (const dir_path& prj,
                  database& db,
                  dir_path path,
                  optional<string> name,
                  optional<bool> def,
                  optional<uint64_t> id)
  {
    if (!exists (path))
      fail << "configuration directory " << path << " does not exist";

    transaction t (db.begin ());

    using count = configuration_count;
    using query = bdep::query<count>;

    // By default the first added configuration is the default.
    //
    if (!def)
      def = (db.query_value<count> () == 0);

    // Make sure the configuration path is absolute and normalized. Also
    // derive relative to project directory path is possible.
    //
    path.complete ();
    path.normalize ();

    optional<dir_path> rel_path;
    try {rel_path = path.relative (prj);} catch (const invalid_path&) {}

    shared_ptr<configuration> r (
      new configuration {
        id,
        name,
        path,
        move (rel_path),
        *def});

    try
    {
      db.persist (r);
    }
    catch (const odb::exception&)
    {
      // See if this is id, name, or path conflict.
      //
      if (id && db.query_value<count> (query::id == *id) != 0)
        fail << "configuration with id " << *id << " already exists "
             << "in project " << prj;

      if (name && db.query_value<count> (query::name == *name) != 0)
        fail << "configuration with name '" << *name << "' already exists "
             << "in project " << prj;

      if (db.query_value<count> (query::path == path.string ()) != 0)
        fail << "configuration with path " << path << " already exists "
             << "in project " << prj;

      // Hm, what could that be?
      //
      throw;
    }

    t.commit ();

    if (verb)
    {
      diag_record dr (text);
      /*            */ dr << "added configuration ";
      if (r->name)     dr << '@' << *r->name << ' ';
      /*            */ dr << r->path << " (" << *r->id;
      if (r->default_) dr << ", default";
      /*            */ dr << ')';
    }

    return r;
  }

  int
  cmd_config (const cmd_config_options& o, cli::scanner& args)
  {
    //@@ TODO: get subcommand and pass to tracer.

    tracer trace ("config");

    //@@ TODO: validate project/config options for subcommands.

    for (const string& n: o.config_name ())
      text << n;

    return 0;
  }
}