Skip to content

Commit d549538

Browse files
committed
fix yaml stdin
1 parent 1b89a2f commit d549538

File tree

5 files changed

+202
-38
lines changed

5 files changed

+202
-38
lines changed

frontend-laminar/src/main/scala/ru/d10xa/jsonlogviewer/ViewElement.scala

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import com.raquo.laminar.DomApi
1212
import ru.d10xa.jsonlogviewer.decline.yaml.ConfigYaml
1313
import ru.d10xa.jsonlogviewer.decline.yaml.Feed
1414
import ru.d10xa.jsonlogviewer.decline.Config
15+
import ru.d10xa.jsonlogviewer.shell.ShellImpl
1516

1617
import scala.util.chaining.*
1718

@@ -61,7 +62,14 @@ object ViewElement {
6162
)
6263
fs2.Stream
6364
.eval(configYamlRefIO)
64-
.flatMap(configYamlRef => LogViewerStream.stream(c, configYamlRef))
65+
.flatMap(configYamlRef =>
66+
LogViewerStream.stream(
67+
c,
68+
configYamlRef,
69+
new StdInLinesStreamImpl,
70+
new ShellImpl
71+
)
72+
)
6573
.compile
6674
.toList
6775
.map(stringsToHtmlElement)

json-log-viewer/jvm/src/main/scala/ru/d10xa/jsonlogviewer/Application.scala

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import fs2.*
88
import ru.d10xa.jsonlogviewer.decline.ConfigInit
99
import ru.d10xa.jsonlogviewer.decline.ConfigInitImpl
1010
import ru.d10xa.jsonlogviewer.decline.DeclineOpts
11+
import ru.d10xa.jsonlogviewer.shell.ShellImpl
1112

1213
object Application
1314
extends CommandIOApp(
@@ -21,14 +22,18 @@ object Application
2122
Supervisor[IO].use { supervisor =>
2223
configInit.initConfigYaml(config, supervisor).use { configRef =>
2324
LogViewerStream
24-
.stream(config, configRef)
25+
.stream(
26+
config = config,
27+
configYamlRef = configRef,
28+
stdinStream = new StdInLinesStreamImpl,
29+
shell = new ShellImpl
30+
)
2531
.through(text.utf8.encode)
2632
.through(fs2.io.stdout)
2733
.compile
2834
.drain
2935
.as(ExitCode.Success)
3036
}
3137
}
32-
3338

3439
}

json-log-viewer/shared/src/main/scala/ru/d10xa/jsonlogviewer/LogViewerStream.scala

Lines changed: 16 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -13,29 +13,20 @@ import ru.d10xa.jsonlogviewer.decline.Config.FormatIn
1313
import ru.d10xa.jsonlogviewer.formatout.ColorLineFormatter
1414
import ru.d10xa.jsonlogviewer.formatout.RawFormatter
1515
import ru.d10xa.jsonlogviewer.logfmt.LogfmtLogLineParser
16+
import ru.d10xa.jsonlogviewer.shell.Shell
1617
import ru.d10xa.jsonlogviewer.shell.ShellImpl
17-
1818
import scala.util.matching.Regex
1919
import scala.util.Failure
2020
import scala.util.Success
2121
import scala.util.Try
2222

