rakit 0.1.8 → 0.1.9

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 618281ffaa52461777b6cf921c5290e89dc503ef845adc9410d4934d917ed285
4
- data.tar.gz: c3b90837302fb00dac1987e6c181307480ab7133fe113dc65805b307e0c2ed3a
3
+ metadata.gz: 625ef9ce05d218d28a9a42e13e8417791f7215f762788ce71de172ed9968da73
4
+ data.tar.gz: 551fd0f49789f7cec7b83a7a0d9f5483089c2bd0faac095e7dd62362931d1142
5
5
  SHA512:
6
- metadata.gz: 9c9b06b9a2fce44ff8cb4b99993c2a6caff13a9b5155cb2202b23000faccdc82853201134bff2cef57bd17400e038d86d6ef3437239c26409587ed78ef3b3c30
7
- data.tar.gz: 4b3624c2093bde3d3f0a42959a511793e231dc2fba0a6e2cf7baac4613812355764a11a195cd76ec8abfa7c082813e38243e7276e94de19505fd33499827d0ca
6
+ metadata.gz: 2beeea6a957517741246af04634b252d05023b067b4f2253c8953d7b227d9dcd5a0f1cd83363fe09810fea382599de6e6ee4a78de16d26bcbbce494a3a80e079
7
+ data.tar.gz: 2282fa15d28d2c8be932187a147c43f0c4a6d43afe83dcd5c7ffa27d5b03bd7f2c81e64eb78f9a43a2a6b263a4ead085d598ffbe04e8a571dc4b542e1bebc409
data/exe/rakit CHANGED
@@ -1,8 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- # CLI for rakit gem. Subcommands: markdown (pdf|amalgamate), file (list|copy), word-count (--json-keys), static-web-server (start|stop|running|publish).
5
- # CLI for rakit gem. Subcommands: file (list|copy), word-count (--json-keys), static-web-server (start|stop|running|publish), word-cloud (status|install|generate).
4
+ # CLI for rakit gem. Subcommands: markdown (amalgamate|disaggregate|validate), file (list|copy), word-count, word-cloud, static-web-server (start|stop|running|publish|view).
6
5
 
7
6
  require "rakit"
8
7
 
@@ -17,18 +16,30 @@ def usage_stderr(msg = nil)
17
16
  $stderr.puts " file list <directory> [--recursive] [--include-hidden] [--format console|json|proto-json]"
18
17
  $stderr.puts " file copy <source> <destination> [--overwrite] [--create-directories] [--format ...]"
19
18
  $stderr.puts " word-count <file>|--stdin --json-keys [--format console|json|proto-json] [options]"
20
- $stderr.puts " static-web-server <start|stop|running|publish> [options] [args]"
19
+ $stderr.puts " markdown amalgamate <root_dir> --out <output_path>"
20
+ $stderr.puts " markdown disaggregate <markdown_path> --out <output_root_dir>"
21
+ $stderr.puts " markdown validate <root_dir>"
22
+ $stderr.puts " static-web-server <start|stop|running|publish|view> [options] [args]"
21
23
  $stderr.puts " word-cloud <status|install|generate> [options] [args]"
24
+ $stderr.puts " start [--port PORT] Start server (idempotent)"
25
+ $stderr.puts " stop Stop server"
26
+ $stderr.puts " running Exit 0 if running, non-zero otherwise"
27
+ $stderr.puts " publish <site_name> <source_dir> Publish static site"
28
+ $stderr.puts " view [path] Open path in browser (default /louparslow/rakit/index.html)"
22
29
  end
23
30
 
24
31
  def main(argv = ARGV)
25
32
  return usage_stderr("Expected subcommand.") if argv.empty?
26
33
 
27
34
  sub = argv[0]
28
- if sub == "markdown"
29
- argv.shift
30
- require "rakit/cli/markdown"
31
- return Rakit::CLI::Markdown.run(argv)
35
+ if sub == "--version" || sub == "-v"
36
+ spec = Gem.loaded_specs["rakit"]
37
+ puts spec ? "#{spec.name} #{spec.version}" : "rakit (version unknown)"
38
+ return 0
39
+ end
40
+ if sub == "--help" || sub == "-h"
41
+ usage_stderr
42
+ return 0
32
43
  end
