Skip to content

Commit

Permalink
feat: support PackageJson~read
Browse files Browse the repository at this point in the history
  • Loading branch information
G-Rath committed Aug 12, 2023
1 parent b78f6b9 commit 372a9d4
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 4 deletions.
17 changes: 13 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,13 +56,22 @@ end
package_json.manager.run("lint", ["--fix"])
```

The `PackageJson` class represents a `package.json` on disk within a directory,
creating the file if it does not already exist.

Because it is expected that the `package.json` might be changed by external
The `PackageJson` class represents a `package.json` on disk within a directory;
because it is expected that the `package.json` might be changed by external
sources such as package managers, `PackageJson` reads and writes to and from the
`package.json` as needed rather than representing it in memory.

You can initialize a `PackageJson` with either `new` or `read` depending on if
you want to ensure the `package.json` exists or throw if it doesn't:

```ruby
# this will create the `package.json` if it does not exist
PackageJson.new(:npm, "path/to/directory")

# this will error if the `package.json` does not exist
PackageJson.read("path/to/directory", :npm)
```

A `PackageJson` also comes with a `manager` that can be used to manage
dependencies and run scripts. The manager will be inferred by the
[`packageManager`](https://nodejs.org/api/packages.html#packagemanager) property
Expand Down
8 changes: 8 additions & 0 deletions lib/package_json.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ class NotImplementedError < Error; end

attr_reader :manager, :path

def self.read(path_to_directory = Dir.pwd, fallback_manager = :npm)
unless File.exist?("#{path_to_directory}/package.json")
raise Error, "#{path_to_directory} does not contain a package.json"
end

new(fallback_manager, path_to_directory)
end

def initialize(fallback_manager = :npm, path_to_directory = Dir.pwd)
@path = path_to_directory

Expand Down
112 changes: 112 additions & 0 deletions spec/package_json_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,118 @@
expect(PackageJson::VERSION).not_to be_nil
end

describe ".read" do
context "when the package.json does not exist" do
it "raises an error" do
expect { described_class.read }.to raise_error(
PackageJson::Error, "#{Dir.pwd} does not contain a package.json"
)
end
end

context "when the package.json already exists with the packageManager property" do
it "does not error" do
with_package_json_file({ "version" => "1.0.0" }) do
expect { described_class.new }.not_to raise_error
end
end

it "uses the packageManager property" do
with_package_json_file({ "version" => "1.0.0", "packageManager" => "pnpm" }) do
package_json = described_class.new

expect(package_json.manager).to be_a PackageJson::Managers::PnpmLike
end
end

it "ignores the fallback manager" do
with_package_json_file({ "version" => "1.0.0", "packageManager" => "pnpm" }) do
package_json = described_class.new(:yarn_classic)

expect(package_json.manager).to be_a PackageJson::Managers::PnpmLike
end
end

it "supports having a version specified" do
with_package_json_file({ "version" => "1.0.0", "packageManager" => "[email protected]" }) do
package_json = described_class.new

expect(package_json.manager).to be_a PackageJson::Managers::PnpmLike
end
end

it "requires a major version for yarn" do
with_package_json_file({ "version" => "1.0.0", "packageManager" => "yarn" }) do
expect { described_class.new }.to raise_error(PackageJson::Error, "a major version must be present for Yarn")
end
end

it "only supports yarn v1" do
with_package_json_file({ "version" => "1.0.0", "packageManager" => "yarn@2" }) do
expect { described_class.new }.to raise_error(PackageJson::Error, "only Yarn classic is supported")
end
end

it "supports a full version being specified for yarn" do
with_package_json_file({ "version" => "1.0.0", "packageManager" => "[email protected]" }) do
package_json = described_class.new

expect(package_json.manager).to be_a PackageJson::Managers::YarnClassicLike
end
end

it "does not change the packageManager property" do
with_package_json_file({ "version" => "1.0.0", "packageManager" => "pnpm" }) do
described_class.new(:yarn_classic)

expect_package_json_with_content({ "version" => "1.0.0", "packageManager" => "pnpm" })
end
end

it "raises an error if the package manager is not supported" do
with_package_json_file({ "version" => "1.0.0", "packageManager" => "unknown" }) do
expect { described_class.new }.to raise_error(
PackageJson::Error,
'unsupported package manager "unknown"'
)
end
end
end

context "when the package.json already exists without the packageManager property" do
it "does not error" do
with_package_json_file({ "version" => "1.0.0" }) do
expect { described_class.new }.not_to raise_error
end
end

it "uses the fallback manager" do
with_package_json_file({ "version" => "1.0.0" }) do
package_json = described_class.new(:yarn_classic)

expect(package_json.manager).to be_a PackageJson::Managers::YarnClassicLike
end
end

it "does not add the packageManager property" do
with_package_json_file({ "version" => "1.0.0" }) do
described_class.new(:yarn_classic)

expect_package_json_with_content({ "version" => "1.0.0" })
end
end

it "raises an error if the fallback manager is not supported" do
with_package_json_file({ "version" => "1.0.0" }) do
expect { described_class.new(:unknown) }.to raise_error(
PackageJson::Error,
'unsupported package manager "unknown"'
)
end
end
end
end

describe ".new" do
context "when the package.json does not exist" do
it "does not error" do
Expand Down

0 comments on commit 372a9d4

Please sign in to comment.