зеркало из https://github.com/github/licensed.git
add migrate command, migrate to v2
This commit is contained in:
Родитель
4b3ea99d8b
Коммит
ea44e0cbc2
|
@ -23,6 +23,7 @@ test/fixtures/cabal/*
|
|||
!test/fixtures/cabal/app*
|
||||
test/fixtures/git_submodule/*
|
||||
!test/fixtures/git_submodule/README
|
||||
!test/fixtures/migrations/**/*
|
||||
|
||||
vendor/licenses
|
||||
.licenses
|
||||
|
|
|
@ -12,6 +12,12 @@ Licensed is **not** a complete open source license compliance solution. Please u
|
|||
|
||||
Licensed is in active development and currently used at GitHub. See the [open issues](https://github.com/github/licensed/issues) for a list of potential work.
|
||||
|
||||
## Migrating to 2.x
|
||||
|
||||
Licensed 2.x is incompatible with configuration files and cached records from 1.x. Migrating to 2.x is easy using the `licensed migrate` command.
|
||||
|
||||
See the [migration documentation](./docs/migrating_to_newer_versions.md) for more info, or run `licensed help migrate`.
|
||||
|
||||
## Installation
|
||||
|
||||
### With a Gemfile
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
# Migrating your licensed configuration and cached records to the latest version of licensed
|
||||
|
||||
Licensed v2+ ships with an additional executable, `licensed-migrator`, that can be used to update your licensed files to the format expected by the currently installed version. To run, execute `licensed migrate --from v1 -c <path to licensed configuration file>`, replacing `v1` with the major version of licensed to migrate from.
|
|
@ -9,3 +9,4 @@ require "licensed/configuration"
|
|||
require "licensed/reporters"
|
||||
require "licensed/commands"
|
||||
require "licensed/ui/shell"
|
||||
require "licensed/migrations"
|
||||
|
|
|
@ -35,6 +35,23 @@ module Licensed
|
|||
puts Licensed::VERSION
|
||||
end
|
||||
|
||||
desc "migrate", "Migrate from a previous version of licensed"
|
||||
method_option :config, aliases: "-c", type: :string, required: true,
|
||||
desc: "Path to licensed configuration file"
|
||||
method_option :from, aliases: "-f", type: :string, required: true,
|
||||
desc: "Licensed version to migrate from - #{Licensed.previous_major_versions.map { |major| "v#{major}" }.join(", ")}"
|
||||
def migrate
|
||||
case options["from"]
|
||||
when "v1"
|
||||
Licensed::Migrations::V2.migrate(options["config"], shell)
|
||||
else
|
||||
shell = Thor::Base.shell.new
|
||||
shell.say "Unrecognized option from=#{options["from"]}", :red
|
||||
CLI.command_help(shell, 'migrate')
|
||||
exit 1
|
||||
end
|
||||
end
|
||||
|
||||
# If an error occurs (e.g. a missing command or argument), exit 1.
|
||||
def self.exit_on_failure?
|
||||
true
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Licensed
|
||||
module Migrations
|
||||
require "licensed/migrations/v2"
|
||||
end
|
||||
end
|
|
@ -0,0 +1,47 @@
|
|||
# frozen_string_literal: true
|
||||
require "licensed/shell"
|
||||
|
||||
module Licensed
|
||||
module Migrations
|
||||
class V2
|
||||
def self.migrate(config_path, shell = Licensed::UI::Shell.new)
|
||||
shell.info "updating to v2"
|
||||
|
||||
shell.info "updating bundler configuration keys"
|
||||
# replace all "rubygem" and "rubygems" configuration keys with "bundler"
|
||||
# to account for the bundler source's `type` change from `rubygem` to `bundler`
|
||||
File.write(config_path, File.read(config_path).gsub(/rubygems?:/, "bundler:"))
|
||||
|
||||
shell.info "updating cached records"
|
||||
# load the configuration to find and update cached contents
|
||||
configuration = Licensed::Configuration.load_from(config_path)
|
||||
configuration.apps.each do |app|
|
||||
Dir.chdir app.cache_path do
|
||||
# licensed v1 cached records were stored as .txt files with YAML frontmatter
|
||||
Dir["**/*.txt"].each do |file|
|
||||
# find the yaml and non-yaml data by parsing the yaml data out of the contents
|
||||
# then reserializing the contents to a string that can be stripped from the
|
||||
# original file contents
|
||||
cached_contents = File.read(file)
|
||||
yaml = YAML.load(cached_contents)
|
||||
cached_contents = cached_contents.gsub(yaml.to_yaml + "---", "")
|
||||
|
||||
# in v1, licenses and notices are separated by special text dividers
|
||||
# in v2, cached records are defined and formatted entirely in yaml
|
||||
licenses, *notices = cached_contents.split(("-") * 80).map(&:strip)
|
||||
licenses = licenses.split(("*") * 80).map(&:strip)
|
||||
yaml["licenses"] = licenses.map { |text| { "text" => text } }
|
||||
yaml["notices"] = notices.map { |text| { "text" => text } }
|
||||
|
||||
# v2 records are stored in `.dep.yml` files
|
||||
# write the new yaml contents to the new file and delete old file
|
||||
new_file = file.gsub(".txt", ".dep.yml")
|
||||
File.write(new_file, yaml.to_yaml)
|
||||
File.delete(file)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,4 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
module Licensed
|
||||
VERSION = "1.5.2".freeze
|
||||
|
||||
def self.previous_major_versions
|
||||
major_version = Gem::Version.new(Licensed::VERSION).segments.first
|
||||
(1...major_version).to_a
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
name: migration-v2
|
||||
cache_path: cache
|
||||
|
||||
sources:
|
||||
rubygem: true
|
||||
|
||||
reviewed:
|
||||
rubygem:
|
||||
- test
|
||||
|
||||
ignored:
|
||||
rubygem:
|
||||
- test
|
||||
|
||||
rubygem:
|
||||
value: test
|
||||
|
||||
apps:
|
||||
- source_path: "."
|
||||
- source_path: "."
|
||||
reviewed:
|
||||
rubygem: # to verify that individual app configurations are updated as well
|
||||
- test
|
|
@ -0,0 +1,43 @@
|
|||
---
|
||||
type: manifest
|
||||
name: notices
|
||||
version: bd72e775440b11efdea627789f1d92ca3bcfd772
|
||||
license: bsd-3-clause
|
||||
---
|
||||
|
||||
Copyright 2018 GitHub
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software
|
||||
without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
|
||||
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum sed mollis
|
||||
magna. Integer vehicula condimentum justo, a ornare urna congue sit amet.
|
||||
Nulla quis hendrerit metus, eu iaculis dui. Integer vitae turpis sapien.
|
||||
Maecenas sed ultrices mauris. Nunc posuere dictum malesuada. Cras sapien eros,
|
||||
pulvinar vitae orci sed, euismod pretium lectus. Sed varius sodales dui, quis
|
||||
lobortis turpis elementum in. Vestibulum accumsan lectus eget ipsum rutrum,
|
||||
quis malesuada elit euismod. Proin porta sem posuere tempor gravida. Duis
|
||||
lacinia diam in neque faucibus, sed egestas erat suscipit. Aenean blandit diam
|
||||
sem.
|
|
@ -0,0 +1,40 @@
|
|||
# frozen_string_literal: true
|
||||
require "test_helper"
|
||||
|
||||
describe Licensed::Migrations::V2 do
|
||||
let(:fixtures) { File.expand_path("../../fixtures/migrations/v2", __FILE__) }
|
||||
let(:shell) { TestShell.new }
|
||||
|
||||
it "updates configuration settings" do
|
||||
Dir.mktmpdir do |tmp|
|
||||
FileUtils.cp_r fixtures, tmp
|
||||
Dir.chdir(File.join(tmp, "v2")) do
|
||||
Licensed::Migrations::V2.migrate(".licensed.yml", shell)
|
||||
configuration = Licensed::Configuration.load_from(".licensed.yml")
|
||||
configuration.apps.each do |app|
|
||||
assert app.enabled?("bundler")
|
||||
refute app.enabled?("rubygem")
|
||||
assert app.reviewed?({ "name" => "test", "type" => "bundler" })
|
||||
refute app.reviewed?({ "name" => "test", "type" => "rubygem" })
|
||||
assert app.ignored?({ "name" => "test", "type" => "bundler" })
|
||||
refute app.ignored?({ "name" => "test", "type" => "rubygem" })
|
||||
assert_equal "test", app.dig("bundler", "value")
|
||||
assert_nil app.dig("rubygem", "value")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it "updates cached records" do
|
||||
Dir.mktmpdir do |tmp|
|
||||
FileUtils.cp_r fixtures, tmp
|
||||
Dir.chdir(File.join(tmp, "v2")) do
|
||||
Licensed::Migrations::V2.migrate(".licensed.yml", shell)
|
||||
cached_record = Licensed::DependencyRecord.read("cache/manifest/notices.dep.yml")
|
||||
assert cached_record
|
||||
refute_empty cached_record.licenses
|
||||
refute_empty cached_record.notices
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Загрузка…
Ссылка в новой задаче