33
44
 
34
45
  if sub == "file"
@@ -43,6 +54,82 @@ def main(argv = ARGV)
43
54
  return Rakit::CLI::WordCount.run(argv)
44
55
  end
45
56
 
57
+ if sub == "markdown"
58
+ argv.shift
59
+ cmd = argv.shift
60
+ begin
61
+ case cmd
62
+ when "amalgamate"
63
+ root_dir = argv.shift
64
+ out_idx = argv.index("--out")
65
+ output_path = out_idx && argv[out_idx + 1] ? argv[out_idx + 1] : nil
66
+ unless root_dir && output_path
67
+ usage_stderr("markdown amalgamate requires <root_dir> and --out <output_path>")
68
+ return 1
69
+ end
70
+ doc = Rakit::Markdown.load_document(root_dir: root_dir)
71
+ Rakit::Markdown.amalgamate(document: doc, output_path: output_path)
72
+ return 0
73
+ when "disaggregate"
74
+ md_path = argv.shift
75
+ out_idx = argv.index("--out")
76
+ output_root = out_idx && argv[out_idx + 1] ? argv[out_idx + 1] : nil
77
+ unless md_path && output_root
78
+ usage_stderr("markdown disaggregate requires <markdown_path> and --out <output_root_dir>")
79
+ return 1
80
+ end
81
+ Rakit::Markdown.disaggregate(markdown_path: md_path, output_root_dir: output_root)
82
+ return 0
83
+ when "validate"
84
+ root_dir = argv.shift
85
+ unless root_dir
86
+ usage_stderr("markdown validate requires <root_dir>")
87
+ return 1
88
+ end
89
+ if Rakit::Markdown.validate(root_dir: root_dir)
90
+ return 0
91
+ else
92
+ Rakit::Markdown.validation_failures.each { |msg| $stderr.puts msg }
93
+ return 1
94
+ end
95
+ when "merge"
96
+ source_dir = argv.shift
97
+ target_path = argv.shift
98
+ create_dirs = argv.include?("--create-directories")
99
+ unless source_dir && target_path
100
+ usage_stderr("markdown merge requires <source_dir> and <target_path>")
101
+ return 1
102
+ end
103
+ result = Rakit::Markdown.merge(source_dir, target_path, create_directories: create_dirs)
104
+ unless result[:success]
105
+ $stderr.puts result[:message] if result[:message].to_s.length > 0
106
+ return 1
107
+ end
108
+ return 0
109
+ when "pdf"
110
+ input_md = argv.shift
111
+ output_pdf = argv.shift
112
+ unless input_md
113
+ usage_stderr("markdown pdf requires <input.md>")
114
+ return 1
115
+ end
116
+ result = Rakit::Markdown.generate_pdf(input_md, output_pdf)
117
+ unless result[:success]
118
+ $stderr.puts result[:message] if result[:message].to_s.length > 0
119
+ $stderr.puts result[:stderr] if result[:stderr].to_s.length > 0
120
+ return 1
121
+ end
122
+ return 0
123
+ else
124
+ usage_stderr(cmd ? "markdown: use amalgamate, disaggregate, validate, merge, or pdf" : "markdown requires a command")
125
+ return 1
126
+ end
127
+ rescue ArgumentError, Errno::ENOENT, Errno::EACCES => e
128
+ $stderr.puts e.message
129
+ return 1
130
+ end
131
+ end
132
+
46
133
  if sub == "word-cloud"
47
134
  argv.shift
48
135
  require "rakit/cli/word_cloud"
@@ -65,6 +152,7 @@ def main(argv = ARGV)
65
152
  end
66
153
  end
67
154
  Rakit::StaticWebServer.start(port: port)
155
+ puts "http://localhost:#{port}"
68
156
  return 0
69
157
  when "stop"
70
158
  Rakit::StaticWebServer.stop
