Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add: fpm search #1054

Open
wants to merge 57 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
7d5a99d
fix: url bug
henilp105 Mar 27, 2024
06d353c
Merge branch 'fortran-lang:main' into fpm-search
henilp105 May 18, 2024
94fdf25
add: search functionality for fpm registry
henilp105 May 19, 2024
0a4f910
add: search
henilp105 May 19, 2024
7a4bdb5
add: search
henilp105 May 19, 2024
cc9bd57
add: search
henilp105 May 19, 2024
0a99d4a
add: search
henilp105 May 19, 2024
b048451
add: search
henilp105 May 19, 2024
0b66b85
add: search
henilp105 May 19, 2024
d2b173a
fix search
henilp105 May 19, 2024
6d5c44b
add: search
henilp105 May 19, 2024
354fda1
fix: get file and add page
henilp105 May 19, 2024
baed1f5
fix: if no page number is provided
henilp105 May 19, 2024
3456c39
add: search functionality support registry, namespaces,packages
henilp105 May 26, 2024
384ef93
clean
henilp105 May 26, 2024
ea021d3
clean
henilp105 May 26, 2024
7dbd3f7
clean
henilp105 May 26, 2024
11c05cb
clean
henilp105 May 26, 2024
762b78e
clean
henilp105 May 26, 2024
08f0171
clean
henilp105 May 26, 2024
511a107
Merge branch 'fortran-lang:main' into fpm-search
henilp105 May 26, 2024
a87b472
fix
henilp105 May 27, 2024
5f3a18d
fix
henilp105 May 27, 2024
334eeb5
add: new search paramters
henilp105 May 27, 2024
a0dbf40
add: new search paramters
henilp105 May 27, 2024
494194f
add: new search paramters
henilp105 May 27, 2024
5eb04a5
add: new search paramters
henilp105 May 27, 2024
034051d
add: version functionality
henilp105 May 29, 2024
373155c
add: docs
henilp105 May 29, 2024
18c3975
search in local registry
henilp105 May 29, 2024
606c20a
add: search
henilp105 May 29, 2024
e9822d9
Merge branch 'fortran-lang:main' into fpm-search
henilp105 May 29, 2024
c1216f0
add: search
henilp105 May 29, 2024
fc62c32
add: local registry search functionality for all parameters
henilp105 May 31, 2024
ced681e
clean
henilp105 May 31, 2024
52b0d79
add: enable global search
henilp105 May 31, 2024
0ca0eae
fix: bugs
henilp105 May 31, 2024
4a4c6ce
clean
henilp105 May 31, 2024
8800925
clean
henilp105 May 31, 2024
b02bd72
search description
henilp105 Jun 6, 2024
e05e51d
search query matching
henilp105 Jun 6, 2024
469051f
fix: search and clean
henilp105 Jun 6, 2024
c1b0c18
seach local registry functionality with all parameters
henilp105 Jun 6, 2024
aa1112b
Merge branch 'fortran-lang:main' into fpm-search
henilp105 Jun 7, 2024
8496b5c
clean
henilp105 Jun 9, 2024
4beb573
Merge branch 'fortran-lang:main' into fpm-search
henilp105 Jun 22, 2024
5c259a4
refactor
henilp105 Jun 22, 2024
1c86fdf
refactor and clean
henilp105 Jun 22, 2024
4a1975f
clean
henilp105 Jun 23, 2024
0f668a5
fix
henilp105 Jun 23, 2024
dad1f49
add docs
henilp105 Jun 23, 2024
c3f27ba
fix
henilp105 Jun 23, 2024
81ea75b
clean
henilp105 Jun 23, 2024
805f1e5
Merge branch 'main' into fpm-search
henilp105 Jun 28, 2024
a62162a
fix
henilp105 Jun 28, 2024
ad779ec
add: comments
henilp105 Jul 2, 2024
2d088aa
test commit
henilp105 Aug 26, 2024
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
6 changes: 5 additions & 1 deletion app/main.f90
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ program main
fpm_update_settings, &
fpm_clean_settings, &
fpm_publish_settings, &
get_command_line_settings
get_command_line_settings, &
fpm_search_settings
use fpm_error, only: error_t
use fpm_filesystem, only: exists, parent_dir, join_path
use fpm, only: cmd_build, cmd_run, cmd_clean
Expand All @@ -20,6 +21,7 @@ program main
use fpm_cmd_new, only: cmd_new
use fpm_cmd_update, only : cmd_update
use fpm_cmd_publish, only: cmd_publish
use fpm_cmd_search, only: cmd_search
use fpm_os, only: change_directory, get_current_directory

