• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

GothenburgBitFactory / taskwarrior / 10152339701

29 Jul 2024 09:45PM UTC coverage: 84.437% (+0.07%) from 84.372%
10152339701

push

github

web-flow
Merge pull request #3566 from felixschurk/add-clang-format

Add clang-format to enforce style guide

12359 of 13760 new or added lines in 147 files covered. (89.82%)

123 existing lines in 42 files now uncovered.

19070 of 22585 relevant lines covered (84.44%)

19724.02 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.59
/src/commands/CmdDuplicate.cpp
1
////////////////////////////////////////////////////////////////////////////////
2
//
3
// Copyright 2006 - 2021, Tomas Babej, Paul Beckingham, Federico Hernandez.
4
//
5
// Permission is hereby granted, free of charge, to any person obtaining a copy
6
// of this software and associated documentation files (the "Software"), to deal
7
// in the Software without restriction, including without limitation the rights
8
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
// copies of the Software, and to permit persons to whom the Software is
10
// furnished to do so, subject to the following conditions:
11
//
12
// The above copyright notice and this permission notice shall be included
13
// in all copies or substantial portions of the Software.
14
//
15
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
16
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
// SOFTWARE.
22
//
23
// https://www.opensource.org/licenses/mit-license.php
24
//
25
////////////////////////////////////////////////////////////////////////////////
26

27
#include <cmake.h>
28
// cmake.h include header must come first
29

30
#include <CmdDuplicate.h>
31
#include <Context.h>
32
#include <Filter.h>
33
#include <format.h>
34
#include <main.h>
35
#include <util.h>
36

37
#include <iostream>
38

39
////////////////////////////////////////////////////////////////////////////////
40
CmdDuplicate::CmdDuplicate() {
4,389✔
41
  _keyword = "duplicate";
4,389✔
42
  _usage = "task <filter> duplicate <mods>";
4,389✔
43
  _description = "Duplicates the specified tasks";
4,389✔
44
  _read_only = false;
4,389✔
45
  _displays_id = false;
4,389✔
46
  _needs_gc = false;
4,389✔
47
  _uses_context = true;
4,389✔
48
  _accepts_filter = true;
4,389✔
49
  _accepts_modifications = true;
4,389✔
50
  _accepts_miscellaneous = false;
4,389✔
51
  _category = Command::Category::operation;
4,389✔
52
}
4,389✔
53

54
////////////////////////////////////////////////////////////////////////////////
55
int CmdDuplicate::execute(std::string&) {
7✔
56
  auto rc = 0;
7✔
57
  auto count = 0;
7✔
58

59
  // Apply filter.
60
  Filter filter;
7✔
61
  std::vector<Task> filtered;
7✔
62
  filter.subset(filtered);
7✔
63
  if (filtered.size() == 0) {
7✔
64
    Context::getContext().footnote("No tasks specified.");
1✔
65
    return 1;
1✔
66
  }
67

68
  // Accumulated project change notifications.
69
  std::map<std::string, std::string> projectChanges;
6✔
70

71
  for (auto& task : filtered) {
13✔
72
    // Duplicate the specified task.
73
    Task dup(task);
7✔
74
    dup.id = 0;               // Reset, and TDB2::add will set.
7✔
75
    dup.set("uuid", uuid());  // Needs a new UUID.
7✔
76
    dup.remove("start");      // Does not inherit start date.
7✔
77
    dup.remove("end");        // Does not inherit end date.
7✔
78
    dup.remove("entry");      // Does not inherit entry date.
7✔
79

80
    // When duplicating a child task, downgrade it to a plain task.
81
    if (dup.has("parent")) {
7✔
82
      dup.remove("parent");
1✔
83
      dup.remove("recur");
1✔
84
      dup.remove("until");
1✔
85
      dup.remove("imask");
1✔
86
      std::cout << format("Note: task {1} was a recurring task.  The duplicated task is not.",
2✔
87
                          task.identifier())
2✔
88
                << '\n';
1✔
89
    }
90

91
    // When duplicating a parent task, create a new parent task.
92
    else if (dup.getStatus() == Task::recurring) {
6✔
93
      dup.remove("mask");
1✔
94
      std::cout << format(
2✔
95
                       "Note: task {1} was a parent recurring task.  The duplicated task is too.",
96
                       task.identifier())
2✔
97
                << '\n';
1✔
98
    }
99

100
    dup.setStatus(Task::pending);  // Does not inherit status.
7✔
101
                                   // Must occur after Task::recurring check.
102

103
    dup.modify(Task::modAnnotate);
7✔
104

105
    if (permission(
7✔
106
            format("Duplicate task {1} '{2}'?", task.identifier(true), task.get("description")),
14✔
107
            filtered.size())) {
7✔
108
      Context::getContext().tdb2.add(dup);
7✔
109
      ++count;
7✔
110
      feedback_affected("Duplicated task {1} '{2}'.", task);
7✔
111

112
      auto status = dup.getStatus();
7✔
113
      if (Context::getContext().verbose("new-id") &&
8✔
114
          (status == Task::pending || status == Task::waiting))
1✔
115
        std::cout << format("Created task {1}.\n", dup.id);
5✔
116

117
      else if (Context::getContext().verbose("new-uuid") && status != Task::recurring)
2✔
118
        std::cout << format("Created task {1}.\n", dup.get("uuid"));
1✔
119

120
      if (Context::getContext().verbose("project"))
7✔
121
        projectChanges[task.get("project")] = onProjectChange(task);
6✔
122
    } else {
123
      std::cout << "Task not duplicated.\n";
×
124
      rc = 1;
×
NEW
125
      if (_permission_quit) break;
×
126
    }
127
  }
7✔
128

129
  // Now list the project changes.
130
  for (const auto& change : projectChanges)
11✔
131
    if (change.first != "") Context::getContext().footnote(change.second);
5✔
132

133
  feedback_affected(count == 1 ? "Duplicated {1} task." : "Duplicated {1} tasks.", count);
6✔
134

135
  return rc;
6✔
136
}
7✔
137

138
////////////////////////////////////////////////////////////////////////////////
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc