Skip to content

Commit

Permalink
Add handling for dirty git dir and non-tagged commits
Browse files Browse the repository at this point in the history
  • Loading branch information
straight-shoota committed Apr 10, 2020
1 parent f427102 commit bfbc2eb
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 5 deletions.
45 changes: 41 additions & 4 deletions spec/compiler/crystal/tools/doc/project_info_spec.cr
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,27 @@ describe Crystal::Doc::ProjectInfo do
ProjectInfo.new_with_defaults(nil, "1.1") { |name, version| "missing:#{name}:#{version}" }.should eq ProjectInfo.new("foo", "1.1")
ProjectInfo.new_with_defaults("bar", "2.0") { |name, version| "missing:#{name}:#{version}" }.should eq ProjectInfo.new("bar", "2.0")
end

it "git non-tagged commit" do
`git init`
`git add shard.yml`
`git commit -m 'Initial commit' --no-gpg-sign`

ProjectInfo.new_with_defaults(nil, nil) { |name, version| "missing:#{name}:#{version}" }.should eq ProjectInfo.new("foo", "master")
ProjectInfo.new_with_defaults(nil, "1.1") { |name, version| "missing:#{name}:#{version}" }.should eq ProjectInfo.new("foo", "1.1")
ProjectInfo.new_with_defaults("bar", "2.0") { |name, version| "missing:#{name}:#{version}" }.should eq ProjectInfo.new("bar", "2.0")
end

it "git non-tagged commit dirty" do
`git init`
`git add shard.yml`
`git commit -m 'Initial commit' --no-gpg-sign`
File.write("foo.txt", "bar")

ProjectInfo.new_with_defaults(nil, nil) { |name, version| "missing:#{name}:#{version}" }.should eq ProjectInfo.new("foo", "master-dev")
ProjectInfo.new_with_defaults(nil, "1.1") { |name, version| "missing:#{name}:#{version}" }.should eq ProjectInfo.new("foo", "1.1")
ProjectInfo.new_with_defaults("bar", "2.0") { |name, version| "missing:#{name}:#{version}" }.should eq ProjectInfo.new("bar", "2.0")
end
end

it "no shard.yml, but git tagged version" do
Expand All @@ -70,28 +91,44 @@ describe Crystal::Doc::ProjectInfo do
# Non-git directory
ProjectInfo.find_git_version.should be_nil

# Empty git directory
`git init`
ProjectInfo.find_git_version.should be_nil

# Non-tagged commit
File.write("file.txt", "foo")
`git add file.txt`
`git commit -m 'Initial commit' --no-gpg-sign`
ProjectInfo.find_git_version.should be_nil
ProjectInfo.find_git_version.should eq "master"

# Non-tagged commit, dirty workdir
File.write("file.txt", "bar")
ProjectInfo.find_git_version.should eq "master-dev"

`git checkout -- .`

# Tagged commit
`git tag v0.1.0`
ProjectInfo.find_git_version.should eq "0.1.0"

# Tagged commit, dirty workdir
File.write("file.txt", "bar")
ProjectInfo.find_git_version.should be_nil
ProjectInfo.find_git_version.should eq "0.1.0-dev"

# Tagged commit, dirty index
`git add file.txt`
ProjectInfo.find_git_version.should be_nil
ProjectInfo.find_git_version.should eq "0.1.0-dev"

`git reset --hard v0.1.0`
ProjectInfo.find_git_version.should eq "0.1.0"

# Multiple tags
`git tag v0.2.0`
ProjectInfo.find_git_version.should be_nil
ProjectInfo.find_git_version.should eq "master"

# Other branch
`git checkout -b foo`
ProjectInfo.find_git_version.should eq "foo"
end

describe ".read_shard_properties" do
Expand Down
25 changes: 24 additions & 1 deletion src/compiler/crystal/tools/doc/project_info.cr
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,30 @@ module Crystal::Doc
end

def self.find_git_version
if ref = git_ref
case git_clean?
when Nil
when true
ref
when false
"#{ref}-dev"
end
end
end

def self.git_clean?
# Use git to determine if index and working directory are clean
io = IO::Memory.new
status = Process.run("git", ["status", "--porcelain"], output: io)
# If clean, output of `git status --porcelain` is empty. Still need to check
# the status code, to make sure empty doesn't mean error.
return unless status.success?
io.rewind
return unless status.success? && io.bytesize == 0
io.bytesize == 0
end

def self.git_ref
io = IO::Memory.new
# Check if current HEAD is tagged
status = Process.run("git", ["tag", "--points-at", "HEAD"], output: io)
return unless status.success?
Expand All @@ -35,6 +51,13 @@ module Crystal::Doc
if versions.size == 1
return versions.first.byte_slice(1)
end

# Otherwise, return current branch name
io.clear
status = Process.run("git", ["rev-parse", "--abbrev-ref", "HEAD"], output: io)
return unless status.success?

io.to_s.strip.presence
end

def self.read_shard_properties
Expand Down

0 comments on commit bfbc2eb

Please sign in to comment.