mor

Cross platform dependency manager

commit 57ceacf508d86d134b2e7f349bd49cccdba6ffa9
parent 31e3f5eabbf5e5be1be83b7777c478b061701ce6
Author: Bharatvaj Hemanth <bharatvaj@yahoo.com>
Date: Mon, 15 Apr 2024 02:15:54 +0530

Add :unzip_archive feature

Update README, Add Config File section

Support '=' and '&' in the value field of key=value

Add CHANGELOG
4 files changed, 118 insertions(+), 68 deletions(-)
A
.gitignore
|
1
+
A
CHANGELOG
|
4
++++
M
README
|
87
+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
M
mor.cmd
|
94
+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1 @@
+out/
diff --git a/CHANGELOG b/CHANGELOG
@@ -0,0 +1,4 @@
+mor v0.2
+--------
+- Handle urls with '&'
+- Add support for extraction using 'tar' (available in windows 10 by default)
diff --git a/README b/README
@@ -9,42 +9,57 @@ mor
 mor(pheus) is tool that simplifies dependency management the right way.
 Some might even say it is a red-pill way of dependency management.
 
-mor searches for requirements.ini file in the current folder, and uses it's content to
-download files.
+mor searches for requirements.ini file in the current folder, and uses it's
+content to download files.
 
 GOALS
 -----
 * Should work standalone
 * Cross-platform
-* Tiny - .cmd on windows, .sh on *NIX
+* Tiny - mor.cmd for windows, mor.sh for *NIX
 
-Section
--------
-mor uses [sections] of the .ini file to setup targets and subdirectories
+Config File
+------------
+mor uses .ini files as config files and can be given to mor with -c flag.
+When no flags are given, it searches for requirements.ini in the current
+working directory.
 
-Sections in mor are the names of the sub-directories
+In a mor config file, the [sections] represent a directory or target.
+The key=value pair under the [section] are the files to download in that
+current directory.
 
-	[precompiled]
-	libfoo-2.7=https://example.com/awavauatush/libfoo.git
+[$] is a special section that is discussed in 'Variables' below.
+
+	; requirements.ini
+	[$]
+	/=out
 
-The result of this is the following,
+	[precompiled]
+	libfoo-2.7=https://example.com/awavauatush/libfoo.zip
+	libbar-3.5=https://example.com/awavauatush/libbar.zip
+	...
 
 	$ mor precompiled
-	$ ls precompiled
-	libfoo-2.7
+	$ tree out/
+	precompile
+	|--libbar-3.5.zip
+	|--libbar-3.5/
+	|--libfoo-2.7.zip
+	|--libfoo-2.7/
 
 Targets
 -------
 
-Not all targets are sub-directoies mind you!
+Not all sections create sub-directoies mind you!
 