@@ -80,6 +168,16 @@ def main(argv = ARGV)
80
168
  end
81
169
  Rakit::StaticWebServer.publish(site_name, source_dir)
82
170
  return 0
171
+ when "view"
172
+ # Default to project Hugo docs index (same as rake view_docs)
173
+ path = argv.shift || "/louparslow/rakit/index.html"
174
+ begin
175
+ Rakit::StaticWebServer.view(path)
176
+ return 0
177
+ rescue RuntimeError => e
178
+ $stderr.puts e.message
179
+ return 1
180
+ end
83
181
  else
84
182
  usage_stderr(cmd ? "Unknown command: #{cmd}" : "Expected command after static-web-server.")
85
183
  return 1
@@ -7,7 +7,7 @@ require 'google/protobuf'
7
7
 
8
8
  descriptor_data = "\n\x12\x61zure.devops.proto\x12\x0brakit.azure\"L\n\x08Pipeline\x12\x0b\n\x03org\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0bpipeline_id\x18\x03 \x01(\x05\x12\r\n\x05token\x18\x04 \x01(\t\"R\n\x18GetPipelineResultRequest\x12\'\n\x08pipeline\x18\x01 \x01(\x0b\x32\x15.rakit.azure.Pipeline\x12\r\n\x05token\x18\x02 \x01(\t\"C\n\x0ePipelineStatus\x12\x0f\n\x07success\x18\x01 \x01(\x08\x12\x0e\n\x06\x65rrors\x18\x02 \x03(\t\x12\x10\n\x08warnings\x18\x03 \x03(\t\"8\n\x0ePipelineResult\x12&\n\x04runs\x18\x01 \x03(\x0b\x32\x18.rakit.azure.PipelineRun\"\x97\x01\n\x0bPipelineRun\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\r\n\x05state\x18\x03 \x01(\t\x12\x0e\n\x06result\x18\x04 \x01(\t\x12\x14\n\x0c\x63reated_date\x18\x05 \x01(\t\x12\x15\n\rfinished_date\x18\x06 \x01(\t\x12\"\n\x06stages\x18\x07 \x03(\x0b\x32\x12.rakit.azure.Stage\"&\n\x05Issue\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0f\n\x07message\x18\x02 \x01(\t\"G\n\x03Job\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06result\x18\x02 \x01(\t\x12\"\n\x06issues\x18\x03 \x03(\x0b\x32\x12.rakit.azure.Issue\"i\n\x05Stage\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06result\x18\x02 \x01(\t\x12\x1e\n\x04jobs\x18\x03 \x03(\x0b\x32\x10.rakit.azure.Job\x12\"\n\x06issues\x18\x04 \x03(\x0b\x32\x12.rakit.azure.Issue\"`\n\x0eTimelineRecord\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04type\x18\x02 \x01(\t\x12\x0e\n\x06result\x18\x03 \x01(\t\x12\"\n\x06issues\x18\x04 \x03(\x0b\x32\x12.rakit.azure.Issue\"\xa8\x01\n\x14PipelineResultDetail\x12\x12\n\nsuccessful\x18\x01 \x01(\x08\x12\x0e\n\x06\x65rrors\x18\x02 \x01(\t\x12\x10\n\x08warnings\x18\x03 \x01(\t\x12%\n\x03run\x18\x04 \x01(\x0b\x32\x18.rakit.azure.PipelineRun\x12\x33\n\x0e\x66\x61iled_records\x18\x05 \x03(\x0b\x32\x1b.rakit.azure.TimelineRecord2i\n\x0ePipelineServer\x12W\n\x11GetPipelineResult\x12%.rakit.azure.GetPipelineResultRequest\x1a\x1b.rakit.azure.PipelineResultB\x0f\xea\x02\x0cRakit::Azureb\x06proto3"
9
9
 
10
- pool = ::Google::Protobuf::DescriptorPool.generated_pool
10
+ pool = Google::Protobuf::DescriptorPool.generated_pool
11
11
  pool.add_serialized_file(descriptor_data)
12
12
 
13
13
  module Rakit
