Git fork

Merge branch 'ps/meson-contrib-bits' into tz/doc-txt-to-adoc-fixes

* ps/meson-contrib-bits:
ci: exercise credential helpers
ci: fix propagating UTF-8 test locale in musl-based Meson job
meson: wire up static analysis via Coccinelle
meson: wire up git-contacts(1)
meson: wire up credential helpers
contrib/credential: fix compilation of "osxkeychain" helper
contrib/credential: fix compiling "libsecret" helper
contrib/credential: fix compilation of wincred helper with MSVC
contrib/credential: fix "netrc" tests with out-of-tree builds
GIT-BUILD-OPTIONS: propagate project's source directory

+229 -27
+1 -1
.github/workflows/main.yml
··· 265 265 run: pip install meson ninja 266 266 - name: Setup 267 267 shell: pwsh 268 - run: meson setup build -Dperl=disabled 268 + run: meson setup build -Dperl=disabled -Dcredential_helpers=wincred 269 269 - name: Compile 270 270 shell: pwsh 271 271 run: meson compile -C build
+1 -1
.gitlab-ci.yml
··· 164 164 extends: .msvc-meson 165 165 stage: build 166 166 script: 167 - - meson setup build -Dperl=disabled 167 + - meson setup build -Dperl=disabled -Dcredential_helpers=wincred 168 168 - meson compile -C build 169 169 artifacts: 170 170 paths:
+1 -2
GIT-BUILD-OPTIONS.in
··· 9 9 GIT_PERF_MAKE_OPTS=@GIT_PERF_MAKE_OPTS@ 10 10 GIT_PERF_REPEAT_COUNT=@GIT_PERF_REPEAT_COUNT@ 11 11 GIT_PERF_REPO=@GIT_PERF_REPO@ 12 + GIT_SOURCE_DIR=@GIT_SOURCE_DIR@ 12 13 GIT_TEST_CMP=@GIT_TEST_CMP@ 13 14 GIT_TEST_CMP_USE_COPIED_CONTEXT=@GIT_TEST_CMP_USE_COPIED_CONTEXT@ 14 15 GIT_TEST_GITPERLLIB=@GIT_TEST_GITPERLLIB@ 15 16 GIT_TEST_INDEX_VERSION=@GIT_TEST_INDEX_VERSION@ 16 - GIT_TEST_MERGE_TOOLS_DIR=@GIT_TEST_MERGE_TOOLS_DIR@ 17 17 GIT_TEST_OPTS=@GIT_TEST_OPTS@ 18 18 GIT_TEST_PERL_FATAL_WARNINGS=@GIT_TEST_PERL_FATAL_WARNINGS@ 19 - GIT_TEST_POPATH=@GIT_TEST_POPATH@ 20 19 GIT_TEST_TEMPLATE_DIR=@GIT_TEST_TEMPLATE_DIR@ 21 20 GIT_TEST_TEXTDOMAINDIR=@GIT_TEST_TEXTDOMAINDIR@ 22 21 GIT_TEST_UTF8_LOCALE=@GIT_TEST_UTF8_LOCALE@
+1 -2
Makefile
··· 3193 3193 -e "s|@GIT_PERF_MAKE_OPTS@|\'$(GIT_PERF_MAKE_OPTS)\'|" \ 3194 3194 -e "s|@GIT_PERF_REPEAT_COUNT@|\'$(GIT_PERF_REPEAT_COUNT)\'|" \ 3195 3195 -e "s|@GIT_PERF_REPO@|\'$(GIT_PERF_REPO)\'|" \ 3196 + -e "s|@GIT_SOURCE_DIR@|\'$(shell pwd)\'|" \ 3196 3197 -e "s|@GIT_TEST_CMP@|\'$(GIT_TEST_CMP)\'|" \ 3197 3198 -e "s|@GIT_TEST_CMP_USE_COPIED_CONTEXT@|\'$(GIT_TEST_CMP_USE_COPIED_CONTEXT)\'|" \ 3198 3199 -e "s|@GIT_TEST_GITPERLLIB@|\'$(shell pwd)/perl/build/lib\'|" \ 3199 3200 -e "s|@GIT_TEST_INDEX_VERSION@|\'$(GIT_TEST_INDEX_VERSION)\'|" \ 3200 - -e "s|@GIT_TEST_MERGE_TOOLS_DIR@|\'$(shell pwd)/mergetools\'|" \ 3201 3201 -e "s|@GIT_TEST_OPTS@|\'$(GIT_TEST_OPTS)\'|" \ 3202 3202 -e "s|@GIT_TEST_PERL_FATAL_WARNINGS@|\'$(GIT_TEST_PERL_FATAL_WARNINGS)\'|" \ 3203 - -e "s|@GIT_TEST_POPATH@|\'$(shell pwd)/po\'|" \ 3204 3203 -e "s|@GIT_TEST_TEMPLATE_DIR@|\'$(shell pwd)/templates/blt\'|" \ 3205 3204 -e "s|@GIT_TEST_TEXTDOMAINDIR@|\'$(shell pwd)/po/build/locale\'|" \ 3206 3205 -e "s|@GIT_TEST_UTF8_LOCALE@|\'$(GIT_TEST_UTF8_LOCALE)\'|" \
+1 -1
ci/install-dependencies.sh
··· 58 58 make libssl-dev libcurl4-openssl-dev libexpat-dev wget sudo default-jre \ 59 59 tcl tk gettext zlib1g-dev perl-modules liberror-perl libauthen-sasl-perl \ 60 60 libemail-valid-perl libio-pty-perl libio-socket-ssl-perl libnet-smtp-ssl-perl libdbd-sqlite3-perl libcgi-pm-perl \ 61 - libpcre2-dev meson ninja-build pkg-config \ 61 + libsecret-1-dev libpcre2-dev meson ninja-build pkg-config \ 62 62 ${CC_PACKAGE:-${CC:-gcc}} $PYTHON_PACKAGE 63 63 64 64 case "$distro" in
+8 -2
ci/lib.sh
··· 348 348 linux32) 349 349 CC=gcc 350 350 ;; 351 - linux-musl) 352 - MESONFLAGS="$MESONFLAGS -DGIT_TEST_UTF8_LOCALE=C.UTF-8" 351 + linux-meson) 352 + MESONFLAGS="$MESONFLAGS -Dcredential_helpers=libsecret,netrc" 353 + ;; 354 + linux-musl-meson) 355 + MESONFLAGS="$MESONFLAGS -Dtest_utf8_locale=C.UTF-8" 353 356 ;; 354 357 linux-leaks|linux-reftable-leaks) 355 358 export SANITIZE=leak ··· 358 361 export SANITIZE=address,undefined 359 362 export NO_SVN_TESTS=LetsSaveSomeTime 360 363 MAKEFLAGS="$MAKEFLAGS NO_PYTHON=YepBecauseP4FlakesTooOften" 364 + ;; 365 + osx-meson) 366 + MESONFLAGS="$MESONFLAGS -Dcredential_helpers=osxkeychain" 361 367 ;; 362 368 esac 363 369
+1 -2
contrib/buildsystems/CMakeLists.txt
··· 1169 1169 string(REPLACE "@GIT_PERF_MAKE_OPTS@" "" git_build_options "${git_build_options}") 1170 1170 string(REPLACE "@GIT_PERF_REPEAT_COUNT@" "" git_build_options "${git_build_options}") 1171 1171 string(REPLACE "@GIT_PERF_REPO@" "" git_build_options "${git_build_options}") 1172 + string(REPLACE "@GIT_SOURCE_DIR@" "${CMAKE_SOURCE_DIR}" git_build_options "${git_build_options}") 1172 1173 string(REPLACE "@GIT_TEST_CMP@" "" git_build_options "${git_build_options}") 1173 1174 string(REPLACE "@GIT_TEST_CMP_USE_COPIED_CONTEXT@" "" git_build_options "${git_build_options}") 1174 1175 string(REPLACE "@GIT_TEST_GITPERLLIB@" "'${CMAKE_BINARY_DIR}/perl/build/lib'" git_build_options "${git_build_options}") 1175 1176 string(REPLACE "@GIT_TEST_INDEX_VERSION@" "" git_build_options "${git_build_options}") 1176 - string(REPLACE "@GIT_TEST_MERGE_TOOLS_DIR@" "'${CMAKE_BINARY_DIR}/mergetools'" git_build_options "${git_build_options}") 1177 1177 string(REPLACE "@GIT_TEST_OPTS@" "" git_build_options "${git_build_options}") 1178 1178 string(REPLACE "@GIT_TEST_PERL_FATAL_WARNINGS@" "" git_build_options "${git_build_options}") 1179 - string(REPLACE "@GIT_TEST_POPATH@" "'${CMAKE_BINARY_DIR}/po'" git_build_options "${git_build_options}") 1180 1179 string(REPLACE "@GIT_TEST_TEMPLATE_DIR@" "'${CMAKE_BINARY_DIR}/templates/blt'" git_build_options "${git_build_options}") 1181 1180 string(REPLACE "@GIT_TEST_TEXTDOMAINDIR@" "'${CMAKE_BINARY_DIR}/po/build/locale'" git_build_options "${git_build_options}") 1182 1181 string(REPLACE "@GIT_TEST_UTF8_LOCALE@" "" git_build_options "${git_build_options}")
+89
contrib/coccinelle/meson.build
··· 1 + spatch = find_program('spatch', required: get_option('coccinelle')) 2 + if not spatch.found() 3 + subdir_done() 4 + endif 5 + 6 + third_party_sources = [ 7 + ':!contrib', 8 + ':!compat/inet_ntop.c', 9 + ':!compat/inet_pton.c', 10 + ':!compat/nedmalloc', 11 + ':!compat/obstack.*', 12 + ':!compat/poll', 13 + ':!compat/regex', 14 + ':!sha1collisiondetection', 15 + ':!sha1dc', 16 + ':!t/unit-tests/clar', 17 + ':!t/unit-tests/clar', 18 + ':!t/t[0-9][0-9][0-9][0-9]*', 19 + ] 20 + 21 + rules = [ 22 + 'array.cocci', 23 + 'commit.cocci', 24 + 'config_fn_ctx.pending.cocci', 25 + 'equals-null.cocci', 26 + 'flex_alloc.cocci', 27 + 'free.cocci', 28 + 'git_config_number.cocci', 29 + 'hashmap.cocci', 30 + 'index-compatibility.cocci', 31 + 'object_id.cocci', 32 + 'preincr.cocci', 33 + 'qsort.cocci', 34 + 'refs.cocci', 35 + 'strbuf.cocci', 36 + 'swap.cocci', 37 + 'the_repository.cocci', 38 + 'xcalloc.cocci', 39 + 'xopen.cocci', 40 + 'xstrdup_or_null.cocci', 41 + 'xstrncmpz.cocci', 42 + ] 43 + 44 + concatenated_rules = custom_target( 45 + command: [ 46 + 'cat', '@INPUT@', 47 + ], 48 + input: rules, 49 + output: 'rules.cocci', 50 + capture: true, 51 + ) 52 + 53 + sources = [ ] 54 + foreach source : run_command(git, '-C', meson.project_source_root(), 'ls-files', '--deduplicate', '*.c', third_party_sources, check: true).stdout().split() 55 + sources += source 56 + endforeach 57 + 58 + headers = [ ] 59 + foreach header : run_command(git, '-C', meson.project_source_root(), 'ls-files', '--deduplicate', '*.h', third_party_sources, check: true).stdout().split() 60 + headers += meson.project_source_root() / header 61 + endforeach 62 + 63 + patches = [ ] 64 + foreach source : sources 65 + patches += custom_target( 66 + command: [ 67 + spatch, 68 + '--all-includes', 69 + '--sp-file', concatenated_rules, 70 + '--patch', meson.project_source_root(), 71 + '@INPUT@', 72 + ], 73 + input: meson.project_source_root() / source, 74 + output: source.underscorify() + '.patch', 75 + capture: true, 76 + depend_files: headers, 77 + ) 78 + endforeach 79 + 80 + concatenated_patch = custom_target( 81 + command: [ 82 + 'cat', '@INPUT@', 83 + ], 84 + input: patches, 85 + output: 'cocci.patch', 86 + capture: true, 87 + ) 88 + 89 + alias_target('coccicheck', concatenated_patch)
+55
contrib/contacts/meson.build
··· 1 + custom_target( 2 + input: 'git-contacts', 3 + output: 'git-contacts', 4 + command: generate_perl_command, 5 + depends: [git_version_file], 6 + install: true, 7 + install_dir: get_option('libexecdir') / 'git-core', 8 + ) 9 + 10 + if get_option('docs').contains('man') 11 + contacts_xml = custom_target( 12 + command: asciidoc_common_options + [ 13 + '--backend=' + asciidoc_docbook, 14 + '--doctype=manpage', 15 + '--out-file=@OUTPUT@', 16 + '@INPUT@', 17 + ], 18 + depends: documentation_deps, 19 + input: 'git-contacts.txt', 20 + output: 'git-contacts.xml', 21 + ) 22 + 23 + custom_target( 24 + command: [ 25 + xmlto, 26 + '-m', '@INPUT@', 27 + 'man', 28 + contacts_xml, 29 + '-o', 30 + meson.current_build_dir(), 31 + ] + xmlto_extra, 32 + input: [ 33 + '../../Documentation/manpage-normal.xsl', 34 + ], 35 + output: 'git-contacts.1', 36 + install: true, 37 + install_dir: get_option('mandir') / 'man1', 38 + ) 39 + endif 40 + 41 + if get_option('docs').contains('html') 42 + custom_target( 43 + command: asciidoc_common_options + [ 44 + '--backend=' + asciidoc_html, 45 + '--doctype=manpage', 46 + '--out-file=@OUTPUT@', 47 + '@INPUT@', 48 + ], 49 + depends: documentation_deps, 50 + input: 'git-contacts.txt', 51 + output: 'git-contacts.html', 52 + install: true, 53 + install_dir: get_option('datadir') / 'doc/git-doc', 54 + ) 55 + endif
+5 -5
contrib/credential/libsecret/git-credential-libsecret.c
··· 59 59 /* ----------------- Secret Service functions ----------------- */ 60 60 61 61 static const SecretSchema schema = { 62 - "org.git.Password", 62 + .name = "org.git.Password", 63 63 /* Ignore schema name during search for backwards compatibility */ 64 - SECRET_SCHEMA_DONT_MATCH_NAME, 65 - { 64 + .flags = SECRET_SCHEMA_DONT_MATCH_NAME, 65 + .attributes = { 66 66 /* 67 67 * libsecret assumes attribute values are non-confidential and 68 68 * unchanging, so we can't include oauth_refresh_token or ··· 168 168 g_free(c->password); 169 169 c->password = g_strdup(""); 170 170 } 171 - for (int i = 1; i < g_strv_length(parts); i++) { 171 + for (guint i = 1; i < g_strv_length(parts); i++) { 172 172 if (g_str_has_prefix(parts[i], "password_expiry_utc=")) { 173 173 g_free(c->password_expiry_utc); 174 174 c->password_expiry_utc = g_strdup(&parts[i][20]); ··· 424 424 struct credential_operation const *try_op = credential_helper_ops; 425 425 struct credential cred = CREDENTIAL_INIT; 426 426 427 - if (!argv[1]) { 427 + if (argc < 2 || !*argv[1]) { 428 428 usage(argv[0]); 429 429 exit(EXIT_FAILURE); 430 430 }
+9
contrib/credential/libsecret/meson.build
··· 1 + executable('git-credential-libsecret', 2 + sources: 'git-credential-libsecret.c', 3 + dependencies: [ 4 + dependency('glib-2.0'), 5 + dependency('libsecret-1'), 6 + ], 7 + install: true, 8 + install_dir: get_option('libexecdir') / 'git-core', 9 + )
+3
contrib/credential/meson.build
··· 1 + foreach helper : get_option('credential_helpers') 2 + subdir(helper) 3 + endforeach
+20
contrib/credential/netrc/meson.build
··· 1 + credential_netrc = custom_target( 2 + input: 'git-credential-netrc.perl', 3 + output: 'git-credential-netrc', 4 + command: generate_perl_command, 5 + depends: [git_version_file], 6 + install: true, 7 + install_dir: get_option('libexecdir') / 'git-core', 8 + ) 9 + 10 + credential_netrc_testenv = test_environment 11 + credential_netrc_testenv.set('CREDENTIAL_NETRC_PATH', credential_netrc.full_path()) 12 + 13 + test('t-git-credential-netrc', 14 + shell, 15 + args: [ meson.current_source_dir() / 't-git-credential-netrc.sh' ], 16 + workdir: meson.current_source_dir(), 17 + env: credential_netrc_testenv, 18 + depends: test_dependencies + bin_wrappers + [credential_netrc], 19 + timeout: 0, 20 + )
+1 -1
contrib/credential/netrc/t-git-credential-netrc.sh
··· 15 15 16 16 export PERL5LIB="$GITPERLLIB" 17 17 test_expect_success 'git-credential-netrc' ' 18 - perl "$GIT_BUILD_DIR"/contrib/credential/netrc/test.pl 18 + perl "$GIT_SOURCE_DIR"/contrib/credential/netrc/test.pl 19 19 ' 20 20 21 21 test_done
+4 -3
contrib/credential/netrc/test.pl
··· 15 15 16 16 my @global_credential_args = @ARGV; 17 17 my $scriptDir = dirname rel2abs $0; 18 - my ($netrc, $netrcGpg, $gcNetrc) = map { catfile $scriptDir, $_; } 18 + my ($netrc, $netrcGpg) = map { catfile $scriptDir, $_; } 19 19 qw(test.netrc 20 - test.netrc.gpg 21 - git-credential-netrc); 20 + test.netrc.gpg); 21 + my $gcNetrc = $ENV{CREDENTIAL_NETRC_PATH} || catfile $scriptDir, qw(git-credential-netrc); 22 + 22 23 local $ENV{PATH} = join ':' 23 24 , $scriptDir 24 25 , $ENV{PATH}
+1 -1
contrib/credential/osxkeychain/git-credential-osxkeychain.c
··· 422 422 const char *usage = 423 423 "usage: git credential-osxkeychain <get|store|erase>"; 424 424 425 - if (!argv[1]) 425 + if (argc < 2 || !*argv[1]) 426 426 die("%s", usage); 427 427 428 428 if (open(argv[0], O_RDONLY | O_EXLOCK) == -1)
+9
contrib/credential/osxkeychain/meson.build
··· 1 + executable('git-credential-osxkeychain', 2 + sources: 'git-credential-osxkeychain.c', 3 + dependencies: [ 4 + dependency('CoreFoundation'), 5 + dependency('Security'), 6 + ], 7 + install: true, 8 + install_dir: get_option('libexecdir') / 'git-core', 9 + )
+2
contrib/credential/wincred/git-credential-wincred.c
··· 12 12 13 13 #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) 14 14 15 + #ifndef _MSC_VER 15 16 __attribute__((format (printf, 1, 2))) 17 + #endif 16 18 static void die(const char *err, ...) 17 19 { 18 20 char msg[4096];
+5
contrib/credential/wincred/meson.build
··· 1 + executable('git-credential-wincred', 2 + sources: 'git-credential-wincred.c', 3 + install: true, 4 + install_dir: get_option('libexecdir') / 'git-core', 5 + )
+3
contrib/meson.build
··· 1 1 foreach feature : get_option('contrib') 2 2 subdir(feature) 3 3 endforeach 4 + 5 + subdir('coccinelle') 6 + subdir('credential')
+2 -3
meson.build
··· 772 772 # features. It is optional if you want to neither execute tests nor use any of 773 773 # these optional features. 774 774 perl_required = get_option('perl') 775 - if get_option('tests') or get_option('gitweb').enabled() 775 + if get_option('tests') or get_option('gitweb').enabled() or 'netrc' in get_option('credential_helpers') 776 776 perl_required = true 777 777 endif 778 778 ··· 1976 1976 1977 1977 foreach key, value : { 1978 1978 'DIFF': diff.full_path(), 1979 + 'GIT_SOURCE_DIR': meson.project_source_root(), 1979 1980 'GIT_TEST_CMP': diff.full_path() + ' -u', 1980 1981 'GIT_TEST_GITPERLLIB': meson.project_build_root() / 'perl', 1981 - 'GIT_TEST_MERGE_TOOLS_DIR': meson.project_source_root() / 'mergetools', 1982 - 'GIT_TEST_POPATH': meson.project_source_root() / 'po', 1983 1982 'GIT_TEST_TEMPLATE_DIR': meson.project_build_root() / 'templates', 1984 1983 'GIT_TEST_TEXTDOMAINDIR': meson.project_build_root() / 'po', 1985 1984 'PAGER_ENV': get_option('pager_environment'),
+5 -1
meson_options.txt
··· 27 27 description: 'Version string reported by git-version(1) and other tools.') 28 28 29 29 # Features supported by Git. 30 - option('contrib', type: 'array', value: [ 'completion' ], choices: [ 'completion', 'subtree' ], 30 + option('contrib', type: 'array', value: [ 'completion' ], choices: [ 'completion', 'contacts', 'subtree' ], 31 + description: 'Contributed features to include.') 32 + option('credential_helpers', type: 'array', value: [ ], choices: [ 'libsecret', 'netrc', 'osxkeychain', 'wincred' ], 31 33 description: 'Contributed features to include.') 32 34 option('curl', type: 'feature', value: 'enabled', 33 35 description: 'Build helpers used to access remotes with the HTTP transport.') ··· 99 101 description: 'Which backend to use to generate documentation.') 100 102 101 103 # Testing. 104 + option('coccinelle', type: 'feature', value: 'auto', 105 + description: 'Provide a coccicheck target that generates a Coccinelle patch.') 102 106 option('tests', type: 'boolean', value: true, 103 107 description: 'Enable building tests. This requires Perl, but is separate from the "perl" option such that you can build tests without Perl features enabled.') 104 108 option('test_output_directory', type: 'string',
+1 -1
t/lib-gettext.sh
··· 7 7 . ./test-lib.sh 8 8 9 9 GIT_TEXTDOMAINDIR="$GIT_TEST_TEXTDOMAINDIR" 10 - GIT_PO_PATH="$GIT_TEST_POPATH" 10 + GIT_PO_PATH="$GIT_SOURCE_DIR/po" 11 11 export GIT_TEXTDOMAINDIR GIT_PO_PATH 12 12 13 13 if test -n "$GIT_TEST_INSTALLED"
+1 -1
t/t7609-mergetool--lib.sh
··· 7 7 . ./test-lib.sh 8 8 9 9 test_expect_success 'mergetool --tool=vimdiff creates the expected layout' ' 10 - . "$GIT_TEST_MERGE_TOOLS_DIR"/vimdiff && 10 + . "$GIT_SOURCE_DIR"/mergetools/vimdiff && 11 11 run_unit_tests 12 12 ' 13 13