Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Initial support for npm workspaces #485

Merged
merged 1 commit into from
Mar 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion docs/sources/npm.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,21 @@

The npm source will detect dependencies `package.json` is found at an apps `source_path`. It uses `npm list` to enumerate dependencies and metadata.

### Including development dependencies
## Including development dependencies

By default, the npm source will exclude all development dependencies. To include development or test dependencies, set `production_only: false` in the licensed configuration.

```yml
npm:
production_only: false
```

## Using licensed with npm workspaces

Licensed requires npm version 8.5.0 or later to enumerate dependencies inside of npm workspaces. For the best results, treat each workspace directory as a separate app `source_path`:

```yml
apps:
- source_path: path/to/workspace/a
- source_path: path/to/workspace/b
```
24 changes: 23 additions & 1 deletion lib/licensed/sources/npm.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@ def license_metadata
end

def enabled?
Licensed::Shell.tool_available?("npm") && File.exist?(config.pwd.join("package.json"))
Licensed::Shell.tool_available?("npm") && File.exist?(package_json_path)
end

def enumerate_dependencies
packages.map do |name, package|
next if package["name"] == project_name

errors = package["problems"] unless package["path"]
Dependency.new(
name: name,
Expand Down Expand Up @@ -159,6 +161,26 @@ def peer_dependency(parent, name)
def extract_version(parent, name)
parent&.dig("_dependencies", name) || peer_dependency(parent, name)
end

# Returns the current projects name
def project_name
return unless package_json
package_json["name"]
end

## Returns the parse package.json for the current project
def package_json
return unless File.exist?(package_json_path)

@package_json ||= JSON.parse(File.read(package_json_path))
rescue JSON::ParserError => e
message = "Licensed was unable to parse package.json. JSON Error: #{e.message}"
raise Licensed::Sources::Source::Error, message
end

def package_json_path
@package_json_path ||= File.join(config.pwd, "package.json")
end
end
end
end
5 changes: 4 additions & 1 deletion test/fixtures/npm/package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "fixtures",
"name": "licensed-fixtures",
"version": "1.0.0",
"dependencies": {
"@github/query-selector": "1.0.3",
Expand All @@ -11,6 +11,9 @@
"devDependencies": {
"string.prototype.startswith": "0.2.0"
},
"workspaces": [
"packages/a"
],
"description": "npm test fixture",
"repository": "https://github.com/github/licensed",
"license": "MIT"
Expand Down
10 changes: 10 additions & 0 deletions test/fixtures/npm/packages/a/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "licensed-fixtures-a",
"version": "1.0.0",
"description": "",
"author": "",
"license": "MIT",
"dependencies": {
"callbackify": "1.1.0"
}
}
25 changes: 25 additions & 0 deletions test/sources/npm_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,31 @@
end
end
end

describe "from a workspace" do
let(:fixtures) { File.expand_path("../../fixtures/npm/packages/a", __FILE__) }

it "finds dependencies" do
# workspaces will only work as expected with npm > 8.5.0
skip if source.npm_version < Gem::Version.new("8.5.0")

Dir.chdir fixtures do
dep = source.dependencies.detect { |d| d.name == "callbackify" }
assert dep
assert_equal "npm", dep.record["type"]
assert_equal "1.1.0", dep.version
end
end

it "does not include the current workspace project" do
# workspaces will only work as expected with npm > 8.5.0
skip if source.npm_version < Gem::Version.new("8.5.0")

Dir.chdir fixtures do
refute source.dependencies.detect { |d| d.name == "licensed-fixtures-a" }
end
end
end
end

describe "missing dependencies (glob is missing package)" do
Expand Down