@@ -7,7 +7,7 @@ require 'google/protobuf'
7
7
 
8
8
  descriptor_data = "\n\rexample.proto\x12\rrakit.example\"\x1c\n\x0cHelloRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\" \n\rHelloResponse\x12\x0f\n\x07message\x18\x01 \x01(\tB\x13\xea\x02\x10Rakit::Generatedb\x06proto3"
9
9
 
10
- pool = ::Google::Protobuf::DescriptorPool.generated_pool
10
+ pool = Google::Protobuf::DescriptorPool.generated_pool
11
11
  pool.add_serialized_file(descriptor_data)
12
12
 
13
13
  module Rakit
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # source: rakit.azure.proto
4
+
5
+ require 'google/protobuf'
6
+
7
+
8
+ descriptor_data = "\n\x11rakit.azure.proto\x12\x0brakit.azure\"L\n\x08Pipeline\x12\x0b\n\x03org\x18\x01 \x01(\t\x12\x0f\n\x07project\x18\x02 \x01(\t\x12\x13\n\x0bpipeline_id\x18\x03 \x01(\x05\x12\r\n\x05token\x18\x04 \x01(\t\"R\n\x18GetPipelineResultRequest\x12\'\n\x08pipeline\x18\x01 \x01(\x0b\x32\x15.rakit.azure.Pipeline\x12\r\n\x05token\x18\x02 \x01(\t\"C\n\x0ePipelineStatus\x12\x0f\n\x07success\x18\x01 \x01(\x08\x12\x0e\n\x06\x65rrors\x18\x02 \x03(\t\x12\x10\n\x08warnings\x18\x03 \x03(\t\"8\n\x0ePipelineResult\x12&\n\x04runs\x18\x01 \x03(\x0b\x32\x18.rakit.azure.PipelineRun\"\x97\x01\n\x0bPipelineRun\x12\n\n\x02id\x18\x01 \x01(\x05\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\r\n\x05state\x18\x03 \x01(\t\x12\x0e\n\x06result\x18\x04 \x01(\t\x12\x14\n\x0c\x63reated_date\x18\x05 \x01(\t\x12\x15\n\rfinished_date\x18\x06 \x01(\t\x12\"\n\x06stages\x18\x07 \x03(\x0b\x32\x12.rakit.azure.Stage\"&\n\x05Issue\x12\x0c\n\x04type\x18\x01 \x01(\t\x12\x0f\n\x07message\x18\x02 \x01(\t\"G\n\x03Job\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06result\x18\x02 \x01(\t\x12\"\n\x06issues\x18\x03 \x03(\x0b\x32\x12.rakit.azure.Issue\"i\n\x05Stage\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0e\n\x06result\x18\x02 \x01(\t\x12\x1e\n\x04jobs\x18\x03 \x03(\x0b\x32\x10.rakit.azure.Job\x12\"\n\x06issues\x18\x04 \x03(\x0b\x32\x12.rakit.azure.Issue\"`\n\x0eTimelineRecord\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04type\x18\x02 \x01(\t\x12\x0e\n\x06result\x18\x03 \x01(\t\x12\"\n\x06issues\x18\x04 \x03(\x0b\x32\x12.rakit.azure.Issue\"\xa8\x01\n\x14PipelineResultDetail\x12\x12\n\nsuccessful\x18\x01 \x01(\x08\x12\x0e\n\x06\x65rrors\x18\x02 \x01(\t\x12\x10\n\x08warnings\x18\x03 \x01(\t\x12%\n\x03run\x18\x04 \x01(\x0b\x32\x18.rakit.azure.PipelineRun\x12\x33\n\x0e\x66\x61iled_records\x18\x05 \x03(\x0b\x32\x1b.rakit.azure.TimelineRecord2i\n\x0ePipelineServer\x12W\n\x11GetPipelineResult\x12%.rakit.azure.GetPipelineResultRequest\x1a\x1b.rakit.azure.PipelineResultB\x0f\xea\x02\x0cRakit::Azureb\x06proto3"
9
+
10
+ pool = ::Google::Protobuf::DescriptorPool.generated_pool
11
+ pool.add_serialized_file(descriptor_data)
12
+
13
+ module Rakit
14
+ module Azure
15
+ Pipeline = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("rakit.azure.Pipeline").msgclass
16
+ GetPipelineResultRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("rakit.azure.GetPipelineResultRequest").msgclass
17
+ PipelineStatus = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("rakit.azure.PipelineStatus").msgclass
18
+ PipelineResult = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("rakit.azure.PipelineResult").msgclass
19
+ PipelineRun = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("rakit.azure.PipelineRun").msgclass
20
+ Issue = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("rakit.azure.Issue").msgclass
21
+ Job = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("rakit.azure.Job").msgclass
22
+ Stage = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("rakit.azure.Stage").msgclass
23
+ TimelineRecord = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("rakit.azure.TimelineRecord").msgclass
24
+ PipelineResultDetail = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("rakit.azure.PipelineResultDetail").msgclass
25
+ end
26
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # source: rakit.docfx.proto
4
+
5
+ require 'google/protobuf'
6
+
7
+
8
+ descriptor_data = "\n\x11rakit.docfx.proto\x12\x0brakit.docfx\"6\n\x0c\x42uildRequest\x12\x12\n\nsource_dir\x18\x01 \x01(\t\x12\x12\n\noutput_dir\x18\x02 \x01(\t\"/\n\x0b\x42uildResult\x12\x0f\n\x07success\x18\x01 \x01(\x08\x12\x0f\n\x07message\x18\x02 \x01(\tB\x13\xea\x02\x10Rakit::Generatedb\x06proto3"
9
+
10
+ pool = ::Google::Protobuf::DescriptorPool.generated_pool
11
+ pool.add_serialized_file(descriptor_data)
12
+
13
+ module Rakit
14
+ module Generated
15
+ BuildRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("rakit.docfx.BuildRequest").msgclass
16
+ BuildResult = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("rakit.docfx.BuildResult").msgclass
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # source: rakit.example.proto
4
+
5
+ require 'google/protobuf'
6
+
7
+
8
+ descriptor_data = "\n\x13rakit.example.proto\x12\rrakit.example\"\x1c\n\x0cHelloRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\" \n\rHelloResponse\x12\x0f\n\x07message\x18\x01 \x01(\tB\x13\xea\x02\x10Rakit::Generatedb\x06proto3"
9
+
10
+ pool = ::Google::Protobuf::DescriptorPool.generated_pool
11
+ pool.add_serialized_file(descriptor_data)
12
+
13
+ module Rakit
14
+ module Generated
15
+ HelloRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("rakit.example.HelloRequest").msgclass
16
+ HelloResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("rakit.example.HelloResponse").msgclass
17
+ end
18
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # source: rakit.markdown.proto
4
+
5
+ require 'google/protobuf'
6
+
7
+
8
+ descriptor_data = "\n\x14rakit.markdown.proto\x12\x0erakit.markdown\"r\n\x07Section\x12\n\n\x02id\x18\x01 \x01(\t\x12\r\n\x05title\x18\x02 \x01(\t\x12\x0c\n\x04\x62ody\x18\x03 \x01(\t\x12\x13\n\x0bsource_path\x18\x04 \x01(\t\x12)\n\x08sections\x18\x05 \x03(\x0b\x32\x17.rakit.markdown.Section\"V\n\x08\x44ocument\x12\r\n\x05title\x18\x01 \x01(\t\x12\x10\n\x08root_dir\x18\x02 \x01(\t\x12)\n\x08sections\x18\x03 \x03(\x0b\x32\x17.rakit.markdown.Section\"3\n\x10ValidationResult\x12\r\n\x05valid\x18\x01 \x01(\x08\x12\x10\n\x08\x66\x61ilures\x18\x02 \x03(\tb\x06proto3"
9
+
10
+ pool = ::Google::Protobuf::DescriptorPool.generated_pool
11
+ pool.add_serialized_file(descriptor_data)
12
+
13
+ module Rakit
14
+ module Markdown
15
+ Section = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("rakit.markdown.Section").msgclass
16
+ Document = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("rakit.markdown.Document").msgclass
17
+ ValidationResult = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("rakit.markdown.ValidationResult").msgclass
18
+ end
19
+ end
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # source: rakit.shell.proto
4
+
5
+ require 'google/protobuf'
6
+
7
+
8
+ descriptor_data = "\n\x11rakit.shell.proto\x12\x0brakit.shell\"\x9a\x02\n\x07\x43ommand\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04\x61rgs\x18\x02 \x03(\t\x12\x19\n\x11working_directory\x18\x03 \x01(\t\x12\x17\n\x0ftimeout_seconds\x18\x04 \x01(\x05\x12\x1a\n\x12\x65xpected_exit_code\x18\x05 \x01(\x05\x12\x17\n\x0f\x65xpected_stdout\x18\x06 \x01(\t\x12\x17\n\x0f\x65xpected_stderr\x18\x07 \x01(\t\x12<\n\x13\x61\x63\x63\x65ptance_criteria\x18\x08 \x03(\x0b\x32\x1f.rakit.shell.AcceptanceCriteria\x12\x13\n\x0b\x65xit_status\x18\t \x01(\x05\x12\x0e\n\x06stdout\x18\n \x01(\t\x12\x0e\n\x06stderr\x18\x0b \x01(\t\"1\n\x12\x41\x63\x63\x65ptanceCriteria\x12\x0c\n\x04kind\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\"-\n\nTestResult\x12\x0f\n\x07success\x18\x01 \x01(\x08\x12\x0e\n\x06\x65rrors\x18\x02 \x03(\t\"b\n\rFormatRequest\x12%\n\x07\x63ommand\x18\x01 \x01(\x0b\x32\x14.rakit.shell.Command\x12*\n\x06\x66ormat\x18\x02 \x01(\x0e\x32\x1a.rakit.shell.CommandFormat\" \n\x0e\x46ormatResponse\x12\x0e\n\x06output\x18\x01 \x01(\t*Z\n\rCommandFormat\x12\x1e\n\x1a\x43OMMAND_FORMAT_UNSPECIFIED\x10\x00\x12\x0c\n\x08ONE_LINE\x10\x01\x12\x0e\n\nMULTI_LINE\x10\x02\x12\x0b\n\x07\x43OMPACT\x10\x03\x32\xc1\x01\n\x0e\x43ommandService\x12\x35\n\x07\x45xecute\x12\x14.rakit.shell.Command\x1a\x14.rakit.shell.Command\x12\x35\n\x04Test\x12\x14.rakit.shell.Command\x1a\x17.rakit.shell.TestResult\x12\x41\n\x06\x46ormat\x12\x1a.rakit.shell.FormatRequest\x1a\x1b.rakit.shell.FormatResponseB\x0f\xea\x02\x0cRakit::Shellb\x06proto3"
9
+
10
+ pool = ::Google::Protobuf::DescriptorPool.generated_pool
11
+ pool.add_serialized_file(descriptor_data)
12
+
13
+ module Rakit
14
+ module Shell
15
+ Command = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("rakit.shell.Command").msgclass
16
+ AcceptanceCriteria = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("rakit.shell.AcceptanceCriteria").msgclass
17
+ TestResult = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("rakit.shell.TestResult").msgclass
18
+ FormatRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("rakit.shell.FormatRequest").msgclass
19
+ FormatResponse = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("rakit.shell.FormatResponse").msgclass
20
+ CommandFormat = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("rakit.shell.CommandFormat").enummodule
21
+ end
22
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # source: rakit.static_web_server.proto
4
+
5
+ require 'google/protobuf'
6
+
7
+
8
+ descriptor_data = "\n\x1drakit.static_web_server.proto\x12\x17rakit.static_web_server\"T\n\x15StaticWebServerConfig\x12\x16\n\x0eroot_directory\x18\x01 \x01(\t\x12\x0c\n\x04port\x18\x02 \x01(\r\x12\x15\n\rhttps_enabled\x18\x03 \x01(\x08\"=\n\x0ePublishRequest\x12\x11\n\tsite_name\x18\x01 \x01(\t\x12\x18\n\x10source_directory\x18\x02 \x01(\t\"1\n\rPublishResult\x12\x0f\n\x07success\x18\x01 \x01(\x08\x12\x0f\n\x07message\x18\x02 \x01(\t\"-\n\x0cServerStatus\x12\x0f\n\x07running\x18\x01 \x01(\x08\x12\x0c\n\x04port\x18\x02 \x01(\rB\x13\xea\x02\x10Rakit::Generatedb\x06proto3"
9
+
10
+ pool = ::Google::Protobuf::DescriptorPool.generated_pool
11
+ pool.add_serialized_file(descriptor_data)
12
+
13
+ module Rakit
14
+ module Generated
15
+ StaticWebServerConfig = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("rakit.static_web_server.StaticWebServerConfig").msgclass
16
+ PublishRequest = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("rakit.static_web_server.PublishRequest").msgclass
17
+ PublishResult = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("rakit.static_web_server.PublishResult").msgclass
18
+ ServerStatus = ::Google::Protobuf::DescriptorPool.generated_pool.lookup("rakit.static_web_server.ServerStatus").msgclass
19
+ end
20
+ end
@@ -7,7 +7,7 @@ require "net/http"
7
7
  require "uri"
