Merge bitcoin/bitcoin#24409: Always output license/copyright info with -version

5a89bed410 contrib: address gen-manpages feedback from #24263 (fanquake)
2618fb8d15 Output license info when binaries are passed -version (fanquake)
4c3e3c5746 refactor: shift CopyrightHolders() and LicenseInfo() to clientversion.cpp (fanquake)

Pull request description:

  Addresses a review comment from #24263, and addresses the [comment](https://github.com/bitcoin/bitcoin/pull/24263#issuecomment-1030582925) where it was pointed out that we are inconsistent with emitting  our copyright. After this change, the copyright is always emitted with `-version`, rather than `-help`, i.e:
  ```bash
  bitcoind -version

  Bitcoin Core version v22.99.0-fc1f355913f6-dirty
  Copyright (C) 2009-2022 The Bitcoin Core developers

  Please contribute if you find Bitcoin Core useful. Visit
  <https://bitcoincore.org/> for further information about the software.
  The source code is available from <https://github.com/bitcoin/bitcoin>.

  This is experimental software.
  Distributed under the MIT software license, see the accompanying file COPYING
  or <https://opensource.org/licenses/MIT>
  ```

  The info is also added to binaries other than `bitcoind`/`bitcoin-qt`. This change also prevents duplicate copyright info appearing in the `bitcoind` man page.

ACKs for top commit:
  laanwj:
    Tested ACK 5a89bed410

Tree-SHA512: 0ac2a1adf9e9de0c3206f35837008e3f93eaf15b193736203d71609273f0887cca20b8a90972cb9f941ebd62b330d61a0cbb5fb1b7a7f2dbc715ed8a0c1569d9
This commit is contained in:
MarcoFalke 2022-02-23 09:39:37 +01:00
commit 3c565302aa
No known key found for this signature in database
GPG key ID: CE2B75697E69A548
13 changed files with 68 additions and 55 deletions

View file

@ -32,7 +32,6 @@ mandir = os.getenv('MANDIR', os.path.join(topdir, 'doc/man'))
# Verify that all the required binaries are usable, and extract copyright # Verify that all the required binaries are usable, and extract copyright
# message in a first pass. # message in a first pass.
copyright = None
versions = [] versions = []
for relpath in BINARIES: for relpath in BINARIES:
abspath = os.path.join(builddir, relpath) abspath = os.path.join(builddir, relpath)
@ -42,18 +41,17 @@ for relpath in BINARIES:
print(f'{abspath} not found or not an executable', file=sys.stderr) print(f'{abspath} not found or not an executable', file=sys.stderr)
sys.exit(1) sys.exit(1)
# take first line (which must contain version) # take first line (which must contain version)
verstr = r.stdout.split('\n')[0] verstr = r.stdout.splitlines()[0]
# last word of line is the actual version e.g. v22.99.0-5c6b3d5b3508 # last word of line is the actual version e.g. v22.99.0-5c6b3d5b3508
verstr = verstr.split()[-1] verstr = verstr.split()[-1]
assert verstr.startswith('v') assert verstr.startswith('v')
# remaining lines are copyright
copyright = r.stdout.split('\n')[1:]
assert copyright[0].startswith('Copyright (C)')
# Only bitcoin-qt prints the copyright message on --version, so store it specifically. versions.append((abspath, verstr, copyright))
if relpath == 'src/qt/bitcoin-qt':
copyright = r.stdout.split('\n')[1:]
versions.append((abspath, verstr)) if any(verstr.endswith('-dirty') for (_, verstr, _) in versions):
if any(verstr.endswith('-dirty') for (_, verstr) in versions):
print("WARNING: Binaries were built from a dirty tree.") print("WARNING: Binaries were built from a dirty tree.")
print('man pages generated from dirty binaries should NOT be committed.') print('man pages generated from dirty binaries should NOT be committed.')
print('To properly generate man pages, please commit your changes (or discard them), rebuild, then run this script again.') print('To properly generate man pages, please commit your changes (or discard them), rebuild, then run this script again.')
@ -61,13 +59,13 @@ if any(verstr.endswith('-dirty') for (_, verstr) in versions):
with tempfile.NamedTemporaryFile('w', suffix='.h2m') as footer: with tempfile.NamedTemporaryFile('w', suffix='.h2m') as footer:
# Create copyright footer, and write it to a temporary include file. # Create copyright footer, and write it to a temporary include file.
assert copyright # Copyright is the same for all binaries, so just use the first.
footer.write('[COPYRIGHT]\n') footer.write('[COPYRIGHT]\n')
footer.write('\n'.join(copyright).strip()) footer.write('\n'.join(versions[0][2]).strip())
footer.flush() footer.flush()
# Call the binaries through help2man to produce a manual page for each of them. # Call the binaries through help2man to produce a manual page for each of them.
for (abspath, verstr) in versions: for (abspath, verstr, _) in versions:
outname = os.path.join(mandir, os.path.basename(abspath) + '.1') outname = os.path.join(mandir, os.path.basename(abspath) + '.1')
print(f'Generating {outname}') print(f'Generating {outname}')
subprocess.run([help2man, '-N', '--version-string=' + verstr, '--include=' + footer.name, '-o', outname, abspath], check=True) subprocess.run([help2man, '-N', '--version-string=' + verstr, '--include=' + footer.name, '-o', outname, abspath], check=True)

