| # -*- coding: utf-8 -*- |
| # Copyright (c) 2012 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """Generate an HTML file containing license info for all installed packages. |
| |
| Documentation on this script is also available here: |
| http://www.chromium.org/chromium-os/licensing-for-chromiumos-developers |
| |
| End user (i.e. package owners) documentation is here: |
| http://www.chromium.org/chromium-os/licensing-for-chromiumos-package-owners |
| |
| Usage: |
| For this script to work, you must have built the architecture |
| this is being run against, _after_ you've last run repo sync. |
| Otherwise, it will query newer source code and then fail to work on packages |
| that are out of date in your build. |
| |
| Recommended build: |
| cros_sdk |
| export BOARD=x86-alex |
| sudo rm -rf /build/$BOARD |
| cd ~/trunk/src/scripts |
| # If you wonder why we need to build Chromium OS just to run |
| # `emerge -p -v virtual/target-os` on it, we don't. |
| # However, later we run ebuild unpack, and this will apply patches and run |
| # configure. Configure will fail due to aclocal macros missing in |
| # /build/x86-alex/usr/share/aclocal (those are generated during build). |
| # This will take about 10mn on a Z620. |
| ./build_packages --board=$BOARD --nowithautotest --nowithtest --nowithdev |
| --nowithfactory |
| cd ~/trunk/chromite/licensing |
| # This removes left over packages from an earlier build that could cause |
| # conflicts. |
| eclean-$BOARD packages |
| %(prog)s [--debug] [--all-packages] --board $BOARD [-o o.html] 2>&1 | tee out |
| |
| The workflow above is what you would do to generate a licensing file by hand |
| given a chromeos tree. |
| Note that building packages now creates a license.yaml fork in the package |
| which you can see with |
| qtbz2 -x -O /build/x86-alex/packages/dev-util/libc-bench-0.0.1-r8.tbz2 | |
| qxpak -x -O - license.yaml |
| This gets automatically installed in |
| /build/x86-alex/var/db/pkg/dev-util/libc-bench-0.0.1-r8/license.yaml |
| |
| Unless you run with --generate, the script will now gather those license |
| bits and generate a license file from there. |
| License bits for each package are generated by default from |
| src/scripts/hooks/install/gen-package-licenses.sh which gets run automatically |
| by emerge as part of a package build (by running this script with |
| --hook /path/to/tmp/portage/build/tree/for/that/package |
| |
| If license bits are missing, they are generated on the fly if you were running |
| with sudo. If you didn't use sudo, this on the fly late generation will fail |
| and act as a warning that your prebuilts were missing package build time |
| licenses. |
| |
| You can check the licenses and/or generate a HTML file for a list of |
| packages using --package or -p: |
| %(prog)s --package "dev-libs/libatomic_ops-7.2d" --package |
| "net-misc/wget-1.14" --board $BOARD -o out.html |
| |
| Note that you'll want to use --generate to force regeneration of the licensing |
| bits from a package source you may have just modified but not rebuilt. |
| |
| If you want to check licensing against all ChromeOS packages, you should |
| run ./build_packages --board=$BOARD to build everything and then run |
| this script with --all-packages. |
| |
| By default, when no package is specified, this script processes all |
| packages for $BOARD. The output HTML file is meant to update |
| http://src.chromium.org/viewvc/chrome/trunk/src/chrome/browser/resources/ + |
| chromeos/about_os_credits.html?view=log |
| (gclient config svn://svn.chromium.org/chrome/trunk/src) |
| For an example CL, see https://codereview.chromium.org/13496002/ |
| |
| The detailed process is listed below. |
| |
| * Check out the branch you intend to generate the HTML file for. Use |
| the internal manifest for this purpose. |
| repo init -b <branch_name> -u <URL> |
| |
| The list of branches (e.g. release-R33-5116.B) are available here: |
| https://chromium.googlesource.com/chromiumos/manifest/+refs |
| |
| * Generate the HTML file by following the steps mentioned |
| previously. Check whether your changes are valid with: |
| bin/diff_license_html output.html-M33 output.html-M34 |
| and review the diff. |
| |
| * Update the about_os_credits.html in the svn repository. Create a CL |
| and upload it for review. |
| gcl change <change_name> |
| gcl upload <change_name> |
| |
| When uploading, you may get a warning for file being too large to |
| upload. In this case, your CL can still be reviewed. Always include |
| the diff in your commit message so that the reviewers know what the |
| changes are. You can add reviewers on the review page by clicking on |
| "Edit issue". (A quick reference: |
| http://www.chromium.org/developers/quick-reference) |
| |
| Make sure you click on 'Publish+Mail Comments' after adding reviewers |
| (the review URL looks like this https://codereview.chromium.org/183883018/ ). |
| |
| * After receiving LGTMs, commit your change with 'gcl commit <change_name>'. |
| |
| If you don't get this in before the freeze window, it'll need to be merged into |
| the branch being released, which is done by adding a Merge-Requested label. |
| Once it's been updated to "Merge-Approved" by a TPM, please merge into the |
| required release branch. You can ask karen@ for merge approve help. |
| Example: http://crbug.com/221281 |
| |
| Note however that this is only during the transition period. |
| build-image will be modified to generate the license for each board and save |
| the file in /opt/google/chrome/resources/about_os_credits.html or as defined |
| in http://crbug.com/271832 . |
| """ |
| |
| from __future__ import print_function |
| |
| import os |
| |
| from chromite.lib import commandline |
| from chromite.lib import cros_build_lib |
| from chromite.lib import cros_logging as logging |
| from chromite.lib import osutils |
| |
| from chromite.licensing import licenses_lib |
| |
| |
| EXTRA_LICENSES_DIR = os.path.join(licenses_lib.SCRIPT_DIR, |
| 'extra_package_licenses') |
| |
| # These packages exist as workarounds.... |
| EXTRA_PACKAGES = ( |
| ('sys-kernel/Linux-2.6', |
| ['http://www.kernel.org/'], ['GPL-2'], []), |
| ('app-arch/libarchive-3.1.2', |
| ['http://www.libarchive.org/'], ['BSD', 'public-domain'], |
| ['libarchive-3.1.2.LICENSE']), |
| ) |
| |
| |
| def LoadPackageInfo(board, all_packages, generateMissing, packages): |
| """Do the work when we're not called as a hook.""" |
| logging.info("Using board %s.", board) |
| |
| builddir = os.path.join(cros_build_lib.GetSysroot(board=board), |
| 'tmp', 'portage') |
| |
| if not os.path.exists(builddir): |
| raise AssertionError( |
| "FATAL: %s missing.\n" |
| "Did you give the right board and build that tree?" % builddir) |
| |
| detect_packages = not packages |
| if detect_packages: |
| # If no packages were specified, we look up the full list. |
| packages = licenses_lib.ListInstalledPackages(board, all_packages) |
| |
| if not packages: |
| raise AssertionError('FATAL: Could not get any packages for board %s' % |
| board) |
| |
| logging.debug("Initial Package list to work through:\n%s", |
| '\n'.join(sorted(packages))) |
| licensing = licenses_lib.Licensing(board, packages, generateMissing) |
| |
| licensing.LoadPackageInfo() |
| logging.debug("Package list to skip:\n%s", |
| '\n'.join([p for p in sorted(packages) |
| if licensing.packages[p].skip])) |
| logging.debug("Package list left to work through:\n%s", |
| '\n'.join([p for p in sorted(packages) |
| if not licensing.packages[p].skip])) |
| licensing.ProcessPackageLicenses() |
| if detect_packages: |
| # If we detected 'all' packages, we have to add in these extras. |
| for fullnamewithrev, homepages, names, files in EXTRA_PACKAGES: |
| license_texts = [osutils.ReadFile(os.path.join(EXTRA_LICENSES_DIR, f)) |
| for f in files] |
| licensing.AddExtraPkg(fullnamewithrev, homepages, names, license_texts) |
| |
| return licensing |
| |
| |
| def main(args): |
| parser = commandline.ArgumentParser(usage=__doc__) |
| parser.add_argument("-b", "--board", |
| help="which board to run for, like x86-alex") |
| parser.add_argument("-p", "--package", action="append", default=[], |
| dest="packages", |
| help="check the license of the package, e.g.," |
| "dev-libs/libatomic_ops-7.2d") |
| parser.add_argument("-a", "--all-packages", action="store_true", |
| dest="all_packages", |
| help="Run licensing against all packages in the " |
| "build tree, instead of just virtual/target-os " |
| "dependencies.") |
| parser.add_argument("-g", "--generate-licenses", action="store_true", |
| dest="gen_licenses", |
| help="Generate license information, if missing.") |
| parser.add_argument("-o", "--output", type="path", |
| help="which html file to create with output") |
| opts = parser.parse_args(args) |
| |
| |
| if not opts.board: |
| raise AssertionError("No board given (--board)") |
| |
| if not opts.output and not opts.gen_licenses: |
| raise AssertionError("You must specify --output and/or --generate-licenses") |
| |
| if opts.gen_licenses and os.geteuid() != 0: |
| raise AssertionError("Run with sudo if you use --generate-licenses.") |
| |
| licensing = LoadPackageInfo( |
| opts.board, opts.all_packages, opts.gen_licenses, opts.packages) |
| |
| if opts.output: |
| licensing.GenerateHTMLLicenseOutput(opts.output) |