8
8
 
9
9
  begin
10
- require "generated/azure.devops_pb"
10
+ require "generated/rakit.azure_pb"
11
11
  rescue StandardError
12
12
  # google-protobuf not available or version conflict (e.g. running without bundle exec)
13
13
  end
@@ -0,0 +1,72 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fileutils"
4
+
5
+ module Rakit
6
+ # Build Docfx static documentation sites from source. Used by task :docfx and tests.
7
+ # Contract: specs/010-docfx/contracts/ruby-api.md
8
+ module Docfx
9
+ class << self
10
+ attr_accessor :docfx_path
11
+
12
+ def docfx_path
13
+ @docfx_path ||= "docfx"
14
+ end
15
+
16
+ # @param source_dir [String] path to Docfx source (must exist and be a directory)
17
+ # @param output_dir [String] path for build output
18
+ # @return [true] on success
19
+ # @return [false] on failure (Docfx not found, build failed, or invalid paths). Idempotent: repeated runs overwrite output_dir.
20
+ def build(source_dir:, output_dir:)
21
+ source_dir = ::File.expand_path(source_dir)
22
+ output_dir = ::File.expand_path(output_dir)
23
+ return false unless ::File.directory?(source_dir)
24
+ return false if ::File.file?(source_dir)
25
+
26
+ # Ensure output_dir can be created (parent writable)
27
+ parent = ::File.dirname(output_dir)
28
+ return false unless parent != output_dir
29
+ begin
30
+ FileUtils.mkdir_p(output_dir)
31
+ rescue Errno::EACCES, Errno::EROFS, Errno::EEXIST, Errno::ENOTDIR
32
+ return false
33
+ end
34
+
35
+ bin = docfx_path
36
+ resolved = ::File.absolute_path?(bin) && ::File.executable?(bin) ? bin : which(bin)
37
+ return false unless resolved
38
+ bin = resolved
39
+
40
+ out_abs = output_dir
41
+ success = Dir.chdir(source_dir) do
42
+ system(bin, "build", "-o", out_abs, out: $stdout, err: $stderr)
43
+ end
44
+ return false unless success
45
+ return false unless ::File.directory?(out_abs) && (Dir.entries(out_abs) - %w[. ..]).any?
46
+
47
+ true
48
+ end
49
+
50
+ # @param source_dir [String] path to check
51
+ # @return [Boolean] true if docfx.json exists under source_dir
52
+ def valid_source?(source_dir)
53
+ dir = ::File.expand_path(source_dir)
54
+ return false unless ::File.directory?(dir)
55
+ ::File.file?(::File.join(dir, "docfx.json"))
56
+ end
57
+
58
+ private
59
+
60
+ def which(cmd)
61
+ exts = ENV["PATHEXT"] ? ENV["PATHEXT"].split(::File::PATH_SEPARATOR) : [""]
62
+ ENV["PATH"].split(::File::PATH_SEPARATOR).each do |path|
63
+ exts.each do |ext|
64
+ exe = ::File.join(path, "#{cmd}#{ext}")
65
+ return exe if ::File.executable?(exe) && !::File.directory?(exe)
66
+ end
67
+ end
68
+ nil
69
+ end
70
+ end
71
+ end
72
+ end
data/lib/rakit/gem.rb CHANGED
@@ -67,6 +67,10 @@ module Rakit
67
67
  end
