Reputation: 124
I'm trying to build a sass workspace.
I - Goal
I have two directories :
/css is a destination directory for /sass files convertion result.
My goal is to code sass or scss in /sass directory, and call a bash file to convert each .sass or .scss file from /sass into a .css result in /css directory.
II - What I did:
[/!\ Maybe useless to read it entirelly, firstly go to the part III which explain the problem.]
Here is my /convert bash file :
SASS_FILES_PATH=sass
CSS_DEST_PATH=css
function get_cleaned_filename {
# Split fileName to removre file directory:
IFS='/' # Split delimiter
read -ra ADDR <<< "$1"
local ARRAY_LENGTH=${#ADDR[@]}
RESULT="${ADDR[$ARRAY_LENGTH - 1]}"
# Split fileName to removre file type:
IFS='.' # Split delimiter
read -ra ADDR <<< "$RESULT"
RESULT="${ADDR[0]}"
}
# function convert_file/1 convert the file in parameter into .css file
# Parameters : $1 : path to source file
# Precondition : file in parameter should have .scss ou .sass extension
#
# Postcondition : create a .css and a .css.map files that correspond to
# the converted .sass or .scss file.
function convert_file {
get_cleaned_filename $f;
FILENAME=$RESULT;
# We can have two files .sass and .scss using the same name :
if test -f $CSS_DEST_PATH/$FILENAME.css;
then
echo "a file $CSS_DEST_PATH/$FILENAME.css exist";
FILENAME=$FILENAME_2;
echo "renamed to $FILENAME_2";
fi
echo "[DEBUG]: sass ${f} ${CSS_DEST_PATH}/${FILENAME}.css";
sass --trace ${f} ${CSS_DEST_PATH}/${FILENAME}.css;
}
if ! test -f $SASS_FILES_PATH/*.sass || ! test -f $SASS_FILES_PATH/*.scss;
then
echo "Pas de fichier à convertir dans le dossier, aucune opération n'a été éxécutée.";
else
# Empty CSS_DEST_PATH :
if test -f $CSS_DEST_PATH/*;
then
for cssFileName in $CSS_DEST_PATH/*;
do
rm $cssFileName;
done
fi
# Convert every .scss and .sass files into .css
# If scss file exist in curent directory
if test -f $SASS_FILES_PATH/*.scss;
then
# Convert each .scss file into css and move it to css directory
for f in $SASS_FILES_PATH/*.scss;
do
convert_file $f;
done
fi
# If sass file exist in curent directory
if test -f $SASS_FILES_PATH/*.sass;
then
# Convert each .sass file into css and move it to css directory
for f in $SASS_FILES_PATH/*.sass;
do
convert_file $f;
done
fi
fi
III - What is the mistake:
In function convert_file\1, i have a mistake :
echo "[DEBUG]: sass ${f} ${CSS_DEST_PATH}/${FILENAME}.css";
sass --trace ${f} ${CSS_DEST_PATH}/${FILENAME}.css;
The sass call (second line) return an error:
me@myComputer:~/Desktop/computing/sassWorkshop$ bash convert
[DEBUG]: sass sass/test.scss css/test.css
Traceback (most recent call last):
7: from /usr/bin/sass:8:in `<main>'
6: from /usr/lib/ruby/vendor_ruby/sass/exec/base.rb:19:in `parse!'
5: from /usr/lib/ruby/vendor_ruby/sass/exec/base.rb:52:in `parse'
4: from /usr/lib/ruby/vendor_ruby/sass/exec/sass_scss.rb:52:in `process_result'
3: from /usr/lib/ruby/vendor_ruby/sass/exec/base.rb:120:in `process_result'
2: from /usr/lib/ruby/vendor_ruby/sass/exec/base.rb:182:in `open_file'
1: from /usr/lib/ruby/vendor_ruby/sass/exec/base.rb:182:in `open'
/usr/lib/ruby/vendor_ruby/sass/exec/base.rb:182:in `initialize': No such file or directory @rb_sysopen - sass/test (Errno::ENOENT)
Note that "convert" is the name of the bash file i use !
The thing i don't understand is that my echo "[DEBUG]: ..." line print that according to my variables, the sass call is "sass sass/test.scss css/test.css". But when i type this line into my terminal, the line works well and my .css file is created.
IV - What i tried:
I tried "rm .sass-cache/ -R" which don't changed anything.
I'm sorry if my post isn't well formed, or if there is many English mistakes (not my mother thong) if it's the case told me please :)
Thanks for any comment than can help me
Upvotes: 0
Views: 423
Reputation: 19675
You should really check your script with shellcheck.net as it contains several errors, mainly due to missing double quotes around variables, use of deprecated test and something that I can't explain:
FILENAME=$FILENAME_2;
The value of the variable FILENAME_2
is not set.
Also:
if ! test -f $SASS_FILES_PATH/*.sass || ! test -f $SASS_FILES_PATH/*.scss;
-f
does not work with globs, so you need to iterate each globbing to update flags and test each flag, or better use the find
command return code
if ! find "$SASS_FILES_PATH/" -name '*.sass' || ! find "$SASS_FILES_PATH/" -name '*.scss'
Useless and dangerous unsecured rm
loop:
for cssFileName in $CSS_DEST_PATH/*;
do
rm $cssFileName;
done
Replace with
rm -- "$CSS_DEST_PATH/"*
Same issue, cannot test -f
with globbing:
# If scss file exist in curent directory
if test -f $SASS_FILES_PATH/*.scss;
This will test files exist and execute the conversion on each entry:
find "$SASS_FILES_PATH" -name '*.scss" -o -name '*.sass' -exec convert {} \;
Your function to clean file-name is suboptimal:
function get_cleaned_filename {
# Split fileName to removre file directory:
IFS='/' # Split delimiter
read -ra ADDR <<< "$1"
local ARRAY_LENGTH=${#ADDR[@]}
RESULT="${ADDR[$ARRAY_LENGTH - 1]}"
# Split fileName to removre file type:
IFS='.' # Split delimiter
read -ra ADDR <<< "$RESULT"
RESULT="${ADDR[0]}"
}
Instead:
function get_cleaned_filename {
filename="${1##*/}" # remove leading directories path
echo "${filename%\.*}" # remove dot suffix
}
Then in convert_file
:
function convert_file {
FILENAME="$(get_cleaned_filename "$1")";
Finally, this may do what you want:
find sass/ -type f \( -name '*.scss' -o -name '*.sass' \) -exec bash -c 'src="$0"; _tdest="/${0%\.*}"; dest="css/${_tdest##*/}.css"; rm -f "$dest"; sass --trace "$src" "$dest"' {} \;
or
#!/usr/bin/env bash
find sass/ -type f \( -name '*.scss' -o -name '*.sass' \) -exec bash -c '
# Source file (.scss or .sass) passed as argument 0
src="$0"
# Strip-out file name extension
_tdest="/${0%\.*}"
# Construct destination file path/name.css
dest="css/${_tdest##*/}.css" # Construct destination file path/name.css
# Remove destination file if it exists
rm -f "$dest"
# Perform the scss|sass compilation
sass --trace "$src" "$dest"
' {} \;
Upvotes: 1