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

#include <bpkg/cfg-create>

#include <butl/fdstream>

#include <bpkg/package>
#include <bpkg/package-odb>
#include <bpkg/database>
#include <bpkg/diagnostics>

using namespace std;
using namespace butl;

namespace bpkg
{
  int
  cfg_create (const cfg_create_options& o, cli::scanner& args)
  {
    tracer trace ("cfg_create");

    if (o.wipe () && !o.directory_specified ())
      fail << "--wipe requires explicit --directory|-d";

    dir_path c (o.directory ());
    l4 ([&]{trace << "creating configuration in " << c;});

    // If the directory already exists, make sure it is empty. Otherwise
    // create it.
    //
    if (exists (c))
    {
      l5 ([&]{trace << "directory " << c << " exists";});

      if (!empty (c))
      {
        l5 ([&]{trace << "directory " << c << " not empty";});

        if (!o.wipe ())
          fail << "directory " << c << " is not empty" <<
            info << "use --wipe to clean it up but be careful";

        rm_r (c, false);
      }
    }
    else
    {
      l5 ([&]{trace << "directory " << c << " does not exist";});
      mk_p (c);
    }

    // Sort arguments into modules and configuration variables.
    //
    string mods;  // build2 create meta-operation parameters.
    strings vars;

    while (args.more ())
    {
      string a (args.next ());

      if (a.find ('=') != string::npos)
      {
        vars.push_back (move (a));
      }
      else if (!a.empty ())
      {
        mods += mods.empty () ? ", " : " ";
        mods += a;
      }
      else
        fail << "empty string as argument";
    }

    // Create and configure.
    //
    // Run quiet. Use path representation to get canonical trailing slash.
    //
    run_b (o,
           c,
           "create('" + c.representation () + "'" + mods + ")",
           true,
           vars);

    // Create .bpkg/.
    //
    mk (c / bpkg_dir);

    // Create the database.
    //
    database db (open (c, trace, true));

    // Add the special, root repository object with empty location.
    //
    transaction t (db.begin ());
    db.persist (repository (repository_location ()));
    t.commit ();

    if (verb)
    {
      c.complete ().normalize ();
      text << "created new configuration in " << c;
    }

    return 0;
  }
}