implicit none
Expand Down Expand Up @@ -86,6 +88,8 @@ program main
call cmd_update(settings)
type is (fpm_clean_settings)
call cmd_clean(settings)
type is (fpm_search_settings)
call cmd_search(settings)
type is (fpm_publish_settings)
call cmd_publish(settings)
end select
Expand Down
178 changes: 178 additions & 0 deletions src/fpm/cmd/search.f90
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
!> Search a package from both local and remote registry using the `search` subcommand.
!> The package can be searched by packagename, namespace, query (description and README.md), and license from the registries (local and remote).
!> the remote registry URL can also be specified by the paramter --registry.
!> It can be used as `fpm search --query q* --page 1 --registry URL --namespace n* --package p* --package_version v* --license l* --limit 10 --sort-by [name] --sort [asc/desc]`
module fpm_cmd_search
use fpm_command_line, only: fpm_search_settings
use fpm_manifest, only: package_config_t, get_package_data
use fpm_model, only: fpm_model_t
use fpm_error, only: error_t, fpm_stop
use fpm_versioning, only: version_t
use fpm_filesystem, only: exists, join_path, get_temp_filename, delete_file, basename, &
canon_path, dirname, list_files, is_hidden_file
use fpm_git, only: git_archive
use fpm_downloader, only: downloader_t
use fpm_strings, only: string_t, string_array_contains, split, str,glob
use fpm, only: build_model
use fpm_error, only : error_t, fatal_error, fpm_stop
use jonquil, only : json_object
use tomlf, only : toml_array, get_value, len, toml_key, toml_loads, toml_table, &
toml_serializer,toml_value
use tomlf_utils_io, only : read_whole_file
use fpm_settings, only: fpm_global_settings, get_global_settings, official_registry_base_url

implicit none
private
public :: cmd_search

contains

!> Search the fpm registry for a package
subroutine cmd_search(settings)
!> Settings for the search command.
class(fpm_search_settings), intent(in) :: settings
type(fpm_global_settings) :: global_settings
character(:), allocatable :: tmp_file, name, namespace, description, query_url, package_version
integer :: stat, unit, ii
type(json_object) :: json
type(json_object), pointer :: p
!> Error handling.
type(error_t), allocatable :: error
type(toml_array), pointer :: array
type(version_t), allocatable :: version

!> Downloader instance.
class(downloader_t), allocatable :: downloader
allocate (downloader)

call get_global_settings(global_settings, error)
if (allocated(error)) then
call fpm_stop(1, "Error retrieving global settings"); return
end if

!> Generate a temporary file to store the downloaded package search data
tmp_file = get_temp_filename()
open (newunit=unit, file=tmp_file, action='readwrite', iostat=stat)
if (stat /= 0) then
call fatal_error(error, "Error creating temporary file for downloading package."); return
end if
query_url = settings%registry//'/packages_cli' &
& // '?query='//settings%query &
& // '&page='//settings%page &
& // '&package='//settings%package &
& // '&namespace='//settings%namespace &
& // '&version='//settings%version &
& // '&license='//settings%license &
& // '&limit='//settings%limit &
& // '&sort_by='//settings%sort_by &
& // '&sort='//settings%sort

