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

Tatsh / winprefs / 17633540827

11 Sep 2025 03:55AM UTC coverage: 99.552% (-0.03%) from 99.583%
17633540827

push

github

Tatsh
tests: fix

11 of 12 new or added lines in 3 files covered. (91.67%)

3112 of 3126 relevant lines covered (99.55%)

210.99 hits per line

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

96.0
/native/git.c
1
#include "git.h"
2
#include "constants.h"
3
#include "git_branch.h"
4

5
// This function does NOT escape double quotes. Inner double quotes must be escaped by the caller.
6
static inline bool run_process_no_window(int n_args, wchar_t *arg0, ...) {
39✔
7
    PROCESS_INFORMATION pi = {0};
39✔
8
    STARTUPINFO si = {.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES,
39✔
9
                      .wShowWindow = SW_HIDE};
10
    wchar_t cmd[32767];
11
    wmemset(cmd, L'\0', 32767);
39✔
12
    va_list args;
13
    va_start(args, arg0);
39✔
14
    wchar_t *cur;
15
    size_t i = 0;
39✔
16
    size_t req_size = (size_t)_snwprintf(nullptr, 0, L"\"%ls\" ", arg0);
39✔
17
    _snwprintf(cmd, req_size + 1, L"\"%ls\" ", arg0);
39✔
18
    i += req_size;
39✔
19
    int index = 0;
39✔
20
    for (index = 0; index < (n_args - 1); index++) {
179✔
21
        cur = va_arg(args, wchar_t *);
140✔
22
        if (!cur) { // LCOV_EXCL_START
23
            break;
24
        } // LCOV_EXCL_STOP
25
        req_size = (size_t)_snwprintf(nullptr, 0, L"\"%ls\" ", cur);
140✔
26
        _snwprintf(cmd + i, req_size + 1, L"\"%ls\" ", cur);
140✔
27
        i += req_size;
140✔
28
    }
29
    va_end(args);
39✔
30
    if (i >= 32767) { // LCOV_EXCL_START
31
        return false;
32
    } // LCOV_EXCL_STOP
33
    cmd[i - 1] = L'\0';
39✔
34
    debug_print(L"Executing: '%ls'\n", cmd);
39✔
35
    bool ret = CreateProcess(
39✔
36
        nullptr, cmd, nullptr, nullptr, false, CREATE_NO_WINDOW, nullptr, nullptr, &si, &pi);
37
    if (ret) {
39✔
38
        WaitForSingleObject(pi.hProcess, INFINITE);
33✔
39
        DWORD exit_code;
40
        bool result = GetExitCodeProcess(pi.hProcess, &exit_code);
33✔
41
        CloseHandle(pi.hProcess);
33✔
42
        CloseHandle(pi.hThread);
33✔
43
        if (!result) {
33✔
44
            debug_print(L"Failed to get exit code.\n");
1✔
45
            return false;
1✔
46
        }
47
        debug_print(L"Exit code: %lu\n", exit_code);
32✔
48
        return exit_code == 0;
32✔
49
    }
50
    return ret;
6✔
51
}
52

53
static inline bool has_git() {
16✔
54
    return run_process_no_window(2, L"git.exe", L"--version");
16✔
55
}
56

57
static inline bool dir_exists(wchar_t *path) {
15✔
58
    DWORD attrib = GetFileAttributes(path);
15✔
59
    return attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_DIRECTORY);
15✔
60
}
61