2323
object LogViewerStream {
2424

25-
private var stdInLinesStreamImpl: StdInLinesStream =
26-
new StdInLinesStreamImpl()
27-
28-
def getStdInLinesStreamImpl: StdInLinesStream = stdInLinesStreamImpl
29-
30-
def setStdInLinesStreamImpl(impl: StdInLinesStream): Unit =
31-
stdInLinesStreamImpl = impl
32-
33-
private def stdinLinesStream: Stream[IO, String] =
34-
stdInLinesStreamImpl.stdinLinesStream
35-
3625
def stream(
3726
config: Config,
38-
configYamlRef: Ref[IO, Option[ConfigYaml]]
27+
configYamlRef: Ref[IO, Option[ConfigYaml]],
28+
stdinStream: StdInLinesStream,
29+
shell: Shell
3930
): Stream[IO, String] = {
4031
def processStreamWithConfig(
4132
inputStream: Stream[IO, String],
@@ -58,7 +49,7 @@ object LogViewerStream {
5849
Stream.empty
5950
} else if (resolvedConfigs.length > 1) {
6051
val feedStreams = resolvedConfigs.map { resolvedConfig =>
61-
val feedStream = commandsAndInlineInputToStream(
52+
val feedStream = shell.mergeCommandsAndInlineInput(
6253
resolvedConfig.commands,
6354
resolvedConfig.inlineInput
6455
)
@@ -67,14 +58,17 @@ object LogViewerStream {
6758
Stream.emits(feedStreams).parJoin(feedStreams.size)
6859
} else {
6960
val resolvedConfig = resolvedConfigs.head
70-
val inputStream = if (resolvedConfig.inlineInput.isDefined) {
71-
commandsAndInlineInputToStream(
72-
resolvedConfig.commands,
73-
resolvedConfig.inlineInput
74-
)
75-
} else {
76-
stdinLinesStream
77-
}
61+
val inputStream =
62+
if (
63+
resolvedConfig.inlineInput.isDefined || resolvedConfig.commands.nonEmpty
64+
) {
65+
shell.mergeCommandsAndInlineInput(
66+
resolvedConfig.commands,
67+
resolvedConfig.inlineInput
68+
)
69+
} else {
70+
stdinStream.stdinLinesStream
71+
}
7872
processStreamWithConfig(inputStream, resolvedConfig)
7973
}
8074

@@ -213,12 +207,6 @@ object LogViewerStream {
213207
case Failure(_) => parseResult.raw
214208
}
215209

216-
private def commandsAndInlineInputToStream(
217-
commands: List[String],
218-
inlineInput: Option[String]
219-
): Stream[IO, String] =
220-
new ShellImpl().mergeCommandsAndInlineInput(commands, inlineInput)
221-
222210
def makeNonCsvLogLineParser(
223211
resolvedConfig: ResolvedConfig
224212
): LogLineParser = {
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
package ru.d10xa.jsonlogviewer
2+
3+
import cats.effect.IO
4+
import cats.effect.Ref
5+
import fs2.Stream
6+
import munit.CatsEffectSuite
7+
import ru.d10xa.jsonlogviewer.decline.yaml.ConfigYaml
8+
import ru.d10xa.jsonlogviewer.decline.yaml.Feed
9+
import ru.d10xa.jsonlogviewer.decline.Config
10+
import ru.d10xa.jsonlogviewer.decline.FieldNamesConfig
11+
import ru.d10xa.jsonlogviewer.decline.TimestampConfig
12+
import ru.d10xa.jsonlogviewer.shell.Shell
13+
14+
class YamlCommandExecutionTest extends CatsEffectSuite {
15+
16+
private val basicConfig = Config(
17+
configFile = None,
18+
fieldNames = FieldNamesConfig(
19+
timestampFieldName = "@timestamp",
20+
levelFieldName = "level",
21+
messageFieldName = "message",
22+
stackTraceFieldName = "stack_trace",
23+
loggerNameFieldName = "logger_name",
24+
threadNameFieldName = "thread_name"
25+
),
26+
timestamp = TimestampConfig(None, None),
27+
grep = List.empty,
28+
filter = None,
29+
formatIn = None,
30+
formatOut = None,
31+
showEmptyFields = false
32+
)
33+
34+
test("should use commands from YAML when inlineInput is absent") {
35+
// Arrange: Test implementations with unique output
36+
val testStdinStream = new StdInLinesStream {
37+
override def stdinLinesStream: Stream[IO, String] =
38+
Stream.emit("FROM_STDIN")
39+
}
40+
41+
val testShell = new Shell {
42+
override def mergeCommandsAndInlineInput(
43+
commands: List[String],
44+
inlineInput: Option[String]
45+
): Stream[IO, String] =
46+
Stream.emit(s"FROM_COMMAND:${commands.mkString(",")}")
47+
}
48+
49+
// YAML configuration with command but without inlineInput
50+
val configYaml = ConfigYaml(
51+
fieldNames = None,
52+
feeds = Some(
53+
List(
54+
Feed(
55+
name = Some("test-feed"),
56+
commands = List("cat test.log"),
57+
inlineInput = None, // No inline input
58+
filter = None,
59+
formatIn = None,
60+
fieldNames = None,
61+
rawInclude = None,
62+
rawExclude = None,
63+
excludeFields = None,
64+
showEmptyFields = None
65+
)
66+
)
67+
),
68+
showEmptyFields = None
69+
)
70+
71+
val yamlRef = Ref.unsafe[IO, Option[ConfigYaml]](Some(configYaml))
72+
73+
val result = LogViewerStream
74+
.stream(
75+
basicConfig,
76+
yamlRef,
77+
testStdinStream,
78+
testShell
79+
)
80+
.compile
81+
.toList
82+
.unsafeRunSync()
83+
84+
assert(
85+
result.exists(_.contains("FROM_COMMAND")),
86+
"Should use output from commands in YAML"
87+
)
88+
assert(
89+
!result.exists(_.contains("FROM_STDIN")),
90+
"Should not use stdin"
91+
)
92+
}
93+
94+
test("should use stdin when no commands or inlineInput are present") {
95+
val testStdinStream = new StdInLinesStream {
96+
override def stdinLinesStream: Stream[IO, String] =
97+
Stream.emit("FROM_STDIN")
98+
}
99+
100+
val testShell = new Shell {
101+
override def mergeCommandsAndInlineInput(
102+
commands: List[String],
103+
inlineInput: Option[String]
104+
): Stream[IO, String] =
105+
Stream.emit("FROM_COMMAND")
106+
}
107+
108+
val configYaml = ConfigYaml(
109+
fieldNames = None,
110+
feeds = Some(
111+
List(
112+
Feed(
113+
name = Some("test-feed"),
114+
commands = List.empty, // Empty commands list
115+
inlineInput = None, // No inline input
116+
filter = None,
117+
formatIn = None,
118+
fieldNames = None,
119+
rawInclude = None,
120+
rawExclude = None,
121+
excludeFields = None,
122+
showEmptyFields = None
123+
)
124+
)
125+
),
126+
showEmptyFields = None
127+
)
128+
129+
val yamlRef = Ref.unsafe[IO, Option[ConfigYaml]](Some(configYaml))
130+
131+
val result = LogViewerStream
132+
.stream(
133+
basicConfig,
134+
yamlRef,
135+
testStdinStream,
136+
testShell
137+
)
138+
.compile
139+
.toList
140+
.unsafeRunSync()
141+
142+
assert(
143+
result.exists(_.contains("FROM_STDIN")),
144+
"Should use stdin"
145+
)
146+
assert(
147+
!result.exists(_.contains("FROM_COMMAND")),
148+
"Should not use command output when no commands are present"
149+
)
150+
}
151+
}

json-log-viewer/shared/src/test/scala/ru/d10xa/jsonlogviewer/csv/CsvProcessingTest.scala

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package ru.d10xa.jsonlogviewer.csv
22

3-
import cats.effect.unsafe.implicits.global
43
import cats.effect.IO
54
import cats.effect.Ref
65
import fs2.Stream
@@ -9,6 +8,7 @@ import ru.d10xa.jsonlogviewer.decline.yaml.ConfigYaml
98
import ru.d10xa.jsonlogviewer.decline.Config
109
import ru.d10xa.jsonlogviewer.decline.FieldNamesConfig
1110
import ru.d10xa.jsonlogviewer.decline.TimestampConfig
11+
import ru.d10xa.jsonlogviewer.shell.ShellImpl
1212
import ru.d10xa.jsonlogviewer.LogViewerStream
1313
import ru.d10xa.jsonlogviewer.StdInLinesStream
1414

@@ -45,9 +45,15 @@ class CsvProcessingTest extends CatsEffectSuite {
4545
Stream.emits(List(csvHeader, csvLine1, csvLine2))
4646
}
4747

48-
_ <- IO(LogViewerStream.setStdInLinesStreamImpl(testStreamImpl))
49-
50-
results <- LogViewerStream.stream(csvConfig, configRef).compile.toList
48+
results <- LogViewerStream
49+
.stream(
50+
config = csvConfig,
51+
configYamlRef = configRef,
52+
stdinStream = testStreamImpl,
53+
shell = new ShellImpl
54+
)
55+
.compile
56+
.toList
5157

5258
} yield {
5359
assert(results.nonEmpty, "Results should not be empty")
@@ -97,9 +103,15 @@ class CsvProcessingTest extends CatsEffectSuite {
97103
Stream.emits(List(csvHeader, csvLine))
98104
}
99105

100-
_ <- IO(LogViewerStream.setStdInLinesStreamImpl(testStreamImpl))
101-
102-
results <- LogViewerStream.stream(csvConfig, configRef).compile.toList
106+
results <- LogViewerStream
107+
.stream(
108+
config = csvConfig,
109+
configYamlRef = configRef,
110+
stdinStream = testStreamImpl,
111+
shell = new ShellImpl
112+
)
113+
.compile
114+
.toList
103115

104116
} yield {
105117
assert(results.nonEmpty, "Results should not be empty")

0 commit comments

Comments
 (0)