-Sections that have a '@' or '#' as the starting letter are treated as target(@) and target query(#).
+Sections that have a '@' or '#' as the starting letter are treated as target(@)
+and target query(#).
 
-Previously we have created [precompiled] section and invoked the mor command to download it. Real life
-is seldom this simple.
+Previously we have created [precompiled] section and invoked the mor command to
+download it. Real life is seldom this simple.
 
-Usually we are in a situation where the pre-compiled binaries are different for different architectures
-and platforms.
+Usually we are in a situation where the pre-compiled binaries are different for
+different architectures and platforms.
 
 	; packages.ini
 	[precompiled-macos]

@@ -77,23 +92,15 @@ Variables in mor has a specific rule and follows the following regex,
 
 	([a-z][A-z])*[0-9][a-z]
 
-Specials
---------
-$ - use to deference a variable
-
-
-Example
--------
-	; packages.ini
 	[$]
+	; the output folder
+	/=outfolder
+	; arbitrary variables
 	github=https://github.com
-	select=k-v
-	/=out/.sysroot
 
-	[folder/]
-	libfoo-2.7=$github/foo/libfoo/releases/download/v26.1/foo-26.1-osx-universal_binary.zip
-	libfoo-git-2.7=$github/foo/libfoo.git
 
+Example
+-------
 	; requirements.ini
 	[$]
 	>[]=packages.ini

@@ -106,8 +113,18 @@ Example
 	[@lib:x86_64-apple-darwin]
 	libfoo-git=2.7
 
-Bugs/Feature
-------------
+	; packages.ini
+	[$]
+	github=https://github.com
+	match=k-v
+	/=out/.sysroot
+
+	[folder/]
+	libfoo-2.7=$github/foo/libfoo/releases/download/v26.1/foo-26.1-osx-universal_binary.zip
+	libfoo-git-2.7=$github/foo/libfoo.git
+
+Bugs/Feature/Todo
+-----------------
 - Deferencing a $variable second time is disabled. This is for simplicity/security.
 
 - Currently it is not possible to null a variable with -D in Windows.

@@ -117,6 +134,10 @@ Bugs/Feature
 The above will silently assign 'download' to $var.
 This is a bug with how the cmd process arguments. Use -Dvar="" instead.
 
+- TODO Implement variables expansion
+- TODO Add test cases
+- TODO Merge if two section with same names are present
+
 Credits
 -------
 The graphics is a derivative of "butler" by jgs.
diff --git a/mor.cmd b/mor.cmd
@@ -1,22 +1,15 @@
 @echo off
 setlocal EnableDelayedExpansion
-set mor_version=0.1
+set mor_version=0.2
+set root_dir=%cd%\out\
 
 rem default values
 set /a is_logi=0
 set config_file=requirements.ini
 
-call :read_ini requirements.ini
-
-exit /b
-
 if "%~1" == "" goto print_usage
 goto :main
 
-:unarchive <archive> <destination>
-if "%~1x" == ".zip" do unzip "%~1" -d "%~2"
-goto :eof
-
 :logi
 if %is_logi% equ 1 echo %*
 goto :eof

@@ -32,47 +25,77 @@ set /a section_count=0
 set current_section=[
 
 rem locally remove env variables starting with '['
-for /f "usebackq delims== tokens=1" %%l in ( `set [` ) do (
-    set %%l=
-    echo before: set %%l=
-) 2>nul
+set [ 2>nul && for /f "usebackq delims== tokens=1" %%l in ( `set [` ) do (
+	set %%l=
+)
 
-for /f "usebackq delims=: tokens=1,*" %%l in ( `findstr /n /v ^; "%1"` ) do (
-	for /f "usebackq delims==] tokens=1,*" %%a in ( '%%m' ) do (
-        echo actual: %%m
-		set key=%%a
+for /f "usebackq delims=: tokens=1,*" %%l in ( `findstr /n /v ^; %~1` ) do (
+	for /f "usebackq delims==] tokens=1,*" %%a in ( '%%~m' ) do (
+		call :logi actual: %%m
+		set key=%%~a
 		if "!key:~0,1!" == "[" (
 			set current_section=%%a
-            set %%a= 
-			echo section set: !current_section!
+			set %%a= 
+			call :logi section set: !current_section!
 		) else (
-            set [precompiled || (
-                echo [precompiled not found, maybe first?
-            )
-            for /f "usebackq delims== tokens=1,*" %%t in (`set !current_section!`) do (
-                set "!current_section!=%%u %%a %%b "
-                echo set "!current_section!=%%u %%a %%b "
-            )
-
+			for /f "usebackq delims== tokens=1,*" %%t in (`set !current_section!`) do (
+				set !current_section!=%%u %%a "%%b" 
+				call :logi set !current_section!=%%u %%a "%%b" 
+			)
 		)
 	)
 )
-for /f "useback delims== tokens=1,*" %%l in (`set [`) do (
-    echo %%l: %%m
+
+for /f "usebackq delims==[ tokens=1,*" %%l in (`set [`) do (
+	call :prime_download %%l %%~m 
 )
-echo --------------
-for /f "tokens=1,2" %%t in ( "!%section%!" ) do (
-	echo %%t
-	echo %%u
+endlocal
+goto :eof
+
+:prime_download
+setlocal EnableDelayedExpansion
+set target=%1
+shift
+for /f %%a in ("%targets%") do (
+	if "!target!" == "%%a" (
+		set current_target_dir="%root_dir%\%%a"
+		call :logi Current Target Dir: !current_target_dir!
+		if not exist "!current_target_dir!" mkdir "!current_target_dir!"
+		:key_value
+		if "%~1" == "" goto :eof
+		for %%i in (%2) do set ext=%%~xi
+		call :download_archive !current_target_dir! %1 %2 !ext!
+		call :unzip_archive !current_target_dir! %1 !ext!
+		shift
+		shift
+		goto :key_value
+	)
 )
 endlocal
 goto :eof
 
+:unzip_archive
+setlocal
+	echo x [%2]
+	tar xzf "%1\%2%3" -C %1
+endlocal
+goto :eof
+
+:download_archive
+setlocal
+	echo v [%2] %3
+	bitsadmin /rawreturn /transfer "mor %2" %3 "%1\%2%4" || (
+		echo fatal: Failed while downloading %3
+		exit /b
+	)
+endlocal
+goto :eof
+
 :main
 setlocal
 :parse
 set arg=%~1
-if "%~1" == "" goto :eof
+if "%~1" == "" goto :main_continue
 if "%~1" == "-v" (
 	echo mor v%mor_version%
 	goto :eof

@@ -102,8 +125,9 @@ if "%arg:~0,1%" == "=" echo "= command"
 
 shift
 goto parse
+:main_continue
+call :read_ini "%config_file%"
 endlocal
 goto :eof
 
-
 endlocal