I'm writing a library that makes use of a file from a GitHub repository that I don't own:
git init foo
cd foo
git submodule add https://github.com/KhronosGroup/Vulkan-Docs.git github/KhronosGroup/Vulkan-Docs
mkdir -p src/com/example/foo resources/com/example/foo
Here are the other two relevant files in foo.
build.boot:
(set-env!
:resource-paths #{"src" "resources"}
:dependencies '[[adzerk/bootlaces "0.1.13" :scope "test"]])
(require '[adzerk.bootlaces :refer :all])
(deftask run [f function SYM sym]
(with-pass-thru _
(require (symbol (namespace function)))
((resolve function))))
(def +version+ "0.1.0-SNAPSHOT")
(bootlaces! +version+ :dont-modify-paths? true)
(task-options!
pom {:project 'com.example/foo
:version +version+})
src/com/example/foo/core.clj:
(ns com.example.foo.core
(:require [clojure.java.io :as io]))
(defn bar []
(some-> "com/example/foo/spec.xml" io/resource slurp count prn))
What I want is some sort of add task that allows me to do something like this:
boot add --resource --from github/KhronosGroup/Vulkan-Docs/src/spec/vk.xml --to com/example/foo/spec.xml run -f com.example.foo.core/bar
585128
I tried using the -R option of sift, but it has two problems for my use case:
Far more files than just the one I want (vk.xml) are pulled into the fileset, which would bloat the size of my JAR
Because -R simply adds the directory to the set of resource paths, all of its contents are added to the fileset at the top level, which could easily clobber my own resources
Essentially, I want something that has the same effect as the below three commands, but without actually touching the resources directory:
cp github/KhronosGroup/Vulkan-Docs/src/spec/vk.xml resources/com/example/foo/spec.xml
boot build-jar
rm resources/com/example/foo/spec.xml
In other words, the com.example/foo JAR should contain that XML file as a resource, so that resource should be available when I use com.example/foo from another project:
boot -d com.example/foo:0.1.0-SNAPSHOT repl
(require '[com.example.foo.core :as foo])
;;=> nil
(foo/bar)
;; 585128
;;=> nil
How can I pull a specific file (e.g. from a Git submodule) into the fileset at a specific location as a resource, without touching any of the files that I already have in the fileset?
Related
I have multiple projects and one of them is a purposed deployment configuration for setting up multiple repositories, configuring a server structure from files and folders, and finally deploying some services (Docker based).
And with that one project, I want to figure out on how to solve the following situation:
Start with a collection of ( I call this tags)
REPOSITORY_COLLECTION=(
"folder_a:repository_a:branch_a"
"folder_b:repository_b:branch_b"
"folder_c:repository_c:branch_c"
)
folder stands for the source location of where repositories are going to be cloned from Git (I have pairs of repository names separated in different kinds of 'folders')
repository is the name of a repository from Git
branch is the remote branch from Git that is going to be used within the script
So, in order to use the values from within the array, they need to get separated. This is how I've done that:
for collection in ${REPOSITORY_COLLECTION[#]}; do
folder="${collection%%:*}" # only take the first part
result="${collection##"$folder:"}" # remove folder from collection value
repository="${result%%:*}" # only take the second part
branch="${result#"$repository:"}" # only take the third part
# then, add it to new arrays to keep them separated and for the requirement that it is going to be used within the other functionalities of the script
repository_tags+=("$collection")
repository_types+=("$folder")
repositories+=("$repository")
repository_branches+=("$branch")
done
After that, I will need both '$repository_types' and '$repositories' to check if that repository already exists or not. So I need to shape a path; but if I'm not wrong, it will require me to still compare all separated values with the source of $collection "$repository_tags" to check whether the combination of the two is correct. Values are from the same source array, but are randomly chosen according to each other. So:
for tags in ${repository_tags[#]}; do
for repository_type in ${repository_types[#]}; do
# beginning with the source
source_path="/path_to_server/repositories/$repository_type"
if [ -d "$source_path" ]; then
echo && echo "$source_path exist"
else
echo && echo "$source_path doesn't exist, creating it.."
echo "mkdir -p $source_path"
mkdir -p $source_path
fi
for repository in ${repositories[#]}; do
if [[ "$tags" == "$repository_type"* ]] && [[ "$tags" == *"$repository"* ]]; then
# adding the repository value to it, and check if it exists
if [ ! -d "$source_path/$repository" ]; then
# clone from Git
echo "Source '$source_path': Ready to clone $repository"
else
# pull changes from Git
echo "Source '$source_path': Ready to pull changes from $repository"
fi
fi
done
done
done
According to the result when running this:
/path_to_server/repositories/folder_a doesn't exist, creating it..
mkdir -p /path_to_server/repositories/folder_a
Source '/path_to_server/repositories/folder_a': Ready to clone repository_a
/path_to_server/repositories/folder_b doesn't exist, creating it..
mkdir -p /path_to_server/repositories/folder_b
/path_to_server/repositories/folder_c doesn't exist, creating it..
mkdir -p /path_to_server/repositories/folder_c
/path_to_server/repositories/folder_a exist
/path_to_server/repositories/folder_b exist
Source '/path_to_server/repositories/folder_b': Ready to clone repository_b
/path_to_server/repositories/folder_c exist
/path_to_server/repositories/folder_a exist
/path_to_server/repositories/folder_b exist
/path_to_server/repositories/folder_c exist
Source '/path_to_server/repositories/folder_c': Ready to clone repository_c
I like and want the first lines to repeat for every other values such as this;
/path_to_server/repositories/folder_a doesn't exist, creating it..
mkdir -p /path_to_server/repositories/folder_a
Source '/path_to_server/repositories/folder_a': Ready to clone repository_a
Does anyone know what I can do better in this situation, or on how this can be solved?
IFS=: read -r folder repo branch <<< "$collection"
is the simpler way to split a string on colons and assign the fields to variables.
Beyond that, I don't follow what you're doing at all. You may have 1 or more repositories in each folder, and you may have 1 or more branches in each repository. It smells like you need to switch to a language that can do arbitrarily deeply nested data structures.
I was just wondering what’s the best way to configure codecov for a monorepo setting. For example, let’s say I have packages A and B under my monorepo. The way I’m currently using codecov is by using a github action codecov/codecov-action#v1, by using multiple uses statement in my GitHub workflow YAML file like the following:-
- uses: codecov/codecov-action#v1
with:
files: ./packages/A/coverage/lcov.info
flags: flag_a
name: A
- uses: codecov/codecov-action#v1
with:
files: ./packages/B/coverage/lcov.info
flags: flag_b
name: B
I know it's possible to use a comma-separated value to upload multiple files, but I have to set a separate flag for each package, and doing it that way doesn't seem to work.
Thank you.
If anyone wants to know my solution, heres what I came up with.
I ended up replacing the github action with my own bash script.
final code
#!/usr/bin/env bash
codecov_file="${GITHUB_WORKSPACE}/scripts/codecov.sh"
curl -s https://codecov.io/bash > $codecov_file
chmod +x $codecov_file
cd "${GITHUB_WORKSPACE}/packages";
for dir in */
do
package="${dir/\//}"
if [ -d "$package/coverage" ]
then
file="$PWD/$package/coverage/lcov.info"
flag="${package/-/_}"
$codecov_file -f $file -F $flag -v -t $CODECOV_TOKEN
fi
done
this is what the above bash script does
Downloading the bash uploader script from codecov
Moving to the packages directory where are the packages are located, and going through all the 1st level directories
Change the package name by removing extra slash
If the directory contains coverage directory only then enter into it, since only those packages have been tested.
Create a file and flag variable (removing hypen with underscore as codecov doesn't support hypen in flag name)
Executed the downloaded codecov script by passing the file and flag variable as argument
I don't get the scenario of this given code. All I wanted is to compare the files that is given below. But, in this script nothings happen. I assume that this given code can executed wherever like in /root and it will run. Please check this out.
#!/bin/bash
for file in /var/files/sub/old/*
do
# Strip path from file name
file="${file##*/}"
# Strip everything after the first hyphen
prefix="${file%%-*}-"
# Strip everything before the second-to-last dot
suffix="$(echo $file | awk -F. '{ print "."$(NF-1)"."$NF }')"
# Create new file name from $prefix and $suffix, and any version number
new=$(echo "/var/files/new/${prefix}"*"${suffix}")
# If file exists in the 'new' folder:
if test -f "${new}"
then
# Do string comparison to see if new file is lexicographically "greater than" old
if [[ "${new##*/}" > "${file}" ]]
then
# If so, delete the old version.
rm /var/sub/files/old/"${file}"
else
# 'new' file is NOT newer, delete it instead.
rm "${new}"
fi
fi
done
# Move all new files into the old folder.
mv /var/files/new/* /var/files/sub/old/
Example files inside of each sub- directories ..
/var/files/sub/old/
firefox-24.5.0-1.el5_10.i386.rpm
firefox-24.5.0-1.el5_10.x86_64.rpm
google-1.6.0-openjdk-1.6.0.0-5.1.13.3.el5_10.x86_64.rpm
google-1.6.0-openjdk-demo-1.6.0.0-5.1.13.3.el5_10.x86_64.rpm
/var/files/new/
firefox-25.5.0-1.el5_10.i386.rpm
firefox-25.5.0-1.el5_10.x86_64.rpm
ie-1.6.0-openjdk-devel-1.6.0.0-5.1.13.3.el5_10.x86_64.rpm
ie-1.6.0-openjdk-javadoc-1.6.0.0-5.1.13.3.el5_10.x86_64.rpm
ie-1.6.0-openjdk-src-1.6.0.0-5.1.13.3.el5_10.x86_64.rpm
google-2.6.0-openjdk-demo-1.6.0.0-5.1.13.3.el5_10.x86_64.rpm
In this instance, I want to get the files that are the same. So the files that are the same in the given example are:
firefox-24.5.0-1.el5_10.i386.rpm
firefox-24.5.0-1.el5_10.x86_64.rpm
google-1.6.0-openjdk-demo-1.6.0.0-5.1.13.3.el5_10.x86_64.rpm
in the old/ directory and for the new/ directory the equivalents are:
firefox-25.5.0-1.el5_10.i386.rpm
firefox-25.5.0-1.el5_10.x86_64.rpm
google-2.6.0-openjdk-demo-1.6.0.0-5.1.13.3.el5_10.x86_64.rpm
The files have similarity for their first characters. It will display in the terminal. After that, there will be another comparing again of the files and the comparison is about which file is more updated one by the number after the name of the file like: firefox-24.5.0-1.el5_10.i386.rpm compared with firefox-25.5.0-1.el5_10.i386.rpm. So in that instance the firefox-24.5.0-1.el5_10.i386.rpm will be replaced by firefox-25.5.0-1.el5_10.i386.rpm because it has a greater value and more updated one and same as other files that are similar. And if the old one is removed and the new will take replacement of it.
So at this moment after the script has been executed the output will be like this.
/var/files/sub/old/
google-1.6.0-openjdk-1.6.0.0-5.1.13.3.el5_10.x86_64.rpm
firefox-25.5.0-1.el5_10.i386.rpm
firefox-25.5.0-1.el5_10.x86_64.rpm
ie-1.6.0-openjdk-devel-1.6.0.0-5.1.13.3.el5_10.x86_64.rpm
ie-1.6.0-openjdk-javadoc-1.6.0.0-5.1.13.3.el5_10.x86_64.rpm
ie-1.6.0-openjdk-src-1.6.0.0-5.1.13.3.el5_10.x86_64.rpm
google-2.6.0-openjdk-demo-1.6.0.0-5.1.13.3.el5_10.x86_64.rpm
/var/files/new/
<<empty all files here must to moved to other directory take as a replacement>>
Can anyone help me to make a script for this ? above is just an example. Let's assume that there are lots of files to considered as similar and need to removed and moved.
You can use rpm to get the name of the package without version or architecture strings:
rpm -qi -p /firefox-25.5.0-1.el5_10.i386.rpm
Gives:
Name : firefox
Version : 25.5.0
Release : 1.el5_10
Architecture: i386
....
So you can compare the Names to find related packages.
If the goal here is to have the newrpms directory have only the newest version of each RPM from a combination of sources then you most likely want to simply combine all the files in a single directory and then use the repomanage tool (from the yum-utils package, at least on CentOS) to have it inform you which of the RPMS are old and remove them.
Something like:
repomanage --old combined_rpms_directory | xargs -r rm
As to your initial script
for i in $(\ls -d ./new/*);
do
diff ${i} newrpms/;
rm ${i}
done
You generally don't want to "parse" the output from ls, especially when a glob will do what you want just as easily (for i in ./new/* in this case).
diff ${i} newrpms/ is attempting to diff a file and a directory (or two directories if your ls/glob happened to catch a directory) but in neither case will diff do what you want there. That being said what diff does doesn't really matter because, as Barmar said in his comment
your script is removing them without testing the result of diff
A bash script that does the checking. Here's how it works:
Traverse over each file in the old files directory. Get the prefix (package name with no version, architecture, etc), eg. firefox-; get the suffix (architecture.rpm), eg. .i386.rpm.
Attempt to match prefix and suffix with any version number within the new files directory, ie. firefox-*.i386.rpm. If there is a match, $new will contain the file name, eg. firefox-25.5.0-1.el5_10.i386.rpm; if no match, $new will equal the literal string firefox-*.i386.rpm which is not a file.
Check new files directory for existence of $new.
If it exists, check that $new is indeed newer than the old version. This is done by lexicographical string comparison, ie. firefox-24.5.0-1.el5_10.i386.rpm is less than firefox-25.5.0-1.el5_10.i386.rpm because it comes earlier in the alphabet. Conveniently, sane versioning schemes also happen to be alphabetical. NB: this may fail, for example, when comparing version 2 to version 10.
A new version of a file in the old files directory has been found! In this case, get rid of the old file with rm. If the file in the new directory is not newer, then delete it instead.
Done removing old versions. Old files directory has only files without newer versions.
Move all new files into old directory, leaving newest files in old directory, and new directory empty.
#!/bin/bash
for file in /var/files/sub/old/*
do
# Strip path from file name
file="${file##*/}"
# Strip everything after the first hyphen
prefix="${file%%-*}-"
# Strip everything before the second-to-last dot
suffix="$(echo $file | awk -F. '{ print "."$(NF-1)"."$NF }')"
# Create new file name from $prefix and $suffix, and any version number
new=$(echo "/var/files/new/${prefix}"*"${suffix}")
# If file exists in the 'new' folder:
if test -f "${new}"
then
# Do string comparison to see if new file is lexicographically "greater than" old
if [[ "${new##*/}" > "${file}" ]]
then
# If so, delete the old version.
rm /var/sub/files/old/"${file}"
else
# 'new' file is NOT newer, delete it instead.
rm "${new}"
fi
fi
done
# Move all new files into the old folder.
mv /var/files/new/* /var/files/sub/old/
I know to create a patch for an existing file is easy:
diff -aru oldFile newFile 2>&1 | tee myPatch.patch
But what to do, if i want to create a patch for a totally new file? Assume my file is residing in a folder called TestDir. Earlier TestDir did not have a file called entirelyNewfile.c, but now it is having the same.
How to create a patch for entirelyNewfile.c? The idea is, the patch should get properly applied to the specs and generate the RPM build. With BUILD dir having this new file.
Just to add: if i try to take diff between the two directories, one having the new file and the other missing the same, to create the patch, it generates an error saying that file is only present in one folder
Add -N to the diff arguments.
diff /dev/null <newfile>
Will create a patch for your newfile.
The easiest way to do this that I know is to put all the files under version control (if they aren't already). I prefer Git, but something similar could be done in any other version control system:
git init
git add .
git commit -m "initial state"
<do your edits here>
git add .
git commit -m "new state"
git diff HEAD^1
Copying directory from source tree to binary tree. For example: How to copy www to bin folder.
work
├─bin
└─src
├─doing
│ └─www
├─include
└─lib
Thanks.
Since version 2.8, the file command has a COPY sub-command:
file(COPY yourDir DESTINATION yourDestination)
Note that:
Relative input paths are evaluated with respect to the current source
directory, and a relative destination is evaluated with respect to the
current build directory
With CMake 2.8 or later, use the file(COPY ...) command.
With CMake versions below 2.8, the following macro copies files from one directory to another. If you don't want to substitute variables in the copied files, then change the configure_file #ONLY argument (for example to COPYONLY).
# Copy files from source directory to destination directory, substituting any
# variables. Create destination directory if it does not exist.
macro(configure_files srcDir destDir)
message(STATUS "Configuring directory ${destDir}")
make_directory(${destDir})
file(GLOB templateFiles RELATIVE ${srcDir} "${srcDir}/*")
foreach(templateFile ${templateFiles})
set(srcTemplatePath ${srcDir}/${templateFile})
if(NOT IS_DIRECTORY ${srcTemplatePath})
message(STATUS "Configuring file ${templateFile}")
configure_file(
${srcTemplatePath}
${destDir}/${templateFile}
#ONLY)
endif(NOT IS_DIRECTORY ${srcTemplatePath})
endforeach(templateFile)
endmacro(configure_files)
As nobody has mentioned cmake -E copy_directory as a custom target, here's what I've used:
add_custom_target(copy-runtime-files ALL
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/runtime-files-dir ${CMAKE_BINARY_DIR}/runtime-files-dir
DEPENDS ${MY_TARGET})
The configure command will only copy files when cmake is run. Another option is to create a new target, and use the custom_command option. Here's one that I use (if you run it more than once, you'll have to modify the add_custom_target line to make it unique for each call).
macro(copy_files GLOBPAT DESTINATION)
file(GLOB COPY_FILES
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
${GLOBPAT})
add_custom_target(copy ALL
COMMENT "Copying files: ${GLOBPAT}")
foreach(FILENAME ${COPY_FILES})
set(SRC "${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME}")
set(DST "${DESTINATION}/${FILENAME}")
add_custom_command(
TARGET copy
COMMAND ${CMAKE_COMMAND} -E copy ${SRC} ${DST}
)
endforeach(FILENAME)
endmacro(copy_files)
Use execute_process and call cmake -E. If you want a deep copy, you can use the copy_directory command. Even better, you could create a symlink (if your platform supports it) with the create_symlink command. The latter can be achieved like this:
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink ${CMAKE_SOURCE_DIR}/path/to/www
${CMAKE_BINARY_DIR}/path/to/www)
From: http://www.cmake.org/pipermail/cmake/2009-March/028299.html
Thank! That is really helpful advice to use bunch of add_custom_target and add_custom_command. I wrote the following function to use everywhere in my projects. Is also specifies the installation rule. I use it primarily to export interface header files.
#
# export file: copy it to the build tree on every build invocation and add rule for installation
#
function (cm_export_file FILE DEST)
if (NOT TARGET export-files)
add_custom_target(export-files ALL COMMENT "Exporting files into build tree")
endif (NOT TARGET export-files)
get_filename_component(FILENAME "${FILE}" NAME)
add_custom_command(TARGET export-files COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_CURRENT_SOURCE_DIR}/${FILE}" "${CMAKE_CURRENT_BINARY_DIR}/${DEST}/${FILENAME}")
install(FILES "${FILE}" DESTINATION "${DEST}")
endfunction (cm_export_file)
Usage looks like this:
cm_export_file("API/someHeader0.hpp" "include/API/")
cm_export_file("API/someHeader1.hpp" "include/API/")
Based on the answer from Seth Johnson; wrote for more convenience:
# Copy files
macro(resource_files files)
foreach(file ${files})
message(STATUS "Copying resource ${file}")
file(COPY ${file} DESTINATION ${Work_Directory})
endforeach()
endmacro()
# Copy directories
macro(resource_dirs dirs)
foreach(dir ${dirs})
# Replace / at the end of the path (copy dir content VS copy dir)
string(REGEX REPLACE "/+$" "" dirclean "${dir}")
message(STATUS "Copying resource ${dirclean}")
file(COPY ${dirclean} DESTINATION ${Work_Directory})
endforeach()
endmacro()