Skip to content

Commit 45dbdae

Browse files
committed
feat: provider a "proper" CLI experience
1 parent 3bee6ad commit 45dbdae

File tree

9 files changed

+170
-105
lines changed

9 files changed

+170
-105
lines changed

shard.lock

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ shards:
44
git: https://github.com/crystal-lang/json_mapping.cr.git
55
version: 0.1.0
66

7+
version_from_shard:
8+
git: https://github.com/hugopl/version_from_shard.git
9+
version: 1.2.5
10+
711
yaml_mapping:
812
git: https://github.com/crystal-lang/yaml_mapping.cr.git
913
version: 0.1.0

shard.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
11
name: crystal2nix
2-
version: 0.1.1
2+
version: 0.2.0
33

44
authors:
55
- Michael Fellinger
66
- Peter Hoeg <[email protected]>
77

88
targets:
99
crystal2nix:
10-
main: src/crystal2nix.cr
10+
main: src/runner.cr
1111

12-
crystal: 0.35.1
12+
crystal: 1.0.0
1313

1414
dependencies:
15+
version_from_shard:
16+
github: hugopl/version_from_shard
1517
json_mapping:
1618
github: crystal-lang/json_mapping.cr
1719
yaml_mapping:

shards.nix

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
json_mapping = {
3+
owner = "crystal-lang";
4+
repo = "json_mapping.cr";
5+
rev = "v0.1.0";
6+
sha256 = "1qq5vs2085x7cwmp96rrjns0yz9kiz1lycxynfbz5psxll6b8p55";
7+
};
8+
version_from_shard = {
9+
owner = "hugopl";
10+
repo = "version_from_shard";
11+
rev = "v1.2.5";
12+
sha256 = "0xizj0q4rd541rwjbx04cjifc2gfx4l5v6q2y7gmd0ndjmkgb8ik";
13+
};
14+
yaml_mapping = {
15+
owner = "crystal-lang";
16+
repo = "yaml_mapping.cr";
17+
rev = "v0.1.0";
18+
sha256 = "02spz1521g59ar6rp0znnr01di766kknbjxjnygs39yn0cmpzqc1";
19+
};
20+
}

src/cli.cr

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
module Crystal2Nix
2+
SHARD_LOCK = "shard.lock"
3+
4+
class Cli
5+
def initialize
6+
@lock_file = SHARD_LOCK
7+
8+
OptionParser.parse do |parser|
9+
parser.banner = "Usage: crystal2nix [arguments]"
10+
parser.on("-l NAME", "--lock-file=NAME", "Lock file name") do |name|
11+
@lock_file = name
12+
end
13+
parser.on("-h", "--help", "Show this help") do
14+
puts parser
15+
exit
16+
end
17+
parser.invalid_option do |flag|
18+
STDERR.puts "ERROR: #{flag} is not a valid option."
19+
STDERR.puts parser
20+
exit(1)
21+
end
22+
23+
unless File.exists? @lock_file
24+
STDERR.puts "ERROR: #{@lock_file} not found"
25+
exit 1
26+
end
27+
end
28+
end
29+
30+
def run
31+
Worker.new(@lock_file).run
32+
end
33+
end
34+
end

src/crystal2nix.cr

Lines changed: 7 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -1,108 +1,13 @@
11
require "json_mapping"
2+
require "option_parser"
23
require "uri"
34
require "yaml_mapping"
5+
require "version_from_shard"
46

5-
module Crystal2Nix
6-
class PrefetchJSON
7-
JSON.mapping(sha256: String)
8-
end
9-
10-
class ShardLock
11-
YAML.mapping(
12-
version: Float32,
13-
shards: Hash(String, Hash(String, String))
14-
)
15-
end
16-
17-
class RepoUrl
18-
@url : URI
19-
@path : Array(String)
20-
21-
def initialize(kind : String, repo : String)
22-
t = case kind
23-
when "git"
24-
repo
25-
when "github"
26-
"https://github.com/#{repo}"
27-
else
28-
ArgumentError.new "Unknown key: #{kind}"
29-
exit 1
30-
end
31-
@url = URI.parse(t).normalize
32-
@path = @url.path.split("/")
33-
end
34-
35-
def github?
36-
@url.host == "github.com"
37-
end
38-
39-
def owner : String
40-
@path[1]
41-
end
42-
43-
def repo : String
44-
github? ? @path[2].gsub(/\.git$/, "") : @path[2]
45-
end
7+
require "./data"
8+
require "./repo"
9+
require "./worker"
4610

