6
6
import os
7
7
import re
8
8
import shlex
9
+ import shutil
9
10
import subprocess
10
11
import sys
11
12
import types
@@ -1748,7 +1749,11 @@ def test_parse_prompt(prompt_http_calls: None, capsys: pytest.CaptureFixture[str
1748
1749
assert capsys .readouterr ().out == snapshot ('This is the prompt\n ' )
1749
1750
1750
1751
1751
- def test_parse_prompt_codex (prompt_http_calls : None , capsys : pytest .CaptureFixture [str ], tmp_path : Path ) -> None :
1752
+ def test_parse_prompt_codex (
1753
+ prompt_http_calls : None , capsys : pytest .CaptureFixture [str ], tmp_path : Path , monkeypatch : pytest .MonkeyPatch
1754
+ ) -> None :
1755
+ monkeypatch .setattr (shutil , 'which' , lambda x : True ) # type: ignore
1756
+
1752
1757
codex_path = tmp_path / 'codex'
1753
1758
codex_path .mkdir ()
1754
1759
codex_config_path = codex_path / 'config.toml'
@@ -1772,13 +1777,28 @@ def test_parse_prompt_codex(prompt_http_calls: None, capsys: pytest.CaptureFixtu
1772
1777
""" )
1773
1778
1774
1779
1780
+ def test_parse_prompt_codex_not_installed (
1781
+ prompt_http_calls : None , capsys : pytest .CaptureFixture [str ], tmp_path : Path , monkeypatch : pytest .MonkeyPatch
1782
+ ) -> None :
1783
+ monkeypatch .setattr (shutil , 'which' , lambda x : False ) # type: ignore
1784
+
1785
+ with pytest .raises (SystemExit ):
1786
+ main (['prompt' , '--project' , 'fake_org/myproject' , 'fix-span-issue:123' , '--codex' ])
1787
+
1788
+ assert capsys .readouterr ().err == snapshot ("""\
1789
+ codex is not installed. Install `codex`, or remove the `--codex` flag.
1790
+ """ )
1791
+
1792
+
1775
1793
def test_parse_prompt_codex_config_not_found (
1776
- prompt_http_calls : None , capsys : pytest .CaptureFixture [str ], tmp_path : Path
1794
+ prompt_http_calls : None , capsys : pytest .CaptureFixture [str ], tmp_path : Path , monkeypatch : pytest . MonkeyPatch
1777
1795
) -> None :
1796
+ monkeypatch .setattr (shutil , 'which' , lambda x : True ) # type: ignore
1797
+
1778
1798
codex_path = tmp_path / 'codex'
1779
1799
codex_path .mkdir ()
1780
1800
1781
- with patch .dict (os .environ , {'CODEX_HOME' : str (codex_path )}):
1801
+ with patch .dict (os .environ , {'CODEX_HOME' : str (codex_path )}), pytest . raises ( SystemExit ) :
1782
1802
main (['prompt' , '--project' , 'fake_org/myproject' , 'fix-span-issue:123' , '--codex' ])
1783
1803
1784
1804
assert capsys .readouterr ().err == snapshot (
@@ -1787,8 +1807,10 @@ def test_parse_prompt_codex_config_not_found(
1787
1807
1788
1808
1789
1809
def test_parse_prompt_codex_logfire_mcp_installed (
1790
- prompt_http_calls : None , capsys : pytest .CaptureFixture [str ], tmp_path : Path
1810
+ prompt_http_calls : None , capsys : pytest .CaptureFixture [str ], tmp_path : Path , monkeypatch : pytest . MonkeyPatch
1791
1811
) -> None :
1812
+ monkeypatch .setattr (shutil , 'which' , lambda x : True ) # type: ignore
1813
+
1792
1814
codex_path = tmp_path / 'codex'
1793
1815
codex_path .mkdir ()
1794
1816
codex_config_path = codex_path / 'config.toml'
@@ -1803,6 +1825,8 @@ def test_parse_prompt_codex_logfire_mcp_installed(
1803
1825
def test_parse_prompt_claude (
1804
1826
prompt_http_calls : None , capsys : pytest .CaptureFixture [str ], monkeypatch : pytest .MonkeyPatch
1805
1827
) -> None :
1828
+ monkeypatch .setattr (shutil , 'which' , lambda x : True ) # type: ignore
1829
+
1806
1830
def logfire_mcp_installed (_ : list [str ]) -> bytes :
1807
1831
return b'logfire-mcp is installed'
1808
1832
@@ -1812,9 +1836,24 @@ def logfire_mcp_installed(_: list[str]) -> bytes:
1812
1836
assert capsys .readouterr ().out == snapshot ('This is the prompt\n ' )
1813
1837
1814
1838
1839
+ def test_parse_prompt_claude_not_installed (
1840
+ prompt_http_calls : None , capsys : pytest .CaptureFixture [str ], monkeypatch : pytest .MonkeyPatch
1841
+ ) -> None :
1842
+ monkeypatch .setattr (shutil , 'which' , lambda x : False ) # type: ignore
1843
+
1844
+ with pytest .raises (SystemExit ):
1845
+ main (['prompt' , '--project' , 'fake_org/myproject' , 'fix-span-issue:123' , '--claude' ])
1846
+
1847
+ assert capsys .readouterr ().err == snapshot ("""\
1848
+ claude is not installed. Install `claude`, or remove the `--claude` flag.
1849
+ """ )
1850
+
1851
+
1815
1852
def test_parse_prompt_claude_no_mcp (
1816
1853
prompt_http_calls : None , capsys : pytest .CaptureFixture [str ], monkeypatch : pytest .MonkeyPatch
1817
1854
) -> None :
1855
+ monkeypatch .setattr (shutil , 'which' , lambda x : True ) # type: ignore
1856
+
1818
1857
def logfire_mcp_installed (_ : list [str ]) -> bytes :
1819
1858
return b'not installed'
1820
1859
@@ -1829,6 +1868,136 @@ def logfire_mcp_installed(_: list[str]) -> bytes:
1829
1868
""" )
1830
1869
1831
1870
1871
+ def test_parse_prompt_opencode (
1872
+ prompt_http_calls : None ,
1873
+ capsys : pytest .CaptureFixture [str ],
1874
+ tmp_path : Path ,
1875
+ monkeypatch : pytest .MonkeyPatch ,
1876
+ ) -> None :
1877
+ monkeypatch .setattr (shutil , 'which' , lambda x : True ) # type: ignore
1878
+ monkeypatch .setattr (Path , 'cwd' , lambda : tmp_path )
1879
+
1880
+ def check_output (x : list [str ]) -> bytes :
1881
+ return tmp_path .as_posix ().encode ('utf-8' )
1882
+
1883
+ monkeypatch .setattr (subprocess , 'check_output' , check_output )
1884
+
1885
+ main (['prompt' , '--project' , 'fake_org/myproject' , 'fix-span-issue:123' , '--opencode' ])
1886
+
1887
+ out , err = capsys .readouterr ()
1888
+ assert out == snapshot ("""\
1889
+ This is the prompt
1890
+ """ )
1891
+ assert err == snapshot ("""\
1892
+ Logfire MCP server not found. Creating a read token...
1893
+ Logfire MCP server added to OpenCode.
1894
+ """ )
1895
+
1896
+
1897
+ def test_parse_prompt_opencode_no_git (
1898
+ prompt_http_calls : None ,
1899
+ capsys : pytest .CaptureFixture [str ],
1900
+ tmp_path : Path ,
1901
+ monkeypatch : pytest .MonkeyPatch ,
1902
+ ) -> None :
1903
+ monkeypatch .setattr (shutil , 'which' , lambda x : True ) # type: ignore
1904
+ monkeypatch .setattr (Path , 'cwd' , lambda : tmp_path )
1905
+
1906
+ def check_output (x : list [str ]) -> bytes :
1907
+ raise subprocess .CalledProcessError (1 , x )
1908
+
1909
+ monkeypatch .setattr (subprocess , 'check_output' , check_output )
1910
+
1911
+ main (['prompt' , '--project' , 'fake_org/myproject' , 'fix-span-issue:123' , '--opencode' ])
1912
+
1913
+ out , err = capsys .readouterr ()
1914
+ assert out == snapshot ("""\
1915
+ This is the prompt
1916
+ """ )
1917
+ assert err == snapshot ("""\
1918
+ Logfire MCP server not found. Creating a read token...
1919
+ Logfire MCP server added to OpenCode.
1920
+ """ )
1921
+
1922
+
1923
+ def test_parse_prompt_opencode_not_installed (
1924
+ prompt_http_calls : None ,
1925
+ capsys : pytest .CaptureFixture [str ],
1926
+ tmp_path : Path ,
1927
+ monkeypatch : pytest .MonkeyPatch ,
1928
+ ) -> None :
1929
+ monkeypatch .setattr (shutil , 'which' , lambda x : False ) # type: ignore
1930
+ monkeypatch .setattr (Path , 'cwd' , lambda : tmp_path )
1931
+
1932
+ with pytest .raises (SystemExit ):
1933
+ main (['prompt' , '--project' , 'fake_org/myproject' , 'fix-span-issue:123' , '--opencode' ])
1934
+
1935
+ out , err = capsys .readouterr ()
1936
+ assert out == snapshot ('' )
1937
+ assert err == snapshot ("""\
1938
+ opencode is not installed. Install `opencode`, or remove the `--opencode` flag.
1939
+ """ )
1940
+
1941
+
1942
+ def test_parse_prompt_opencode_logfire_mcp_installed (
1943
+ prompt_http_calls : None ,
1944
+ capsys : pytest .CaptureFixture [str ],
1945
+ tmp_path : Path ,
1946
+ monkeypatch : pytest .MonkeyPatch ,
1947
+ ) -> None :
1948
+ monkeypatch .setattr (shutil , 'which' , lambda x : True ) # type: ignore
1949
+ monkeypatch .setattr (Path , 'cwd' , lambda : tmp_path )
1950
+
1951
+ (tmp_path / 'opencode.jsonc' ).write_text ("""
1952
+ {
1953
+ "mcp": {
1954
+ "logfire-mcp": {
1955
+ "command": "uvx",
1956
+ "args": ["logfire-mcp@latest"],
1957
+ "env": {"LOGFIRE_READ_TOKEN": "fake_token"}
1958
+ }
1959
+ }
1960
+ }
1961
+ """ )
1962
+
1963
+ def check_output (x : list [str ]) -> bytes :
1964
+ return tmp_path .as_posix ().encode ('utf-8' )
1965
+
1966
+ monkeypatch .setattr (subprocess , 'check_output' , check_output )
1967
+
1968
+ main (['prompt' , '--project' , 'fake_org/myproject' , 'fix-span-issue:123' , '--opencode' ])
1969
+
1970
+ out , err = capsys .readouterr ()
1971
+ assert out == snapshot ('This is the prompt\n ' )
1972
+ assert err == snapshot ('' )
1973
+
1974
+
1975
+ def test_parse_opencode_logfire_mcp_not_installed_with_existing_config (
1976
+ prompt_http_calls : None ,
1977
+ capsys : pytest .CaptureFixture [str ],
1978
+ tmp_path : Path ,
1979
+ monkeypatch : pytest .MonkeyPatch ,
1980
+ ) -> None :
1981
+ monkeypatch .setattr (shutil , 'which' , lambda x : True ) # type: ignore
1982
+ monkeypatch .setattr (Path , 'cwd' , lambda : tmp_path )
1983
+
1984
+ (tmp_path / 'opencode.jsonc' ).write_text ('{}' )
1985
+
1986
+ def check_output (x : list [str ]) -> bytes :
1987
+ return tmp_path .as_posix ().encode ('utf-8' )
1988
+
1989
+ monkeypatch .setattr (subprocess , 'check_output' , check_output )
1990
+
1991
+ main (['prompt' , '--project' , 'fake_org/myproject' , 'fix-span-issue:123' , '--opencode' ])
1992
+
1993
+ out , err = capsys .readouterr ()
1994
+ assert out == snapshot ('This is the prompt\n ' )
1995
+ assert err == snapshot ("""\
1996
+ Logfire MCP server not found. Creating a read token...
1997
+ Logfire MCP server added to OpenCode.
1998
+ """ )
1999
+
2000
+
1832
2001
def test_base_url_and_logfire_url (
1833
2002
tmp_dir_cwd : Path , logfire_credentials : LogfireCredentials , capsys : pytest .CaptureFixture [str ]
1834
2003
):
0 commit comments