Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/JuliaWorkspaces.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ using Salsa

using AutoHashEquals

include("utils.jl")

include("compat.jl")

import Pkg
Expand Down
3 changes: 2 additions & 1 deletion src/fileio.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ end
function is_path_manifest_file(path)
basename_lower_case = basename(lowercase(path))

return basename_lower_case=="manifest.toml" || basename_lower_case=="juliamanifest.toml"
# Manifest.toml, Manifest-v1.11.toml, JuliaManifest.toml, etc.
return occursin(r"^(julia)?manifest(\-v\d+(\.\d+)*)?\.toml$", basename_lower_case)
end

function is_path_lintconfig_file(path)
Expand Down
58 changes: 38 additions & 20 deletions src/layer_testitems.jl
Original file line number Diff line number Diff line change
Expand Up @@ -109,32 +109,50 @@ Salsa.@derived function derived_testenv(rt, uri)
projects = derived_project_folders(rt)
packages = derived_package_folders(rt)

project_uri = find_project_for_file(projects, uri)
project_uri_guess = @something(
find_project_for_file(projects, uri),
input_fallback_test_project(rt),
Some(nothing)
)
package_uri = find_package_for_file(packages, uri)

if project_uri === nothing
project_uri = input_fallback_test_project(rt)
end

package_name = package_uri === nothing ? nothing : derived_package(rt, package_uri).name
package_name =
if isnothing(package_uri)
nothing
else
safe_getproperty(derived_package(rt, package_uri), :name)
end

if project_uri == package_uri
elseif project_uri in projects
relevant_project = derived_project(rt, project_uri)
project_uri =
if project_uri_guess == package_uri
project_uri_guess
elseif project_uri_guess in projects
relevant_project = derived_project(rt, project_uri_guess)

if isnothing(relevant_project)
nothing
elseif any(i->i.uri == package_uri, collect(values(relevant_project.deved_packages)))
project_uri_guess
else
nothing
end
else
nothing
end

if findfirst(i->i.uri == package_uri, collect(values(relevant_project.deved_packages))) === nothing
project_uri = nothing
project_env_content_hash =
if isnothing(project_uri)
hash(nothing)
else
safe_getproperty(derived_project(rt, project_uri), :content_hash)
end
else
project_uri = nothing
end

env_content_hash = isnothing(project_uri) ? hash(nothing) : derived_project(rt, project_uri).content_hash
if package_uri===nothing
env_content_hash = hash(nothing, env_content_hash)
else
env_content_hash = hash(derived_package(rt, package_uri).content_hash)
end
env_content_hash =
if isnothing(package_uri)
hash(project_env_content_hash)
else
hash(safe_getproperty(derived_package(rt, package_uri), :content_hash))
end

# We construct a string for the env content hash here so that later when we
# deserialize it with JSON.jl we don't end up with Int conversion issues
Expand Down
7 changes: 7 additions & 0 deletions src/utils.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
@inline function safe_getproperty(x, s::Symbol)
if isnothing(x)
return nothing
else
return getproperty(x, s)
end
end
115 changes: 115 additions & 0 deletions test/test_testitems.jl
Original file line number Diff line number Diff line change
Expand Up @@ -439,3 +439,118 @@ end

@test ti.name == "Test1"
end

@testitem "versioned manifest files are detected" begin
using JuliaWorkspaces
using JuliaWorkspaces.URIs2: filepath2uri

mktempdir() do temp_dir
# Create project with versioned manifest
project_dir = joinpath(temp_dir, "VersionedProject")
mkpath(project_dir)

project_file = joinpath(project_dir, "Project.toml")
write(project_file, """
name = "VersionedProject"
uuid = "12345678-1234-1234-1234-123456789abc"
version = "0.1.0"

[deps]
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
""")

# Create versioned manifest
versioned_manifest = joinpath(project_dir, "Manifest-v$(VERSION.major).$(VERSION.minor).toml")
write(versioned_manifest, """
julia_version = "$(VERSION.major).$(VERSION.minor).$(VERSION.patch)"
manifest_format = "2.0"
project_hash = "test"

[[deps.Random]]
deps = ["SHA", "Serialization"]
uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
version = "1.10.0"

[[deps.SHA]]
uuid = "ea8e919c-285b-4e28-92e2-21d1dda8b7a7"
version = "0.7.0"

[[deps.Serialization]]
uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b"
version = "1.10.0"
""")

# Add to workspace
project_uri = filepath2uri(project_file)
manifest_uri = filepath2uri(versioned_manifest)
folder_uri = filepath2uri(project_dir)

jw = JuliaWorkspace()
add_file!(jw, TextFile(project_uri, SourceText(read(project_file, String), "toml")))
add_file!(jw, TextFile(manifest_uri, SourceText(read(versioned_manifest, String), "toml")))

# Test that versioned manifest IS now detected
rt = jw.runtime
potential_projects = JuliaWorkspaces.derived_potential_project_folders(rt)

@test haskey(potential_projects, folder_uri)
project_info = potential_projects[folder_uri]
@test project_info.project_file !== nothing
@test project_info.manifest_file !== nothing # FIXED: versioned manifest now detected

# This should now return a valid project
derived_result = JuliaWorkspaces.derived_project(rt, folder_uri)
@test derived_result !== nothing
@test derived_result isa JuliaWorkspaces.JuliaProject
end
end

@testitem "handle missing manifest gracefully" begin
using JuliaWorkspaces
using JuliaWorkspaces.URIs2: filepath2uri

mktempdir() do temp_dir
# Create a simple project that will work
project_dir = joinpath(temp_dir, "SimpleProject")
mkpath(project_dir)

project_file = joinpath(project_dir, "Project.toml")
write(
project_file,
"""
name = "SimpleProject"
uuid = "12345678-1234-1234-1234-123456789abc"
version = "0.1.0"
""",
)

# NO MANIFEST - this makes derived_project return nothing

# Create Julia file
test_file = joinpath(temp_dir, "test.jl")
write(test_file, "# Test file")

# Add to workspace
project_uri = filepath2uri(project_file)
test_uri = filepath2uri(test_file)
folder_uri = filepath2uri(project_dir)

jw = JuliaWorkspace()
add_file!(jw, TextFile(project_uri, SourceText(read(project_file, String), "toml")))
add_file!(jw, TextFile(test_uri, SourceText("# test", "julia")))

# Set project as fallback test project
JuliaWorkspaces.set_input_fallback_test_project!(jw.runtime, folder_uri)

rt = jw.runtime

# Verify derived_project returns nothing (no manifest)
derived_result = JuliaWorkspaces.derived_project(rt, folder_uri)
@test derived_result === nothing

# This should work with defensive programming - no crash on .content_hash
test_env = get_test_env(jw, test_uri)
@test test_env isa JuliaWorkspaces.JuliaTestEnv
@test test_env.project_uri === nothing # Should be set to nothing due to lack of manifest
end
end
Loading