View file

@ -133,7 +133,10 @@ static int AppInitRPC(int argc, char* argv[])
} }
if (argc < 2 || HelpRequested(gArgs) || gArgs.IsArgSet("-version")) { if (argc < 2 || HelpRequested(gArgs) || gArgs.IsArgSet("-version")) {
std::string strUsage = PACKAGE_NAME " RPC client version " + FormatFullVersion() + "\n"; std::string strUsage = PACKAGE_NAME " RPC client version " + FormatFullVersion() + "\n";
if (!gArgs.IsArgSet("-version")) {
if (gArgs.IsArgSet("-version")) {
strUsage += FormatParagraph(LicenseInfo());
} else {
strUsage += "\n" strUsage += "\n"
"Usage: bitcoin-cli [options] <command> [params] Send command to " PACKAGE_NAME "\n" "Usage: bitcoin-cli [options] <command> [params] Send command to " PACKAGE_NAME "\n"
"or: bitcoin-cli [options] -named <command> [name=value]... Send command to " PACKAGE_NAME " (with named arguments)\n" "or: bitcoin-cli [options] -named <command> [name=value]... Send command to " PACKAGE_NAME " (with named arguments)\n"

View file

@ -102,7 +102,10 @@ static int AppInitRawTx(int argc, char* argv[])
if (argc < 2 || HelpRequested(gArgs) || gArgs.IsArgSet("-version")) { if (argc < 2 || HelpRequested(gArgs) || gArgs.IsArgSet("-version")) {
// First part of help message is specific to this utility // First part of help message is specific to this utility
std::string strUsage = PACKAGE_NAME " bitcoin-tx utility version " + FormatFullVersion() + "\n"; std::string strUsage = PACKAGE_NAME " bitcoin-tx utility version " + FormatFullVersion() + "\n";
if (!gArgs.IsArgSet("-version")) {
if (gArgs.IsArgSet("-version")) {
strUsage += FormatParagraph(LicenseInfo());
} else {
strUsage += "\n" strUsage += "\n"
"Usage: bitcoin-tx [options] <hex-tx> [commands] Update hex-encoded bitcoin transaction\n" "Usage: bitcoin-tx [options] <hex-tx> [commands] Update hex-encoded bitcoin transaction\n"
"or: bitcoin-tx [options] -create [commands] Create hex-encoded bitcoin transaction\n" "or: bitcoin-tx [options] -create [commands] Create hex-encoded bitcoin transaction\n"

View file

@ -53,7 +53,10 @@ static int AppInitUtil(ArgsManager& args, int argc, char* argv[])
if (HelpRequested(args) || args.IsArgSet("-version")) { if (HelpRequested(args) || args.IsArgSet("-version")) {
// First part of help message is specific to this utility // First part of help message is specific to this utility
std::string strUsage = PACKAGE_NAME " bitcoin-util utility version " + FormatFullVersion() + "\n"; std::string strUsage = PACKAGE_NAME " bitcoin-util utility version " + FormatFullVersion() + "\n";
if (!args.IsArgSet("-version")) {
if (args.IsArgSet("-version")) {
strUsage += FormatParagraph(LicenseInfo());
} else {
strUsage += "\n" strUsage += "\n"
"Usage: bitcoin-util [options] [commands] Do stuff\n"; "Usage: bitcoin-util [options] [commands] Do stuff\n";
strUsage += "\n" + args.GetHelpMessage(); strUsage += "\n" + args.GetHelpMessage();

View file

@ -59,7 +59,10 @@ static bool WalletAppInit(ArgsManager& args, int argc, char* argv[])
} }
if (argc < 2 || HelpRequested(args) || args.IsArgSet("-version")) { if (argc < 2 || HelpRequested(args) || args.IsArgSet("-version")) {
std::string strUsage = strprintf("%s bitcoin-wallet version", PACKAGE_NAME) + " " + FormatFullVersion() + "\n"; std::string strUsage = strprintf("%s bitcoin-wallet version", PACKAGE_NAME) + " " + FormatFullVersion() + "\n";
if (!args.IsArgSet("-version")) {
if (args.IsArgSet("-version")) {
strUsage += FormatParagraph(LicenseInfo());
} else {
strUsage += "\n" strUsage += "\n"
"bitcoin-wallet is an offline tool for creating and interacting with " PACKAGE_NAME " wallet files.\n" "bitcoin-wallet is an offline tool for creating and interacting with " PACKAGE_NAME " wallet files.\n"
"By default bitcoin-wallet will act on wallets in the default mainnet wallet directory in the datadir.\n" "By default bitcoin-wallet will act on wallets in the default mainnet wallet directory in the datadir.\n"

View file

@ -126,9 +126,10 @@ static bool AppInit(NodeContext& node, int argc, char* argv[])
if (HelpRequested(args) || args.IsArgSet("-version")) { if (HelpRequested(args) || args.IsArgSet("-version")) {
std::string strUsage = PACKAGE_NAME " version " + FormatFullVersion() + "\n"; std::string strUsage = PACKAGE_NAME " version " + FormatFullVersion() + "\n";
if (!args.IsArgSet("-version")) { if (args.IsArgSet("-version")) {
strUsage += FormatParagraph(LicenseInfo()) + "\n" strUsage += FormatParagraph(LicenseInfo());
"\nUsage: bitcoind [options] Start " PACKAGE_NAME "\n" } else {
strUsage += "\nUsage: bitcoind [options] Start " PACKAGE_NAME "\n"
"\n"; "\n";
strUsage += args.GetHelpMessage(); strUsage += args.GetHelpMessage();
} }

View file

@ -3,9 +3,13 @@
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <clientversion.h> #include <clientversion.h>
#include <util/translation.h>
#include <tinyformat.h> #include <tinyformat.h>
#include <sstream>
#include <string>
#include <vector>
/** /**
* Name of client reported in the 'version' message. Report the same name * Name of client reported in the 'version' message. Report the same name
@ -72,3 +76,32 @@ std::string FormatSubVersion(const std::string& name, int nClientVersion, const
ss << "/"; ss << "/";
return ss.str(); return ss.str();
} }
std::string CopyrightHolders(const std::string& strPrefix)
{
const auto copyright_devs = strprintf(_(COPYRIGHT_HOLDERS).translated, COPYRIGHT_HOLDERS_SUBSTITUTION);
std::string strCopyrightHolders = strPrefix + copyright_devs;
// Make sure Bitcoin Core copyright is not removed by accident
if (copyright_devs.find("Bitcoin Core") == std::string::npos) {
strCopyrightHolders += "\n" + strPrefix + "The Bitcoin Core developers";
}
return strCopyrightHolders;
}
std::string LicenseInfo()
{
const std::string URL_SOURCE_CODE = "<https://github.com/bitcoin/bitcoin>";
return CopyrightHolders(strprintf(_("Copyright (C) %i-%i").translated, 2009, COPYRIGHT_YEAR) + " ") + "\n" +
"\n" +
strprintf(_("Please contribute if you find %s useful. "
"Visit %s for further information about the software.").translated, PACKAGE_NAME, "<" PACKAGE_URL ">") +
"\n" +
strprintf(_("The source code is available from %s.").translated, URL_SOURCE_CODE) +
"\n" +
"\n" +
_("This is experimental software.").translated + "\n" +
strprintf(_("Distributed under the MIT software license, see the accompanying file %s or %s").translated, "COPYING", "<https://opensource.org/licenses/MIT>") +
"\n";
}

View file

@ -41,6 +41,11 @@ extern const std::string CLIENT_NAME;
std::string FormatFullVersion(); std::string FormatFullVersion();
std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector<std::string>& comments); std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector<std::string>& comments);
std::string CopyrightHolders(const std::string& strPrefix);
/** Returns licensing information (for -version) */
std::string LicenseInfo();
#endif // WINDRES_PREPROC #endif // WINDRES_PREPROC
#endif // BITCOIN_CLIENTVERSION_H #endif // BITCOIN_CLIENTVERSION_H

View file

@ -594,25 +594,6 @@ void SetupServerArgs(ArgsManager& argsman)
argsman.AddHiddenArgs(hidden_args); argsman.AddHiddenArgs(hidden_args);
} }
std::string LicenseInfo()
{
const std::string URL_SOURCE_CODE = "<https://github.com/bitcoin/bitcoin>";
return CopyrightHolders(strprintf(_("Copyright (C) %i-%i").translated, 2009, COPYRIGHT_YEAR) + " ") + "\n" +
"\n" +
strprintf(_("Please contribute if you find %s useful. "
"Visit %s for further information about the software.").translated,
PACKAGE_NAME, "<" PACKAGE_URL ">") +
"\n" +
strprintf(_("The source code is available from %s.").translated,
URL_SOURCE_CODE) +
"\n" +
"\n" +
_("This is experimental software.").translated + "\n" +
strprintf(_("Distributed under the MIT software license, see the accompanying file %s or %s").translated, "COPYING", "<https://opensource.org/licenses/MIT>") +
"\n";
}
static bool fHaveGenesis = false; static bool fHaveGenesis = false;
static Mutex g_genesis_wait_mutex; static Mutex g_genesis_wait_mutex;
static std::condition_variable g_genesis_wait_cv; static std::condition_variable g_genesis_wait_cv;

View file

@ -70,7 +70,4 @@ bool AppInitMain(node::NodeContext& node, interfaces::BlockAndHeaderTipInfo* tip
*/ */
void SetupServerArgs(ArgsManager& argsman); void SetupServerArgs(ArgsManager& argsman);
/** Returns licensing information (for -version) */
std::string LicenseInfo();
#endif // BITCOIN_INIT_H #endif // BITCOIN_INIT_H

View file

@ -1342,18 +1342,6 @@ int GetNumCores()
return std::thread::hardware_concurrency(); return std::thread::hardware_concurrency();
} }
std::string CopyrightHolders(const std::string& strPrefix)
{
const auto copyright_devs = strprintf(_(COPYRIGHT_HOLDERS).translated, COPYRIGHT_HOLDERS_SUBSTITUTION);
std::string strCopyrightHolders = strPrefix + copyright_devs;
// Make sure Bitcoin Core copyright is not removed by accident
if (copyright_devs.find("Bitcoin Core") == std::string::npos) {
strCopyrightHolders += "\n" + strPrefix + "The Bitcoin Core developers";
}
return strCopyrightHolders;
}
// Obtain the application startup time (used for uptime calculation) // Obtain the application startup time (used for uptime calculation)
int64_t GetStartupTime() int64_t GetStartupTime()
{ {

View file

@ -512,8 +512,6 @@ std::string HelpMessageOpt(const std::string& option, const std::string& message
*/ */
int GetNumCores(); int GetNumCores();
std::string CopyrightHolders(const std::string& strPrefix);
/** /**
* On platforms that support it, tell the kernel the calling thread is * On platforms that support it, tell the kernel the calling thread is
* CPU-intensive and non-interactive. See SCHED_BATCH in sched(7) for details. * CPU-intensive and non-interactive. See SCHED_BATCH in sched(7) for details.

View file

@ -16,7 +16,7 @@ FALSE_POSITIVES = [
("src/dbwrapper.cpp", "vsnprintf(p, limit - p, format, backup_ap)"), ("src/dbwrapper.cpp", "vsnprintf(p, limit - p, format, backup_ap)"),
("src/index/base.cpp", "FatalError(const char* fmt, const Args&... args)"), ("src/index/base.cpp", "FatalError(const char* fmt, const Args&... args)"),
("src/netbase.cpp", "LogConnectFailure(bool manual_connection, const char* fmt, const Args&... args)"), ("src/netbase.cpp", "LogConnectFailure(bool manual_connection, const char* fmt, const Args&... args)"),
("src/util/system.cpp", "strprintf(_(COPYRIGHT_HOLDERS).translated, COPYRIGHT_HOLDERS_SUBSTITUTION)"), ("src/clientversion.cpp", "strprintf(_(COPYRIGHT_HOLDERS).translated, COPYRIGHT_HOLDERS_SUBSTITUTION)"),
("src/validationinterface.cpp", "LogPrint(BCLog::VALIDATION, fmt \"\\n\", __VA_ARGS__)"), ("src/validationinterface.cpp", "LogPrint(BCLog::VALIDATION, fmt \"\\n\", __VA_ARGS__)"),
("src/wallet/wallet.h", "WalletLogPrintf(std::string fmt, Params... parameters)"), ("src/wallet/wallet.h", "WalletLogPrintf(std::string fmt, Params... parameters)"),
("src/wallet/wallet.h", "LogPrintf((\"%s \" + fmt).c_str(), GetDisplayName(), parameters...)"), ("src/wallet/wallet.h", "LogPrintf((\"%s \" + fmt).c_str(), GetDisplayName(), parameters...)"),