68
68
 
69
69
  def self.version_published?(name, version)
70
+ # If a version >= this one is already published (e.g. latest is higher), treat as published.
71
+ latest = latest_remote_version(name)
72
+ return true if latest && ::Gem::Version.new(latest) >= ::Gem::Version.new(version)
73
+
70
74
  begin
71
75
  return true if version_published_gem_list?(name, version)
72
76
  rescue StandardError
@@ -85,6 +89,21 @@ module Rakit
85
89
  false
86
90
  end
87
91
 
92
+ # Return the latest version string for name on the remote, or nil on error.
93
+ def self.latest_remote_version(name)
94
+ out, _err, status = Open3.capture3("gem", "list", name, "--remote")
95
+ return nil unless status.success?
96
+ # Format: "name (1.0.0)" for latest only, or "name (1.0.0, 0.9.0)" with --all
97
+ out.each_line do |line|
98
+ next unless line.include?(name)
99
+ if line =~ /\s*#{Regexp.escape(name)}\s*\(([^)]+)\)/
100
+ versions = Regexp.last_match(1).split(",").map(&:strip)
101
+ return versions.max { |a, b| ::Gem::Version.new(a) <=> ::Gem::Version.new(b) }
102
+ end
103
+ end
104
+ nil
105
+ end
106
+
88
107
  # Run `gem list NAME --remote` and check if version appears in the output.