!> Get the package data from the registry
call downloader%get_pkg_data(query_url, version, tmp_file, json, error)
close (unit)
if (allocated(error)) then
call fpm_stop(1, "Error retrieving package data from registry: "//settings%registry); return
end if
print *
print *, "Searching packages in Local Registry:"
print *
call search_package(settings%query, settings%namespace, settings%package, settings%version)
if (json%has_key("packages")) then
call get_value(json, 'packages', array)
print *
print '(A,I0,A)', ' Found ', len(array), ' packages in fpm - registry:'
print *
do ii=1, len(array)
call get_value(array, ii, p)
call get_value(p, 'name', name)
call get_value(p, 'namespace', namespace)
call get_value(p, 'description', description)
call get_value(p, 'version', package_version)

print *, "Name: ", name
perazz marked this conversation as resolved.
Show resolved Hide resolved
print *, "namespace: ", namespace
print *, "Description: ", description
print *, "version: ", package_version
print *
end do
else
call fpm_stop(1, "Invalid package data returned"); return
end if
end subroutine cmd_search

subroutine search_package(query,namespace,package,version)
type(fpm_global_settings) :: global_settings
type(error_t), allocatable :: error
character(:), allocatable, intent(in) :: namespace, package, version, query
character(:), allocatable :: path, array(:), versioncheck(:), toml_package_data, print_package(:)
character(:), allocatable :: description, wild
type(string_t), allocatable :: file_names(:)
type(toml_table), allocatable :: table
integer :: i, j, unit, stat
logical :: result

call get_global_settings(global_settings, error)
if (allocated(error)) then
call fpm_stop(1, "Error retrieving global settings"); return
end if

path = global_settings%registry_settings%cache_path

! Scan directory for packages
call list_files(path, file_names,recurse=.true.)
do i=1,size(file_names)
result = package_search_wild(namespace,package,version,file_names(i)%s)
call split(file_names(i)%s,array,'/')
if (result) then
!> query search for description
call read_whole_file(file_names(i)%s, toml_package_data, stat)
if (stat /= 0) then
call fatal_error(error, "Error reading file: "//file_names(i)%s); return
end if
! Load TOML data into a table
call toml_loads(table,toml_package_data)
if (allocated(error)) then
call fpm_stop(1, "Error loading toml file"); return
end if

if (allocated(table)) then
call get_value(table, 'description', description)
if (query /="") then
result = glob(description,query)
if (result) call print_package_data(array,description)
else
call print_package_data(array,description)
end if
else
call fpm_stop(1, "Error Searching for the query"); return
end if
endif
end do
end subroutine search_package

function package_search_wild(namespace,package,version, file_name) result(result)
character(:), allocatable, intent(in) :: namespace, package, version, file_name
character(:), allocatable :: array(:), versioncheck(:)
logical :: result

call split(file_name,array,'/')
call split(array(size(array)-1),versioncheck,'.')
result = array(size(array)) == "fpm.toml"
result = result .and. glob(array(size(array)-3),namespace)
result = result .and. glob(array(size(array)-2),package)
result = result .and. glob(array(size(array)-1),version)
result = result .and. size(versioncheck) > 2
end function package_search_wild

subroutine print_package_data(package_array,description)
character(:), allocatable, intent(in) :: package_array(:)
character(*), intent(in) :: description

print *, "Name: ", package_array(size(package_array)-2)
print *, "Namespace: ", package_array(size(package_array)-3)
print *, "Version: ", package_array(size(package_array)-1)
print *, "Description: ", description
print *
end subroutine print_package_data
end

4 changes: 2 additions & 2 deletions src/fpm/downloader.f90
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,10 @@ subroutine get_file(url, tmp_pkg_file, error)

if (which('curl') /= '') then
print *, "Downloading '"//url//"' -> '"//tmp_pkg_file//"'"
call execute_command_line('curl '//url//' -s -o '//tmp_pkg_file, exitstat=stat)
call execute_command_line('curl "'//url//'" -s -o '//tmp_pkg_file, exitstat=stat)
else if (which('wget') /= '') then
print *, "Downloading '"//url//"' -> '"//tmp_pkg_file//"'"
call execute_command_line('wget '//url//' -q -O '//tmp_pkg_file, exitstat=stat)
call execute_command_line('wget "'//url//'" -q -O '//tmp_pkg_file, exitstat=stat)
else
call fatal_error(error, "Neither 'curl' nor 'wget' installed."); return
end if
Expand Down
Loading
Loading