license_finder 0.9.4-java → 0.9.5-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.gitignore +0 -7
- data/.travis.yml +1 -3
- data/CHANGELOG.rdoc +13 -0
- data/db/migrate/201307251004_data_fix_manual_licenses.rb +2 -2
- data/db/migrate/201307251107_reassociate_license.rb +18 -18
- data/db/migrate/201311192002_add_manually_approved_to_dependencies.rb +7 -0
- data/db/migrate/201311192003_reassociate_manual_approval.rb +14 -0
- data/db/migrate/201311192010_drop_approvals.rb +5 -0
- data/features/cli.feature +1 -1
- data/features/html_report.feature +1 -1
- data/features/{non_bundler_dependencies.feature → manually_managed_dependencies.feature} +6 -6
- data/features/step_definitions/html_report_steps.rb +2 -9
- data/features/step_definitions/{non_bundler_steps.rb → manually_managed_steps.rb} +0 -0
- data/features/step_definitions/shared_steps.rb +4 -8
- data/lib/license_finder.rb +21 -17
- data/lib/license_finder/bower.rb +3 -34
- data/lib/license_finder/bower_package.rb +63 -0
- data/lib/license_finder/bundler.rb +73 -0
- data/lib/license_finder/bundler_package.rb +33 -0
- data/lib/license_finder/cli.rb +33 -35
- data/lib/license_finder/dependency_manager.rb +14 -23
- data/lib/license_finder/license/apache2.rb +1 -1
- data/lib/license_finder/license/lgpl.rb +1 -0
- data/lib/license_finder/npm.rb +22 -39
- data/lib/license_finder/npm_package.rb +61 -0
- data/lib/license_finder/package.rb +14 -80
- data/lib/license_finder/package_saver.rb +13 -75
- data/lib/license_finder/pip.rb +21 -33
- data/lib/license_finder/pip_package.rb +51 -0
- data/lib/license_finder/platform.rb +3 -15
- data/lib/license_finder/possible_license_file.rb +0 -4
- data/lib/license_finder/possible_license_files.rb +4 -0
- data/lib/license_finder/tables.rb +2 -2
- data/lib/license_finder/tables/bundler_group.rb +3 -0
- data/lib/license_finder/tables/dependency.rb +43 -18
- data/lib/license_finder/tables/license_alias.rb +4 -0
- data/lib/license_finder/yml_to_sql.rb +22 -30
- data/license_finder.gemspec +3 -3
- data/readme.md +5 -5
- data/spec/lib/license_finder/bower_package_spec.rb +56 -0
- data/spec/lib/license_finder/bower_spec.rb +3 -24
- data/spec/lib/license_finder/bundler_package_spec.rb +62 -0
- data/spec/lib/license_finder/{bundle_spec.rb → bundler_spec.rb} +7 -7
- data/spec/lib/license_finder/cli_spec.rb +6 -6
- data/spec/lib/license_finder/dependency_manager_spec.rb +14 -15
- data/spec/lib/license_finder/html_report_spec.rb +2 -3
- data/spec/lib/license_finder/markdown_report_spec.rb +4 -4
- data/spec/lib/license_finder/npm_package_spec.rb +51 -0
- data/spec/lib/license_finder/npm_spec.rb +25 -25
- data/spec/lib/license_finder/package_saver_spec.rb +50 -190
- data/spec/lib/license_finder/pip_package_spec.rb +74 -0
- data/spec/lib/license_finder/pip_spec.rb +33 -55
- data/spec/lib/license_finder/tables/dependency_spec.rb +83 -32
- data/spec/lib/license_finder/yml_to_sql_spec.rb +5 -12
- data/spec/spec_helper.rb +22 -2
- metadata +30 -18
- data/lib/license_finder/bundle.rb +0 -74
- data/lib/license_finder/tables/approval.rb +0 -4
- data/spec/lib/license_finder/package_spec.rb +0 -98
data/license_finder.gemspec
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
require './lib/license_finder/platform'
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
|
-
s.required_ruby_version = '>= 1.9.
|
4
|
+
s.required_ruby_version = '>= 1.9.3'
|
5
5
|
s.name = "license_finder"
|
6
|
-
s.version = "0.9.
|
6
|
+
s.version = "0.9.5"
|
7
7
|
s.authors = ["Jacob Maine", "Matthew Kane Parker", "Ian Lesperance", "David Edwards", "Paul Meskers", "Brent Wheeldon", "Trevor John", "David Tengdin", "William Ramsey"]
|
8
8
|
s.email = ["licensefinder@pivotalabs.com"]
|
9
9
|
s.homepage = "https://github.com/pivotal/LicenseFinder"
|
@@ -23,7 +23,7 @@ Gem::Specification.new do |s|
|
|
23
23
|
s.add_dependency "sequel"
|
24
24
|
s.add_dependency "thor"
|
25
25
|
s.add_dependency "rake"
|
26
|
-
s.add_dependency "httparty"
|
26
|
+
s.add_dependency "httparty"
|
27
27
|
s.add_dependency LicenseFinder::Platform.sqlite_gem
|
28
28
|
|
29
29
|
%w(rspec xpath cucumber pry).each do |gem|
|
data/readme.md
CHANGED
@@ -135,25 +135,25 @@ To remove a group from the ignored Bundler groups:
|
|
135
135
|
$ license_finder ignored_bundler_groups remove development
|
136
136
|
```
|
137
137
|
|
138
|
-
###
|
138
|
+
### Manually managing dependencies
|
139
139
|
|
140
|
-
license_finder can track dependencies that
|
140
|
+
license_finder can track dependencies that your package managers don't know about (JS libraries that don't
|
141
141
|
appear in your Gemfile/requirements.txt/package.json, etc.)
|
142
142
|
|
143
143
|
```sh
|
144
144
|
$ license_finder dependencies add MIT my_js_dep 0.1.2
|
145
145
|
```
|
146
146
|
|
147
|
-
To automatically approve
|
147
|
+
To automatically approve an unmanaged dependency when you add it, use:
|
148
148
|
|
149
149
|
```sh
|
150
150
|
$ license_finder dependencies add MIT my_js_dep 0.1.2 --approve
|
151
151
|
```
|
152
152
|
|
153
153
|
The version is optional. Run `license_finder dependencies help` for additional documentation about
|
154
|
-
managing
|
154
|
+
managing these dependencies.
|
155
155
|
|
156
|
-
license_finder cannot automatically detect when
|
156
|
+
license_finder cannot automatically detect when one of these dependencies has been removed from your
|
157
157
|
project, so you can use:
|
158
158
|
|
159
159
|
```sh
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module LicenseFinder
|
4
|
+
describe BowerPackage do
|
5
|
+
subject do
|
6
|
+
described_class.new(
|
7
|
+
"canonicalDir" => "/path/to/thing",
|
8
|
+
"pkgMeta" => {
|
9
|
+
"name" => "dependency-library",
|
10
|
+
"description" => "description",
|
11
|
+
"version" => "1.3.3.7",
|
12
|
+
"main" => "normalize.css",
|
13
|
+
"readme" => "some readme stuff"
|
14
|
+
}
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
it_behaves_like "it conforms to interface required by PackageSaver"
|
19
|
+
|
20
|
+
its(:name) { should == "dependency-library" }
|
21
|
+
its(:version) { should == "1.3.3.7" }
|
22
|
+
its(:summary) { should == "description" }
|
23
|
+
its(:description) { should == "some readme stuff" }
|
24
|
+
|
25
|
+
describe '#license' do
|
26
|
+
def stub_license_files(license_files)
|
27
|
+
PossibleLicenseFiles.stub(:find).with("/path/to/thing").and_return(license_files)
|
28
|
+
end
|
29
|
+
|
30
|
+
let(:package1) { { "pkgMeta" => {"license" => "MIT"} } }
|
31
|
+
let(:package2) { { "pkgMeta" => {"licenses" => [{"type" => "BSD", "url" => "github.github/github"}]} } }
|
32
|
+
let(:package3) { { "pkgMeta" => {"license" => {"type" => "PSF", "url" => "github.github/github"}} } }
|
33
|
+
let(:package4) { { "pkgMeta" => {"licenses" => ["MIT"]} } }
|
34
|
+
|
35
|
+
it 'finds the license for both license structures' do
|
36
|
+
BowerPackage.new(package1).license.should eq("MIT")
|
37
|
+
BowerPackage.new(package2).license.should eq("BSD")
|
38
|
+
BowerPackage.new(package3).license.should eq("PSF")
|
39
|
+
BowerPackage.new(package4).license.should eq("MIT")
|
40
|
+
end
|
41
|
+
|
42
|
+
it "returns a license in a file if detected" do
|
43
|
+
stub_license_files [double(:file, license: 'Detected License')]
|
44
|
+
|
45
|
+
subject.license.should == "Detected License"
|
46
|
+
end
|
47
|
+
|
48
|
+
it "returns 'other' otherwise" do
|
49
|
+
stub_license_files []
|
50
|
+
|
51
|
+
subject.license.should == "other"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
@@ -35,30 +35,9 @@ module LicenseFinder
|
|
35
35
|
expect(current_packages.size).to eq(2)
|
36
36
|
expect(current_packages.first).to be_a(Package)
|
37
37
|
end
|
38
|
-
|
39
|
-
it 'memoizes the current_packages' do
|
40
|
-
allow(Bower).to receive(:`).with(/bower/).and_return('{}').once
|
41
|
-
|
42
|
-
Bower.current_packages
|
43
|
-
Bower.current_packages
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
describe '.harvest_license' do
|
48
|
-
let(:package1) { {"license" => "MIT"} }
|
49
|
-
let(:package2) { {"licenses" => [{"type" => "BSD", "url" => "github.github/github"}]} }
|
50
|
-
let(:package3) { {"license" => {"type" => "PSF", "url" => "github.github/github"}} }
|
51
|
-
let(:package4) { {"licenses" => ["MIT"]} }
|
52
|
-
|
53
|
-
it 'finds the license for both license structures' do
|
54
|
-
Bower.harvest_license(package1).should eq("MIT")
|
55
|
-
Bower.harvest_license(package2).should eq("BSD")
|
56
|
-
Bower.harvest_license(package3).should eq("PSF")
|
57
|
-
Bower.harvest_license(package4).should eq("MIT")
|
58
|
-
end
|
59
38
|
end
|
60
39
|
|
61
|
-
describe '.
|
40
|
+
describe '.active?' do
|
62
41
|
let(:package) { Pathname.new('bower.json').expand_path }
|
63
42
|
|
64
43
|
context 'with a bower.json file' do
|
@@ -67,7 +46,7 @@ module LicenseFinder
|
|
67
46
|
end
|
68
47
|
|
69
48
|
it 'returns true' do
|
70
|
-
expect(Bower.
|
49
|
+
expect(Bower.active?).to eq(true)
|
71
50
|
end
|
72
51
|
end
|
73
52
|
|
@@ -77,7 +56,7 @@ module LicenseFinder
|
|
77
56
|
end
|
78
57
|
|
79
58
|
it 'returns false' do
|
80
|
-
expect(Bower.
|
59
|
+
expect(Bower.active?).to eq(false)
|
81
60
|
end
|
82
61
|
end
|
83
62
|
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module LicenseFinder
|
4
|
+
describe BundlerPackage do
|
5
|
+
subject { described_class.new(gemspec, nil) }
|
6
|
+
|
7
|
+
it_behaves_like "it conforms to interface required by PackageSaver"
|
8
|
+
|
9
|
+
let(:gemspec) do
|
10
|
+
Gem::Specification.new do |s|
|
11
|
+
s.name = 'spec_name'
|
12
|
+
s.version = '2.1.3'
|
13
|
+
s.summary = 'summary'
|
14
|
+
s.description = 'description'
|
15
|
+
s.homepage = 'homepage'
|
16
|
+
|
17
|
+
s.add_dependency 'foo'
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
its(:name) { should == 'spec_name' }
|
22
|
+
its(:version) { should == '2.1.3' }
|
23
|
+
its(:summary) { should == "summary" }
|
24
|
+
its(:description) { should == "description" }
|
25
|
+
its(:groups) { should == [] }
|
26
|
+
its(:children) { should == [] }
|
27
|
+
|
28
|
+
describe "#license" do
|
29
|
+
def stub_license_files(license_files)
|
30
|
+
PossibleLicenseFiles.stub(:find).and_return(license_files)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "returns the license from the gemspec if provided" do
|
34
|
+
gemspec.stub(:license).and_return('Gemspec License')
|
35
|
+
|
36
|
+
subject.license.should == "Gemspec License"
|
37
|
+
end
|
38
|
+
|
39
|
+
it "returns a license in a file if detected" do
|
40
|
+
stub_license_files [double(:file, license: 'Detected License')]
|
41
|
+
|
42
|
+
subject.license.should == "Detected License"
|
43
|
+
end
|
44
|
+
|
45
|
+
it "returns 'other' otherwise" do
|
46
|
+
stub_license_files []
|
47
|
+
|
48
|
+
subject.license.should == "other"
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "#groups" do
|
53
|
+
subject { described_class.new(gemspec, bundler_dependency) }
|
54
|
+
|
55
|
+
let(:bundler_dependency) { double(:dependency, groups: [1, 2, 3]) }
|
56
|
+
|
57
|
+
it "returns bundler dependency's groups" do
|
58
|
+
subject.groups.should == bundler_dependency.groups
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
module LicenseFinder
|
4
|
-
describe
|
4
|
+
describe Bundler do
|
5
5
|
let(:definition) do
|
6
6
|
double('definition', {
|
7
7
|
:dependencies => [],
|
@@ -26,15 +26,15 @@ module LicenseFinder
|
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
|
-
describe '.
|
29
|
+
describe '.current_packages' do
|
30
30
|
subject do
|
31
|
-
|
31
|
+
Bundler.current_packages(config)
|
32
32
|
end
|
33
33
|
|
34
34
|
let(:config) { double(:config, ignore_groups: ['dev', 'test']) }
|
35
35
|
|
36
36
|
before do
|
37
|
-
Bundler::Definition.stub(:build).and_return(definition)
|
37
|
+
::Bundler::Definition.stub(:build).and_return(definition)
|
38
38
|
end
|
39
39
|
|
40
40
|
it "should have 2 dependencies" do
|
@@ -63,7 +63,7 @@ module LicenseFinder
|
|
63
63
|
end
|
64
64
|
end
|
65
65
|
|
66
|
-
describe '.
|
66
|
+
describe '.active?' do
|
67
67
|
let(:gemfile) { Pathname.new('Gemfile').expand_path }
|
68
68
|
|
69
69
|
before :each do
|
@@ -74,7 +74,7 @@ module LicenseFinder
|
|
74
74
|
it 'returns false' do
|
75
75
|
allow(File).to receive(:exists?).with(gemfile).and_return(false)
|
76
76
|
|
77
|
-
|
77
|
+
Bundler.active?.should == false
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
@@ -82,7 +82,7 @@ module LicenseFinder
|
|
82
82
|
it 'returns true' do
|
83
83
|
allow(File).to receive(:exists?).with(gemfile).and_return(true)
|
84
84
|
|
85
|
-
|
85
|
+
Bundler.active?.should == true
|
86
86
|
end
|
87
87
|
end
|
88
88
|
end
|
@@ -5,7 +5,7 @@ module LicenseFinder
|
|
5
5
|
describe Dependencies do
|
6
6
|
describe "add" do
|
7
7
|
it "adds a dependency" do
|
8
|
-
DependencyManager.should_receive(:
|
8
|
+
DependencyManager.should_receive(:create_manually_managed).with("MIT", "js_dep", "1.2.3")
|
9
9
|
|
10
10
|
silence_stdout do
|
11
11
|
subject.add("MIT", "js_dep", "1.2.3")
|
@@ -13,7 +13,7 @@ module LicenseFinder
|
|
13
13
|
end
|
14
14
|
|
15
15
|
it "does not require a version" do
|
16
|
-
DependencyManager.should_receive(:
|
16
|
+
DependencyManager.should_receive(:create_manually_managed).with("MIT", "js_dep", nil)
|
17
17
|
|
18
18
|
silence_stdout do
|
19
19
|
subject.add("MIT", "js_dep")
|
@@ -21,7 +21,7 @@ module LicenseFinder
|
|
21
21
|
end
|
22
22
|
|
23
23
|
it "has an --approve option to approve the added dependency" do
|
24
|
-
DependencyManager.should_receive(:
|
24
|
+
DependencyManager.should_receive(:create_manually_managed).with("MIT", "js_dep", "1.2.3")
|
25
25
|
DependencyManager.should_receive(:approve!).with("js_dep")
|
26
26
|
|
27
27
|
silence_stdout do
|
@@ -32,7 +32,7 @@ module LicenseFinder
|
|
32
32
|
|
33
33
|
describe "remove" do
|
34
34
|
it "removes a dependency" do
|
35
|
-
DependencyManager.should_receive(:
|
35
|
+
DependencyManager.should_receive(:destroy_manually_managed).with("js_dep")
|
36
36
|
silence_stdout do
|
37
37
|
subject.remove("js_dep")
|
38
38
|
end
|
@@ -160,7 +160,7 @@ module LicenseFinder
|
|
160
160
|
describe Main do
|
161
161
|
describe "default" do
|
162
162
|
it "checks for action items" do
|
163
|
-
DependencyManager.should_receive(:
|
163
|
+
DependencyManager.should_receive(:sync_with_package_managers)
|
164
164
|
Dependency.stub(:unapproved) { [] }
|
165
165
|
silence_stdout do
|
166
166
|
described_class.start([])
|
@@ -170,7 +170,7 @@ module LicenseFinder
|
|
170
170
|
|
171
171
|
describe "#rescan" do
|
172
172
|
it "resyncs with Gemfile" do
|
173
|
-
DependencyManager.should_receive(:
|
173
|
+
DependencyManager.should_receive(:sync_with_package_managers)
|
174
174
|
Dependency.stub(:unapproved) { [] }
|
175
175
|
|
176
176
|
silence_stdout do
|
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'digest'
|
3
2
|
|
4
3
|
module LicenseFinder
|
5
4
|
describe DependencyManager do
|
@@ -22,29 +21,29 @@ module LicenseFinder
|
|
22
21
|
Dependency.create(name: "old dependency 1")
|
23
22
|
Dependency.create(name: "old dependency 2")
|
24
23
|
|
25
|
-
|
26
|
-
|
27
|
-
PackageSaver.should_receive(:
|
24
|
+
current_packages = [gem1, gem2]
|
25
|
+
Bundler.stub(:current_packages) { current_packages }
|
26
|
+
PackageSaver.should_receive(:save_all).with(current_packages).and_return([cur1, cur2])
|
28
27
|
|
29
|
-
described_class.
|
28
|
+
described_class.sync_with_package_managers
|
30
29
|
Dependency.all.map(&:name).should =~ [cur1, cur2, man1].map(&:name)
|
31
30
|
end
|
32
31
|
end
|
33
32
|
|
34
|
-
describe ".
|
33
|
+
describe ".create_manually_managed" do
|
35
34
|
it "should add a Dependency" do
|
36
35
|
expect do
|
37
|
-
described_class.
|
36
|
+
described_class.create_manually_managed("MIT", "js_dep", "0.0.0")
|
38
37
|
end.to change(Dependency, :count).by(1)
|
39
38
|
end
|
40
39
|
|
41
40
|
it "should mark the dependency as manual" do
|
42
|
-
described_class.
|
41
|
+
described_class.create_manually_managed("MIT", "js_dep", "0.0.0")
|
43
42
|
.should be_manual
|
44
43
|
end
|
45
44
|
|
46
45
|
it "should set the appropriate values" do
|
47
|
-
dep = described_class.
|
46
|
+
dep = described_class.create_manually_managed("GPL", "js_dep", "0.0.0")
|
48
47
|
dep.name.should == "js_dep"
|
49
48
|
dep.version.should == "0.0.0"
|
50
49
|
dep.license.name.should == "GPL"
|
@@ -53,16 +52,16 @@ module LicenseFinder
|
|
53
52
|
|
54
53
|
it "should complain if the dependency already exists" do
|
55
54
|
Dependency.create(name: "current dependency 1")
|
56
|
-
expect { described_class.
|
55
|
+
expect { described_class.create_manually_managed("GPL", "current dependency 1", "0.0.0") }
|
57
56
|
.to raise_error(LicenseFinder::Error)
|
58
57
|
end
|
59
58
|
end
|
60
59
|
|
61
|
-
describe ".
|
62
|
-
it "should remove a
|
63
|
-
described_class.
|
60
|
+
describe ".destroy_manually_managed" do
|
61
|
+
it "should remove a manually managed Dependency" do
|
62
|
+
described_class.create_manually_managed("GPL", "a manually managed dep", nil)
|
64
63
|
expect do
|
65
|
-
described_class.
|
64
|
+
described_class.destroy_manually_managed("a manually managed dep")
|
66
65
|
end.to change(Dependency, :count).by(-1)
|
67
66
|
end
|
68
67
|
|
@@ -70,7 +69,7 @@ module LicenseFinder
|
|
70
69
|
Dependency.create(name: "a bundler dep")
|
71
70
|
expect do
|
72
71
|
expect do
|
73
|
-
described_class.
|
72
|
+
described_class.destroy_manually_managed("a bundler dep")
|
74
73
|
end.to raise_error(LicenseFinder::Error)
|
75
74
|
end.to_not change(Dependency, :count)
|
76
75
|
end
|
@@ -5,9 +5,8 @@ module LicenseFinder
|
|
5
5
|
describe HtmlReport do
|
6
6
|
describe "#to_s" do
|
7
7
|
let(:dependency) do
|
8
|
-
dep = Dependency.new name: "the-name"
|
8
|
+
dep = Dependency.new name: "the-name", manually_approved: true
|
9
9
|
dep.license = LicenseAlias.create name: 'MIT'
|
10
|
-
dep.approval = Approval.create state: true
|
11
10
|
dep
|
12
11
|
end
|
13
12
|
|
@@ -24,7 +23,7 @@ module LicenseFinder
|
|
24
23
|
end
|
25
24
|
|
26
25
|
context "when the dependency is not approved" do
|
27
|
-
before { dependency.
|
26
|
+
before { dependency.manually_approved = false }
|
28
27
|
|
29
28
|
it "should not add an approved class to he dependency's container" do
|
30
29
|
should have_selector ".unapproved"
|
@@ -6,20 +6,20 @@ module LicenseFinder
|
|
6
6
|
let(:dep1) do
|
7
7
|
dependency = Dependency.new(
|
8
8
|
'name' => 'gem_a',
|
9
|
-
'version' => '1.0'
|
9
|
+
'version' => '1.0',
|
10
|
+
'manually_approved' => false
|
10
11
|
)
|
11
12
|
dependency.license = LicenseFinder::LicenseAlias.create(name: 'MIT')
|
12
|
-
dependency.approval = Approval.create(state: false)
|
13
13
|
dependency
|
14
14
|
end
|
15
15
|
|
16
16
|
let(:dep2) do
|
17
17
|
dependency = Dependency.new(
|
18
18
|
'name' => 'gem_b',
|
19
|
-
'version' => '2.3'
|
19
|
+
'version' => '2.3',
|
20
|
+
'manually_approved' => true
|
20
21
|
)
|
21
22
|
dependency.license = LicenseFinder::LicenseAlias.create(name: 'BSD')
|
22
|
-
dependency.approval = Approval.create(state: true)
|
23
23
|
dependency
|
24
24
|
end
|
25
25
|
|