89
108
  def self.version_published_gem_list?(name, version)
90
109
  out, err, status = Open3.capture3("gem", "list", name, "--remote")
data/lib/rakit/hugo.rb ADDED
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "fileutils"
4
+
5
+ module Rakit
6
+ # Build Hugo static sites from source. Used by publish_docs and tests.
7
+ # Contract: specs/008-hugo-docs-site/contracts/ruby-api.md
8
+ module Hugo
9
+ class << self
10
+ attr_accessor :hugo_path
11
+
12
+ def hugo_path
13
+ @hugo_path ||= "hugo"
14
+ end
15
+
16
+ # @param site_dir [String] path to Hugo source (must exist and be a directory)
17
+ # @param out_dir [String] path for build output
18
+ # @return [true] on success
19
+ # @return [false] on failure (Hugo not found, build failed, or invalid site_dir)
20
+ def build(site_dir:, out_dir:)
21
+ site_dir = ::File.expand_path(site_dir)
22
+ out_dir = ::File.expand_path(out_dir)
23
+ return false unless ::File.directory?(site_dir)
24
+ return false if ::File.file?(site_dir)
25
+
26
+ FileUtils.mkdir_p(out_dir)
27
+ success = system(hugo_path, "-s", site_dir, "-d", out_dir, out: $stdout, err: $stderr)
28
+ return false unless success
29
+ return false unless ::File.directory?(out_dir) && (Dir.entries(out_dir) - %w[. ..]).any?
30
+
31
+ true
32
+ end
33
+
34
+ # @param site_dir [String] path to check
35
+ # @return [Boolean] true if config.toml or config.yaml exists under site_dir
36
+ def valid_site?(site_dir)
37
+ dir = ::File.expand_path(site_dir)
38
+ return false unless ::File.directory?(dir)
39
+ ::File.file?(::File.join(dir, "config.toml")) || ::File.file?(::File.join(dir, "config.yaml"))
40
+ end
41
+ end
42
+ end
43
+ end