47-
def to_s : String
48-
@url.to_s
49-
end
50-
end
51-
52-
class Cli
53-
SHARD_LOCK = "shard.lock"
54-
SHARDS_NIX = "shards.nix"
55-
SUPPORTED_KEYS = %w[git github]
56-
57-
@lock_file : String
58-
59-
def initialize
60-
@lock_file = ARGV.fetch(1, SHARD_LOCK)
61-
unless File.exists? @lock_file
62-
STDERR.puts "ERROR: #{@lock_file} not found"
63-
exit 1
64-
end
65-
end
66-
67-
def run
68-
File.open SHARDS_NIX, "w+" do |file|
69-
file.puts %({)
70-
ShardLock.from_yaml(File.read(@lock_file)).shards.each do |key, value|
71-
url = nil
72-
SUPPORTED_KEYS.each do |k|
73-
url = RepoUrl.new(k, value[k]) if value.has_key?(k)
74-
end
75-
if url.nil?
76-
STDERR.puts "Unable to parse repository entry"
77-
exit 1
78-
end
79-
rev = if value["version"]?
80-
if value["version"] =~ /^(?<version>.+)\+git\.commit\.(?<rev>.+)$/
81-
$~["rev"]
82-
else
83-
"v#{value["version"]}"
84-
end
85-
else
86-
value["commit"]
87-
end
88-
sha256 = ""
89-
args = ["--url", url.to_s, "--rev", rev]
90-
Process.run("nix-prefetch-git", args: args) do |x|
91-
x.error.each_line { |e| puts e }
92-
sha256 = PrefetchJSON.from_json(x.output).sha256
93-
end
94-
95-
file.puts %( #{key} = {)
96-
file.puts %( owner = "#{url.owner}";)
97-
file.puts %( repo = "#{url.repo}";)
98-
file.puts %( rev = "#{rev}";)
99-
file.puts %( sha256 = "#{sha256}";)
100-
file.puts %( };)
101-
end
102-
file.puts %(})
103-
end
104-
end
105-
end
11+
module Crystal2Nix
12+
VersionFromShard.declare
10613
end
107-
108-
Crystal2Nix::Cli.new.run

src/data.cr

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
module Crystal2Nix
2+
class PrefetchJSON
3+
JSON.mapping(sha256: String)
4+
end
5+
6+
class ShardLock
7+
YAML.mapping(
8+
version: Float32,
9+
shards: Hash(String, Hash(String, String))
10+
)
11+
end
12+
end

src/repo.cr

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
module Crystal2Nix
2+
class RepoUrl
3+
@url : URI
4+
@path : Array(String)
5+
6+
def initialize(kind : String, repo : String)
7+
t = case kind
8+
when "git"
9+
repo
10+
when "github"
11+
"https://github.com/#{repo}"
12+
else
13+
ArgumentError.new "Unknown key: #{kind}"
14+
exit 1
15+
end
16+
@url = URI.parse(t).normalize
17+
@path = @url.path.split("/")
18+
end
19+
20+
def github?
21+
@url.host == "github.com"
22+
end
23+
24+
def owner : String
25+
@path[1]
26+
end
27+
28+
def repo : String
29+
github? ? @path[2].gsub(/\.git$/, "") : @path[2]
30+
end
31+
32+
def to_s : String
33+
@url.to_s
34+
end
35+
end
36+
end

src/runner.cr

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
require "./crystal2nix"
2+
require "./cli"
3+
4+
Crystal2Nix::Cli.new.run

src/worker.cr

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
module Crystal2Nix
2+
SHARDS_NIX = "shards.nix"
3+
SUPPORTED_KEYS = %w[git github]
4+
5+
class Worker
6+
def initialize(@lock_file : String)
7+
end
8+
9+
def run
10+
File.open SHARDS_NIX, "w+" do |file|
11+
file.puts %({)
12+
ShardLock.from_yaml(File.read(@lock_file)).shards.each do |key, value|
13+
url = nil
14+
SUPPORTED_KEYS.each do |k|
15+
url = RepoUrl.new(k, value[k]) if value.has_key?(k)
16+
end
17+
if url.nil?
18+
STDERR.puts "Unable to parse repository entry"
19+
exit 1
20+
end
21+
rev = if value["version"]?
22+
if value["version"] =~ /^(?<version>.+)\+git\.commit\.(?<rev>.+)$/
23+
$~["rev"]
24+
else
25+
"v#{value["version"]}"
26+
end
27+
else
28+
value["commit"]
29+
end
30+
sha256 = ""
31+
args = ["--url", url.to_s, "--rev", rev]
32+
Process.run("nix-prefetch-git", args: args) do |x|
33+
x.error.each_line { |e| puts e }
34+
sha256 = PrefetchJSON.from_json(x.output).sha256
35+
end
36+
37+
file.puts %( #{key} = {)
38+
file.puts %( owner = "#{url.owner}";)
39+
file.puts %( repo = "#{url.repo}";)
40+
file.puts %( rev = "#{rev}";)
41+
file.puts %( sha256 = "#{sha256}";)
42+
file.puts %( };)
43+
end
44+
file.puts %(})
45+
end
46+
end
47+
end
48+
end

0 commit comments

Comments
 (0)