diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 5f756dfc2e..9959b61ece 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -265,7 +265,7 @@ jobs: run: pip install meson ninja - name: Setup shell: pwsh - run: meson setup build -Dperl=disabled + run: meson setup build -Dperl=disabled -Dcredential_helpers=wincred - name: Compile shell: pwsh run: meson compile -C build diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 86996fe941..ab2cbb4534 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -164,7 +164,7 @@ build:msvc-meson: extends: .msvc-meson stage: build script: - - meson setup build -Dperl=disabled -Dbackend_max_links=1 + - meson setup build -Dperl=disabled -Dbackend_max_links=1 -Dcredential_helpers=wincred - meson compile -C build artifacts: paths: diff --git a/GIT-BUILD-OPTIONS.in b/GIT-BUILD-OPTIONS.in index ada575fbcb..0a9884e0ad 100644 --- a/GIT-BUILD-OPTIONS.in +++ b/GIT-BUILD-OPTIONS.in @@ -9,14 +9,13 @@ GIT_PERF_MAKE_COMMAND=@GIT_PERF_MAKE_COMMAND@ GIT_PERF_MAKE_OPTS=@GIT_PERF_MAKE_OPTS@ GIT_PERF_REPEAT_COUNT=@GIT_PERF_REPEAT_COUNT@ GIT_PERF_REPO=@GIT_PERF_REPO@ +GIT_SOURCE_DIR=@GIT_SOURCE_DIR@ GIT_TEST_CMP=@GIT_TEST_CMP@ GIT_TEST_CMP_USE_COPIED_CONTEXT=@GIT_TEST_CMP_USE_COPIED_CONTEXT@ GIT_TEST_GITPERLLIB=@GIT_TEST_GITPERLLIB@ GIT_TEST_INDEX_VERSION=@GIT_TEST_INDEX_VERSION@ -GIT_TEST_MERGE_TOOLS_DIR=@GIT_TEST_MERGE_TOOLS_DIR@ GIT_TEST_OPTS=@GIT_TEST_OPTS@ GIT_TEST_PERL_FATAL_WARNINGS=@GIT_TEST_PERL_FATAL_WARNINGS@ -GIT_TEST_POPATH=@GIT_TEST_POPATH@ GIT_TEST_TEMPLATE_DIR=@GIT_TEST_TEMPLATE_DIR@ GIT_TEST_TEXTDOMAINDIR=@GIT_TEST_TEXTDOMAINDIR@ GIT_TEST_UTF8_LOCALE=@GIT_TEST_UTF8_LOCALE@ diff --git a/Makefile b/Makefile index 6d45093089..a9b2de0692 100644 --- a/Makefile +++ b/Makefile @@ -3193,14 +3193,13 @@ GIT-BUILD-OPTIONS: FORCE -e "s|@GIT_PERF_MAKE_OPTS@|\'$(GIT_PERF_MAKE_OPTS)\'|" \ -e "s|@GIT_PERF_REPEAT_COUNT@|\'$(GIT_PERF_REPEAT_COUNT)\'|" \ -e "s|@GIT_PERF_REPO@|\'$(GIT_PERF_REPO)\'|" \ + -e "s|@GIT_SOURCE_DIR@|\'$(shell pwd)\'|" \ -e "s|@GIT_TEST_CMP@|\'$(GIT_TEST_CMP)\'|" \ -e "s|@GIT_TEST_CMP_USE_COPIED_CONTEXT@|\'$(GIT_TEST_CMP_USE_COPIED_CONTEXT)\'|" \ -e "s|@GIT_TEST_GITPERLLIB@|\'$(shell pwd)/perl/build/lib\'|" \ -e "s|@GIT_TEST_INDEX_VERSION@|\'$(GIT_TEST_INDEX_VERSION)\'|" \ - -e "s|@GIT_TEST_MERGE_TOOLS_DIR@|\'$(shell pwd)/mergetools\'|" \ -e "s|@GIT_TEST_OPTS@|\'$(GIT_TEST_OPTS)\'|" \ -e "s|@GIT_TEST_PERL_FATAL_WARNINGS@|\'$(GIT_TEST_PERL_FATAL_WARNINGS)\'|" \ - -e "s|@GIT_TEST_POPATH@|\'$(shell pwd)/po\'|" \ -e "s|@GIT_TEST_TEMPLATE_DIR@|\'$(shell pwd)/templates/blt\'|" \ -e "s|@GIT_TEST_TEXTDOMAINDIR@|\'$(shell pwd)/po/build/locale\'|" \ -e "s|@GIT_TEST_UTF8_LOCALE@|\'$(GIT_TEST_UTF8_LOCALE)\'|" \ diff --git a/ci/install-dependencies.sh b/ci/install-dependencies.sh index 332ba96003..0df74610d0 100755 --- a/ci/install-dependencies.sh +++ b/ci/install-dependencies.sh @@ -58,7 +58,7 @@ ubuntu-*|i386/ubuntu-*|debian-*) make libssl-dev libcurl4-openssl-dev libexpat-dev wget sudo default-jre \ tcl tk gettext zlib1g-dev perl-modules liberror-perl libauthen-sasl-perl \ libemail-valid-perl libio-pty-perl libio-socket-ssl-perl libnet-smtp-ssl-perl libdbd-sqlite3-perl libcgi-pm-perl \ - libpcre2-dev meson ninja-build pkg-config \ + libsecret-1-dev libpcre2-dev meson ninja-build pkg-config \ ${CC_PACKAGE:-${CC:-gcc}} $PYTHON_PACKAGE case "$distro" in diff --git a/ci/lib.sh b/ci/lib.sh index 028fea0e7b..f561884d40 100755 --- a/ci/lib.sh +++ b/ci/lib.sh @@ -348,8 +348,11 @@ case "$jobname" in linux32) CC=gcc ;; -linux-musl) - MESONFLAGS="$MESONFLAGS -DGIT_TEST_UTF8_LOCALE=C.UTF-8" +linux-meson) + MESONFLAGS="$MESONFLAGS -Dcredential_helpers=libsecret,netrc" + ;; +linux-musl-meson) + MESONFLAGS="$MESONFLAGS -Dtest_utf8_locale=C.UTF-8" ;; linux-leaks|linux-reftable-leaks) export SANITIZE=leak @@ -359,6 +362,9 @@ linux-asan-ubsan) export NO_SVN_TESTS=LetsSaveSomeTime MAKEFLAGS="$MAKEFLAGS NO_PYTHON=YepBecauseP4FlakesTooOften" ;; +osx-meson) + MESONFLAGS="$MESONFLAGS -Dcredential_helpers=osxkeychain" + ;; esac MAKEFLAGS="$MAKEFLAGS CC=${CC:-cc}" diff --git a/contrib/buildsystems/CMakeLists.txt b/contrib/buildsystems/CMakeLists.txt index 3179e7ff7a..c6fbd57e15 100644 --- a/contrib/buildsystems/CMakeLists.txt +++ b/contrib/buildsystems/CMakeLists.txt @@ -1169,14 +1169,13 @@ string(REPLACE "@GIT_PERF_MAKE_COMMAND@" "" git_build_options "${git_build_optio string(REPLACE "@GIT_PERF_MAKE_OPTS@" "" git_build_options "${git_build_options}") string(REPLACE "@GIT_PERF_REPEAT_COUNT@" "" git_build_options "${git_build_options}") string(REPLACE "@GIT_PERF_REPO@" "" git_build_options "${git_build_options}") +string(REPLACE "@GIT_SOURCE_DIR@" "${CMAKE_SOURCE_DIR}" git_build_options "${git_build_options}") string(REPLACE "@GIT_TEST_CMP@" "" git_build_options "${git_build_options}") string(REPLACE "@GIT_TEST_CMP_USE_COPIED_CONTEXT@" "" git_build_options "${git_build_options}") string(REPLACE "@GIT_TEST_GITPERLLIB@" "'${CMAKE_BINARY_DIR}/perl/build/lib'" git_build_options "${git_build_options}") string(REPLACE "@GIT_TEST_INDEX_VERSION@" "" git_build_options "${git_build_options}") -string(REPLACE "@GIT_TEST_MERGE_TOOLS_DIR@" "'${CMAKE_BINARY_DIR}/mergetools'" git_build_options "${git_build_options}") string(REPLACE "@GIT_TEST_OPTS@" "" git_build_options "${git_build_options}") string(REPLACE "@GIT_TEST_PERL_FATAL_WARNINGS@" "" git_build_options "${git_build_options}") -string(REPLACE "@GIT_TEST_POPATH@" "'${CMAKE_BINARY_DIR}/po'" git_build_options "${git_build_options}") string(REPLACE "@GIT_TEST_TEMPLATE_DIR@" "'${CMAKE_BINARY_DIR}/templates/blt'" git_build_options "${git_build_options}") string(REPLACE "@GIT_TEST_TEXTDOMAINDIR@" "'${CMAKE_BINARY_DIR}/po/build/locale'" git_build_options "${git_build_options}") string(REPLACE "@GIT_TEST_UTF8_LOCALE@" "" git_build_options "${git_build_options}") diff --git a/contrib/coccinelle/meson.build b/contrib/coccinelle/meson.build new file mode 100644 index 0000000000..5d76a7fee6 --- /dev/null +++ b/contrib/coccinelle/meson.build @@ -0,0 +1,89 @@ +spatch = find_program('spatch', required: get_option('coccinelle')) +if not spatch.found() + subdir_done() +endif + +third_party_sources = [ + ':!contrib', + ':!compat/inet_ntop.c', + ':!compat/inet_pton.c', + ':!compat/nedmalloc', + ':!compat/obstack.*', + ':!compat/poll', + ':!compat/regex', + ':!sha1collisiondetection', + ':!sha1dc', + ':!t/unit-tests/clar', + ':!t/unit-tests/clar', + ':!t/t[0-9][0-9][0-9][0-9]*', +] + +rules = [ + 'array.cocci', + 'commit.cocci', + 'config_fn_ctx.pending.cocci', + 'equals-null.cocci', + 'flex_alloc.cocci', + 'free.cocci', + 'git_config_number.cocci', + 'hashmap.cocci', + 'index-compatibility.cocci', + 'object_id.cocci', + 'preincr.cocci', + 'qsort.cocci', + 'refs.cocci', + 'strbuf.cocci', + 'swap.cocci', + 'the_repository.cocci', + 'xcalloc.cocci', + 'xopen.cocci', + 'xstrdup_or_null.cocci', + 'xstrncmpz.cocci', +] + +concatenated_rules = custom_target( + command: [ + 'cat', '@INPUT@', + ], + input: rules, + output: 'rules.cocci', + capture: true, +) + +sources = [ ] +foreach source : run_command(git, '-C', meson.project_source_root(), 'ls-files', '--deduplicate', '*.c', third_party_sources, check: true).stdout().split() + sources += source +endforeach + +headers = [ ] +foreach header : run_command(git, '-C', meson.project_source_root(), 'ls-files', '--deduplicate', '*.h', third_party_sources, check: true).stdout().split() + headers += meson.project_source_root() / header +endforeach + +patches = [ ] +foreach source : sources + patches += custom_target( + command: [ + spatch, + '--all-includes', + '--sp-file', concatenated_rules, + '--patch', meson.project_source_root(), + '@INPUT@', + ], + input: meson.project_source_root() / source, + output: source.underscorify() + '.patch', + capture: true, + depend_files: headers, + ) +endforeach + +concatenated_patch = custom_target( + command: [ + 'cat', '@INPUT@', + ], + input: patches, + output: 'cocci.patch', + capture: true, +) + +alias_target('coccicheck', concatenated_patch) diff --git a/contrib/contacts/meson.build b/contrib/contacts/meson.build new file mode 100644 index 0000000000..6ec92f47c4 --- /dev/null +++ b/contrib/contacts/meson.build @@ -0,0 +1,55 @@ +custom_target( + input: 'git-contacts', + output: 'git-contacts', + command: generate_perl_command, + depends: [git_version_file], + install: true, + install_dir: get_option('libexecdir') / 'git-core', +) + +if get_option('docs').contains('man') + contacts_xml = custom_target( + command: asciidoc_common_options + [ + '--backend=' + asciidoc_docbook, + '--doctype=manpage', + '--out-file=@OUTPUT@', + '@INPUT@', + ], + depends: documentation_deps, + input: 'git-contacts.txt', + output: 'git-contacts.xml', + ) + + custom_target( + command: [ + xmlto, + '-m', '@INPUT@', + 'man', + contacts_xml, + '-o', + meson.current_build_dir(), + ] + xmlto_extra, + input: [ + '../../Documentation/manpage-normal.xsl', + ], + output: 'git-contacts.1', + install: true, + install_dir: get_option('mandir') / 'man1', + ) +endif + +if get_option('docs').contains('html') + custom_target( + command: asciidoc_common_options + [ + '--backend=' + asciidoc_html, + '--doctype=manpage', + '--out-file=@OUTPUT@', + '@INPUT@', + ], + depends: documentation_deps, + input: 'git-contacts.txt', + output: 'git-contacts.html', + install: true, + install_dir: get_option('datadir') / 'doc/git-doc', + ) +endif diff --git a/contrib/credential/libsecret/git-credential-libsecret.c b/contrib/credential/libsecret/git-credential-libsecret.c index 90034d0cf1..941b2afd5e 100644 --- a/contrib/credential/libsecret/git-credential-libsecret.c +++ b/contrib/credential/libsecret/git-credential-libsecret.c @@ -59,10 +59,10 @@ static void credential_clear(struct credential *c); /* ----------------- Secret Service functions ----------------- */ static const SecretSchema schema = { - "org.git.Password", + .name = "org.git.Password", /* Ignore schema name during search for backwards compatibility */ - SECRET_SCHEMA_DONT_MATCH_NAME, - { + .flags = SECRET_SCHEMA_DONT_MATCH_NAME, + .attributes = { /* * libsecret assumes attribute values are non-confidential and * unchanging, so we can't include oauth_refresh_token or @@ -168,7 +168,7 @@ static int keyring_get(struct credential *c) g_free(c->password); c->password = g_strdup(""); } - for (int i = 1; i < g_strv_length(parts); i++) { + for (guint i = 1; i < g_strv_length(parts); i++) { if (g_str_has_prefix(parts[i], "password_expiry_utc=")) { g_free(c->password_expiry_utc); c->password_expiry_utc = g_strdup(&parts[i][20]); @@ -424,7 +424,7 @@ int main(int argc, char *argv[]) struct credential_operation const *try_op = credential_helper_ops; struct credential cred = CREDENTIAL_INIT; - if (!argv[1]) { + if (argc < 2 || !*argv[1]) { usage(argv[0]); exit(EXIT_FAILURE); } diff --git a/contrib/credential/libsecret/meson.build b/contrib/credential/libsecret/meson.build new file mode 100644 index 0000000000..0137660fe0 --- /dev/null +++ b/contrib/credential/libsecret/meson.build @@ -0,0 +1,9 @@ +executable('git-credential-libsecret', + sources: 'git-credential-libsecret.c', + dependencies: [ + dependency('glib-2.0'), + dependency('libsecret-1'), + ], + install: true, + install_dir: get_option('libexecdir') / 'git-core', +) diff --git a/contrib/credential/meson.build b/contrib/credential/meson.build new file mode 100644 index 0000000000..4216296ae0 --- /dev/null +++ b/contrib/credential/meson.build @@ -0,0 +1,3 @@ +foreach helper : get_option('credential_helpers') + subdir(helper) +endforeach diff --git a/contrib/credential/netrc/meson.build b/contrib/credential/netrc/meson.build new file mode 100644 index 0000000000..a990dbb86d --- /dev/null +++ b/contrib/credential/netrc/meson.build @@ -0,0 +1,20 @@ +credential_netrc = custom_target( + input: 'git-credential-netrc.perl', + output: 'git-credential-netrc', + command: generate_perl_command, + depends: [git_version_file], + install: true, + install_dir: get_option('libexecdir') / 'git-core', +) + +credential_netrc_testenv = test_environment +credential_netrc_testenv.set('CREDENTIAL_NETRC_PATH', credential_netrc.full_path()) + +test('t-git-credential-netrc', + shell, + args: [ meson.current_source_dir() / 't-git-credential-netrc.sh' ], + workdir: meson.current_source_dir(), + env: credential_netrc_testenv, + depends: test_dependencies + bin_wrappers + [credential_netrc], + timeout: 0, +) diff --git a/contrib/credential/netrc/t-git-credential-netrc.sh b/contrib/credential/netrc/t-git-credential-netrc.sh index bf2777308a..1b7b8b3a9a 100755 --- a/contrib/credential/netrc/t-git-credential-netrc.sh +++ b/contrib/credential/netrc/t-git-credential-netrc.sh @@ -15,7 +15,7 @@ export PERL5LIB="$GITPERLLIB" test_expect_success 'git-credential-netrc' ' - perl "$GIT_BUILD_DIR"/contrib/credential/netrc/test.pl + perl "$GIT_SOURCE_DIR"/contrib/credential/netrc/test.pl ' test_done diff --git a/contrib/credential/netrc/test.pl b/contrib/credential/netrc/test.pl index c0fb3718b2..67a0ede564 100755 --- a/contrib/credential/netrc/test.pl +++ b/contrib/credential/netrc/test.pl @@ -15,10 +15,11 @@ BEGIN { my @global_credential_args = @ARGV; my $scriptDir = dirname rel2abs $0; -my ($netrc, $netrcGpg, $gcNetrc) = map { catfile $scriptDir, $_; } +my ($netrc, $netrcGpg) = map { catfile $scriptDir, $_; } qw(test.netrc - test.netrc.gpg - git-credential-netrc); + test.netrc.gpg); +my $gcNetrc = $ENV{CREDENTIAL_NETRC_PATH} || catfile $scriptDir, qw(git-credential-netrc); + local $ENV{PATH} = join ':' , $scriptDir , $ENV{PATH} diff --git a/contrib/credential/osxkeychain/git-credential-osxkeychain.c b/contrib/credential/osxkeychain/git-credential-osxkeychain.c index 1c8310d7fe..611c9798b3 100644 --- a/contrib/credential/osxkeychain/git-credential-osxkeychain.c +++ b/contrib/credential/osxkeychain/git-credential-osxkeychain.c @@ -422,7 +422,7 @@ int main(int argc, const char **argv) const char *usage = "usage: git credential-osxkeychain "; - if (!argv[1]) + if (argc < 2 || !*argv[1]) die("%s", usage); if (open(argv[0], O_RDONLY | O_EXLOCK) == -1) diff --git a/contrib/credential/osxkeychain/meson.build b/contrib/credential/osxkeychain/meson.build new file mode 100644 index 0000000000..3c7677f736 --- /dev/null +++ b/contrib/credential/osxkeychain/meson.build @@ -0,0 +1,9 @@ +executable('git-credential-osxkeychain', + sources: 'git-credential-osxkeychain.c', + dependencies: [ + dependency('CoreFoundation'), + dependency('Security'), + ], + install: true, + install_dir: get_option('libexecdir') / 'git-core', +) diff --git a/contrib/credential/wincred/git-credential-wincred.c b/contrib/credential/wincred/git-credential-wincred.c index 4be0d58cd8..04145b5118 100644 --- a/contrib/credential/wincred/git-credential-wincred.c +++ b/contrib/credential/wincred/git-credential-wincred.c @@ -12,7 +12,9 @@ #define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) +#ifndef _MSC_VER __attribute__((format (printf, 1, 2))) +#endif static void die(const char *err, ...) { char msg[4096]; diff --git a/contrib/credential/wincred/meson.build b/contrib/credential/wincred/meson.build new file mode 100644 index 0000000000..6de23ca17d --- /dev/null +++ b/contrib/credential/wincred/meson.build @@ -0,0 +1,5 @@ +executable('git-credential-wincred', + sources: 'git-credential-wincred.c', + install: true, + install_dir: get_option('libexecdir') / 'git-core', +) diff --git a/contrib/meson.build b/contrib/meson.build index d74b64a518..a88c5dfe09 100644 --- a/contrib/meson.build +++ b/contrib/meson.build @@ -1,3 +1,6 @@ foreach feature : get_option('contrib') subdir(feature) endforeach + +subdir('coccinelle') +subdir('credential') diff --git a/meson.build b/meson.build index 516207f9cf..e86085b0a4 100644 --- a/meson.build +++ b/meson.build @@ -772,7 +772,7 @@ endif # features. It is optional if you want to neither execute tests nor use any of # these optional features. perl_required = get_option('perl') -if get_option('tests') or get_option('gitweb').enabled() +if get_option('tests') or get_option('gitweb').enabled() or 'netrc' in get_option('credential_helpers') perl_required = true endif @@ -1968,10 +1968,9 @@ subdir('contrib') foreach key, value : { 'DIFF': diff.full_path(), + 'GIT_SOURCE_DIR': meson.project_source_root(), 'GIT_TEST_CMP': diff.full_path() + ' -u', 'GIT_TEST_GITPERLLIB': meson.project_build_root() / 'perl', - 'GIT_TEST_MERGE_TOOLS_DIR': meson.project_source_root() / 'mergetools', - 'GIT_TEST_POPATH': meson.project_source_root() / 'po', 'GIT_TEST_TEMPLATE_DIR': meson.project_build_root() / 'templates', 'GIT_TEST_TEXTDOMAINDIR': meson.project_build_root() / 'po', 'PAGER_ENV': get_option('pager_environment'), diff --git a/meson_options.txt b/meson_options.txt index 9e81379099..78d172a740 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -27,7 +27,9 @@ option('version', type: 'string', value: '', description: 'Version string reported by git-version(1) and other tools.') # Features supported by Git. -option('contrib', type: 'array', value: [ 'completion' ], choices: [ 'completion', 'subtree' ], +option('contrib', type: 'array', value: [ 'completion' ], choices: [ 'completion', 'contacts', 'subtree' ], + description: 'Contributed features to include.') +option('credential_helpers', type: 'array', value: [ ], choices: [ 'libsecret', 'netrc', 'osxkeychain', 'wincred' ], description: 'Contributed features to include.') option('curl', type: 'feature', value: 'enabled', description: 'Build helpers used to access remotes with the HTTP transport.') @@ -99,6 +101,8 @@ option('docs_backend', type: 'combo', choices: ['asciidoc', 'asciidoctor', 'auto description: 'Which backend to use to generate documentation.') # Testing. +option('coccinelle', type: 'feature', value: 'auto', + description: 'Provide a coccicheck target that generates a Coccinelle patch.') option('tests', type: 'boolean', value: true, description: 'Enable building tests. This requires Perl, but is separate from the "perl" option such that you can build tests without Perl features enabled.') option('test_output_directory', type: 'string', diff --git a/t/lib-gettext.sh b/t/lib-gettext.sh index 7a734c6973..b3dd68b0b9 100644 --- a/t/lib-gettext.sh +++ b/t/lib-gettext.sh @@ -7,7 +7,7 @@ . ./test-lib.sh GIT_TEXTDOMAINDIR="$GIT_TEST_TEXTDOMAINDIR" -GIT_PO_PATH="$GIT_TEST_POPATH" +GIT_PO_PATH="$GIT_SOURCE_DIR/po" export GIT_TEXTDOMAINDIR GIT_PO_PATH if test -n "$GIT_TEST_INSTALLED" diff --git a/t/t7609-mergetool--lib.sh b/t/t7609-mergetool--lib.sh index e8e205707e..af3ad284ee 100755 --- a/t/t7609-mergetool--lib.sh +++ b/t/t7609-mergetool--lib.sh @@ -7,7 +7,7 @@ Testing basic merge tools options' . ./test-lib.sh test_expect_success 'mergetool --tool=vimdiff creates the expected layout' ' - . "$GIT_TEST_MERGE_TOOLS_DIR"/vimdiff && + . "$GIT_SOURCE_DIR"/mergetools/vimdiff && run_unit_tests '