62
bool git_commit(const wchar_t *output_dir, const wchar_t *deploy_key) {
16✔
63
    bool ret = true;
16✔
64
    wchar_t *branch_arg, *cwd, *date_buf, *escaped_full_deploy_key_path, *git_dir, *git_dir_arg,
65
        *message_buf, *ssh_command, *time_buf, *work_tree_arg;
66
    branch_arg = cwd = date_buf = escaped_full_deploy_key_path = git_dir = git_dir_arg =
16✔
67
        message_buf = ssh_command = time_buf = work_tree_arg = nullptr;
16✔
68
    if (!has_git()) {
16✔
69
        debug_print(L"Wanted to commit but git.exe is not in PATH or failed to run.\n");
1✔
70
        goto cleanup;
1✔
71
    }
72
    debug_print(L"Committing changes.\n");
15✔
73
    size_t work_tree_arg_len = wcslen(output_dir) + wcslen(L"--work-tree=") + 1;
15✔
74
    work_tree_arg = calloc(work_tree_arg_len, WL);
15✔
75
    if (!work_tree_arg) { // LCOV_EXCL_START
76
        goto fail;
77
    } // LCOV_EXCL_STOP
78
    wmemset(work_tree_arg, L'\0', work_tree_arg_len);
15✔
79
    _snwprintf(work_tree_arg, work_tree_arg_len, L"--work-tree=%ls", output_dir);
15✔
80
    size_t git_dir_len = wcslen(output_dir) + wcslen(L"\\.git") + 1;
15✔
81
    git_dir = calloc(git_dir_len, WL);
15✔
82
    if (!git_dir) { // LCOV_EXCL_START
83
        goto fail;
84
    } // LCOV_EXCL_STOP
85
    _snwprintf(git_dir, git_dir_len, L"%ls\\.git", output_dir);
15✔
86
    git_dir[git_dir_len - 1] = L'\0';
15✔
87
    if (!dir_exists(git_dir)) {
15✔
88
        cwd = calloc(MAX_PATH, WL);
5✔
89
        if (!cwd) { // LCOV_EXCL_START
90
            goto fail;
91
        } // LCOV_EXCL_STOP
92
        wmemset(cwd, L'\0', MAX_PATH);
5✔
93
        if (!_wgetcwd(cwd, MAX_PATH) || _wchdir(output_dir) != 0 ||
5✔
94
            !run_process_no_window(3, L"git.exe", L"init", L"--quiet") || _wchdir(cwd) != 0) {
3✔
95
            goto fail;
5✔
96
        }
97
    }
98
    size_t git_dir_arg_len = git_dir_len + wcslen(L"--git-dir=") + 1;
10✔
99
    git_dir_arg = calloc(git_dir_arg_len, WL);
10✔
100
    if (!git_dir_arg) { // LCOV_EXCL_START
101
        goto fail;
102
    } // LCOV_EXCL_STOP
103
    wmemset(git_dir_arg, L'\0', git_dir_arg_len);
10✔
104
    _snwprintf(git_dir_arg, git_dir_arg_len, L"--git-dir=%ls", git_dir);
10✔
105
    git_dir_arg[git_dir_arg_len - 1] = L'\0';
10✔
106
    if (!run_process_no_window(5, L"git.exe", git_dir_arg, work_tree_arg, L"add", L".")) {
10✔
107
        goto fail;
1✔
108
    }
109
    size_t time_needed_size =
9✔
110
        (size_t)GetTimeFormat(LOCALE_USER_DEFAULT, 0, nullptr, nullptr, nullptr, 0);
9✔
111
    if (!time_needed_size) {
9✔
112
        goto fail;
1✔
113
    }
114
    time_buf = calloc(time_needed_size, WL);
8✔
115
    if (!time_buf) { // LCOV_EXCL_START
116
        goto fail;
117
    } // LCOV_EXCL_STOP
118
    if (!GetTimeFormat(LOCALE_USER_DEFAULT, 0, nullptr, nullptr, time_buf, (int)time_needed_size)) {
8✔
119
        goto fail;
1✔
120
    }
121
    size_t date_needed_size =
7✔
122
        (size_t)GetDateFormat(LOCALE_USER_DEFAULT, 0, nullptr, nullptr, nullptr, 0);
7✔
123
    if (!date_needed_size) {
7✔
124
        goto fail;
1✔
125
    }
126
    date_buf = calloc(date_needed_size, WL);
6✔
127
    if (!date_buf) { // LCOV_EXCL_START
128
        goto fail;
129
    } // LCOV_EXCL_STOP
130
    if (!GetDateFormat(LOCALE_USER_DEFAULT, 0, nullptr, nullptr, date_buf, (int)date_needed_size)) {
6✔
131
        goto fail;
1✔
132
    }
133
    size_t needed_size =
5✔
134
        wcslen(AUTOMATIC_COMMIT_MESSAGE_PREFIX) + 3 + time_needed_size + date_needed_size;
5✔
135
    message_buf = calloc(needed_size, WL);
5✔
136
    if (!message_buf) { // LCOV_EXCL_START
137
        goto fail;
138
    } // LCOV_EXCL_STOP
139
    wmemset(message_buf, L'\0', needed_size);
5✔
140
    _snwprintf(message_buf,
5✔
141
               needed_size,
142
               L"%ls%ls %ls",
143
               AUTOMATIC_COMMIT_MESSAGE_PREFIX,
144
               date_buf,
145
               time_buf);
146
    if (!run_process_no_window(10,
5✔
147
                               L"git.exe",
148
                               git_dir_arg,
149
                               work_tree_arg,
150
                               L"commit",
151
                               L"--no-gpg-sign",
152
                               L"--quiet",
153
                               L"--no-verify",
154
                               L"--author=winprefs <winprefs@tat.sh>",
155
                               L"-m",
156
                               message_buf)) {
157
        goto fail;
1✔
158
    }
159
    if (deploy_key) {
4✔
160
        wchar_t full_deploy_key_path[MAX_PATH];
161
        if (!_wfullpath(full_deploy_key_path, deploy_key, MAX_PATH)) {
4✔
162
            goto fail;
3✔
163
        }
164
        escaped_full_deploy_key_path = calloc(MAX_PATH + 2, WL);
3✔
165
        if (!escaped_full_deploy_key_path) { // LCOV_EXCL_START
166
            goto fail;
167
        } // LCOV_EXCL_STOP
168
        wmemset(escaped_full_deploy_key_path, L'\0', MAX_PATH + 2);
3✔
169
        escaped_full_deploy_key_path[0] = L'\'';
3✔
170
        int i, j = 1;
3✔
171
        for (i = 0; i < (int)wcslen(full_deploy_key_path) && j < MAX_PATH; i++, j++) {
3✔
172
            if (full_deploy_key_path[i] == L'\'') {
×
173
                if (j < (MAX_PATH - 1)) {
×
174
                    escaped_full_deploy_key_path[j++] = L'\\';
×
175
                } else { // LCOV_EXCL_START
176
                    break;
177
                } // LCOV_EXCL_STOP
178
            }
179
            escaped_full_deploy_key_path[j] = full_deploy_key_path[i];
×
180
        }
181
        escaped_full_deploy_key_path[j] = L'\'';
3✔
182
        debug_print(L"Deploy key: %ls\n", escaped_full_deploy_key_path);
3✔
183
        size_t ssh_command_len = 68 + wcslen(escaped_full_deploy_key_path) + 3;
3✔
184
        ssh_command = calloc(ssh_command_len, WL);
3✔
185
        if (!ssh_command) { // LCOV_EXCL_START
186
            goto fail;
187
        } // LCOV_EXCL_STOP
188
        wmemset(ssh_command, L'\0', ssh_command_len);
3✔
189
        _snwprintf(ssh_command,
3✔
190
                   ssh_command_len,
191
                   L"ssh -i %ls -F nul -o UserKnownHostsFile=nul -o StrictHostKeyChecking=no",
192
                   escaped_full_deploy_key_path);
193
        if (!run_process_no_window(6,
3✔
194
                                   L"git.exe",
195
                                   git_dir_arg,
196
                                   work_tree_arg,
197
                                   L"config",
198
                                   L"core.sshCommand",
199
                                   ssh_command)) {
200
            goto fail;
1✔
201
        }
202
        branch_arg = get_git_branch(git_dir_arg, git_dir_arg_len, work_tree_arg, work_tree_arg_len);
2✔
203
        if (!branch_arg) {
2✔
NEW
204
            goto fail;
×
205
        }
206
        if (!run_process_no_window(10,
2✔
207
                                   L"git.exe",
208
                                   git_dir_arg,
209
                                   work_tree_arg,
210
                                   L"push",
211
                                   L"-u",
212
                                   L"--porcelain",
213
                                   L"--no-signed",
214
                                   L"origin",
215
                                   L"origin",
216
                                   branch_arg)) {
217
            goto fail;
1✔
218
        }
219
    }
220
    goto cleanup;
1✔
221
fail:
14✔
222
    ret = false;
14✔
223
cleanup:
16✔
224
    free(branch_arg);
16✔
225
    free(cwd);
16✔
226
    free(date_buf);
16✔
227
    free(escaped_full_deploy_key_path);
16✔
228
    free(git_dir);
16✔
229
    free(git_dir_arg);
16✔
230
    free(message_buf);
16✔
231
    free(ssh_command);
16✔
232
    free(time_buf);
16✔
233
    free(work_tree_arg);
16✔
234
    return ret;
16✔
235
}
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

© 2026 Coveralls, Inc