diff --git a/utils/find-first/action.yaml b/utils/find-first/action.yaml new file mode 100644 index 0000000..cb13b8e --- /dev/null +++ b/utils/find-first/action.yaml @@ -0,0 +1,75 @@ +name: find-first +description: "Find the first file matching a pattern and extract detailed information about it." +inputs: + path: + description: "Path to search in." + required: false + default: "." + pattern: + description: "Pattern to search for (supports glob patterns)." + required: true + type: + description: "Type of files to find (f=files, d=directories, l=links)." + required: false + default: "f" + maxDepth: + description: "Maximum depth to search." + required: false + default: "" + minDepth: + description: "Minimum depth to search." + required: false + default: "" + size: + description: "Size constraint (e.g., +100k, -1M)." + required: false + default: "" + modified: + description: "Modified time constraint (e.g., -1, +7)." + required: false + default: "" + additionalArgs: + description: "Additional arguments to pass to find command." + required: false + default: "" +outputs: + found: + description: "Whether a file was found (true/false)." + value: ${{ steps.extract.outputs.found }} + fullPath: + description: "Full path of the first found file." + value: ${{ steps.extract.outputs.fullPath }} + directory: + description: "Directory containing the file." + value: ${{ steps.extract.outputs.directory }} + directoryName: + description: "Name of the directory containing the file." + value: ${{ steps.extract.outputs.directoryName }} + fileName: + description: "Full filename with extension." + value: ${{ steps.extract.outputs.fileName }} + baseName: + description: "Filename without extension." + value: ${{ steps.extract.outputs.baseName }} + extension: + description: "File extension (without dot)." + value: ${{ steps.extract.outputs.extension }} +runs: + using: "composite" + steps: + - name: "Find files." + id: find + uses: act/common/utils/find@master + with: + path: ${{ inputs.path }} + pattern: ${{ inputs.pattern }} + type: ${{ inputs.type }} + maxDepth: ${{ inputs.maxDepth }} + minDepth: ${{ inputs.minDepth }} + size: ${{ inputs.size }} + modified: ${{ inputs.modified }} + additionalArgs: ${{ inputs.additionalArgs }} + - name: "Extract information about first file." + id: extract + run: sh "${{ github.action_path }}/find-first.sh" "${{ steps.find.outputs.files }}" + shell: bash diff --git a/utils/find-first/find-first.sh b/utils/find-first/find-first.sh new file mode 100644 index 0000000..237eabd --- /dev/null +++ b/utils/find-first/find-first.sh @@ -0,0 +1,70 @@ +#!/bin/bash + +# Get the files list from the find output +FILES_LIST="$1" + +if [[ ! -f "$GITHUB_OUTPUT" ]]; then + # Write to stdout if the output file doesn't exist. + GITHUB_OUTPUT="/dev/fd/1" +fi + +# Function to output file information +function output_file_info +{ + local found="$1" + local full_path="$2" + local directory="$3" + local directory_name="$4" + local file_name="$5" + local base_name="$6" + local extension="$7" + + echo "found=$found" >> "$GITHUB_OUTPUT" + echo "fullPath=$full_path" >> "$GITHUB_OUTPUT" + echo "directory=$directory" >> "$GITHUB_OUTPUT" + echo "directoryName=$directory_name" >> "$GITHUB_OUTPUT" + echo "fileName=$file_name" >> "$GITHUB_OUTPUT" + echo "baseName=$base_name" >> "$GITHUB_OUTPUT" + echo "extension=$extension" >> "$GITHUB_OUTPUT" +} + +# Check if any files were found +if [[ -z "$FILES_LIST" ]]; then + output_file_info "false" + exit 0 +fi + +# Get the first file from the list +FIRST_FILE=$(echo "$FILES_LIST" | head -n 1) + +if [[ -z "$FIRST_FILE" ]]; then + output_file_info "false" + exit 0 +fi + +# Extract path information +FULL_PATH="$FIRST_FILE" +DIRECTORY=$(dirname "$FULL_PATH") +DIRECTORY_NAME=$(basename "$DIRECTORY") +FILE_NAME=$(basename "$FULL_PATH") + +# Extract filename parts +if [[ "$FILE_NAME" == *.* ]]; then + # File has an extension + BASE_NAME="${FILE_NAME%.*}" + EXTENSION="${FILE_NAME##*.}" +else + # File has no extension + BASE_NAME="$FILE_NAME" + EXTENSION="" +fi + +# Handle special cases for directory names +if [[ "$DIRECTORY" == "." ]]; then + DIRECTORY_NAME="." +elif [[ "$DIRECTORY" == "/" ]]; then + DIRECTORY_NAME="/" +fi + +# Output all the extracted information using the function +output_file_info "true" "$FULL_PATH" "$DIRECTORY" "$DIRECTORY_NAME" "$FILE_NAME" "$BASE_NAME" "$EXTENSION" diff --git a/utils/find/action.yaml b/utils/find/action.yaml new file mode 100644 index 0000000..99bc2d1 --- /dev/null +++ b/utils/find/action.yaml @@ -0,0 +1,50 @@ +name: find +description: "Find files matching a specific pattern." +inputs: + path: + description: "Path to search in." + required: false + default: "." + pattern: + description: "Pattern to search for (supports glob patterns)." + required: true + type: + description: "Type of files to find (f=files, d=directories, l=links)." + required: false + default: "f" + maxDepth: + description: "Maximum depth to search." + required: false + default: "" + minDepth: + description: "Minimum depth to search." + required: false + default: "" + size: + description: "Size constraint (e.g., +100k, -1M)." + required: false + default: "" + modified: + description: "Modified time constraint (e.g., -1, +7)." + required: false + default: "" + additionalArgs: + description: "Additional arguments to pass to find command." + required: false + default: "" +outputs: + files: + description: "List of found files (newline separated)." + value: ${{ steps.find.outputs.files }} + count: + description: "Number of files found." + value: ${{ steps.find.outputs.count }} +runs: + using: "composite" + steps: + - name: "Find files." + id: find + run: | + bash "${{ github.action_path }}/find.sh" "${{ inputs.path }}" "${{ inputs.pattern }}" "${{ inputs.type }}" \ + "${{ inputs.maxDepth }}" "${{ inputs.minDepth }}" "${{ inputs.size }}" "${{ inputs.modified }}" "${{ inputs.additionalArgs }}" + shell: bash diff --git a/utils/find/find.sh b/utils/find/find.sh new file mode 100644 index 0000000..d8a8d84 --- /dev/null +++ b/utils/find/find.sh @@ -0,0 +1,67 @@ +#!/bin/bash + +# Get inputs +SEARCH_PATH="$1" +PATTERN="$2" +FILE_TYPE="$3" +MAX_DEPTH="$4" +MIN_DEPTH="$5" +SIZE="$6" +MODIFIED="$7" +ADDITIONAL_ARGS="$8" + +if [[ ! -f "$GITHUB_OUTPUT" ]]; then + # Write to stdout if the output file doesn't exist. + GITHUB_OUTPUT="/dev/fd/1" +fi + +# Build the find command - start with basic find and path +FIND_CMD="find \"$SEARCH_PATH\"" + +if [[ -n "$FILE_TYPE" ]]; then + # Add type filter first + FIND_CMD="$FIND_CMD -type $FILE_TYPE" +fi + +# Add depth constraints before name pattern +if [[ -n "$MAX_DEPTH" ]]; then + FIND_CMD="$FIND_CMD -maxdepth $MAX_DEPTH" +fi + +if [[ -n "$MIN_DEPTH" ]]; then + FIND_CMD="$FIND_CMD -mindepth $MIN_DEPTH" +fi + +# Add name pattern +FIND_CMD="$FIND_CMD -name \"$PATTERN\"" + +if [[ -n "$SIZE" ]]; then + FIND_CMD="$FIND_CMD -size $SIZE" +fi + +if [[ -n "$MODIFIED" ]]; then + FIND_CMD="$FIND_CMD -mtime $MODIFIED" +fi + +if [[ -n "$ADDITIONAL_ARGS" ]]; then + FIND_CMD="$FIND_CMD $ADDITIONAL_ARGS" +fi + +# Execute the command and capture output +OUTPUT=$(eval "$FIND_CMD" 2>/dev/null || true) +RESULT=$? + +# Count the number of files found +if [[ -n "$OUTPUT" ]]; then + COUNT=$(echo "$OUTPUT" | wc -l) + echo "files<> "$GITHUB_OUTPUT" + echo "$OUTPUT" >> "$GITHUB_OUTPUT" + echo "EOF" >> "$GITHUB_OUTPUT" +else + COUNT=0 + echo "files=" >> "$GITHUB_OUTPUT" +fi + +echo "count=$COUNT" >> "$GITHUB_OUTPUT" + +exit $RESULT