Can I use environment variables in paths to crates in `Cargo.toml`? - windows

Is it possible to use environment variables in a Cargo.toml file?
Like so:
[package]
name = "tmp-xzxgxn"
version = "0.1.0"
edition = "2021"
[dependencies]
# bevy = {branch = "main", git = "https://github.com/bevyengine/bevy.git"}
# bevy = { path = "~/Documents/GitHub/bevy" }
bevy = { path = "%USERPROFILE%/Documents/GitHub/bevy" }
Note that ~ doesn't work either.

Related

What should I put into FindAppointmentsAsync's &self parameter?

I'm new to rust and am trying to make use of the windows cargo. But I don't understand what I should set the &self parameter in the FindAppointmentsAsync function.
This is Cargo.toml:
[package]
name = "rust-test"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
[dependencies.windows]
version = "0.43.0"
features = [
"ApplicationModel",
"ApplicationModel_Appointments",
"Foundation_Collections",
]
This is main.rs:
use std::time::Duration;
use windows::{
core::*, ApplicationModel::Appointments::*, Foundation::{DateTime, TimeSpan},
};
fn main() -> Result<()> {
let rangestart = DateTime::default();
let rangelength = TimeSpan::from(Duration::new(60 * 60 * 24 * 30, 0));
println!("test");
unsafe {
let store = AppointmentStore();
let result = AppointmentStore::FindAppointmentsAsync(&store, rangestart, rangelength);
}
Ok(())
}
If let store = AppointmentStore::new(); the error is no function or associated item named 'new' found
If let store = AppointmentStore();, the error is expected 1 argument, found 0
If let store = AppointmentStore(""); the error is cannot initialize a tuple struct which contains private fields
You cannot create an AppointmentStore directly, as it has private fields and does not expose a constructor function.
Looking at the docs, there are two ways to get an AppointmentStore:
By calling clone on an existing one.
By calling RequestStoreAsync on an AppointmentManager or AppointmentManagerForUser.
AppointmentManager is a struct with no fields, so you can create one by simply doing:
let foo = AppointmentManager;
let bar = foo.RequestStoreAsync(/* insert params here */);
AppointmentManagerForUser also cannot be constructed directly, and is obtained by calling GetForUser on an AppointmentManager.

How to combine two shell.nix files?

I have the first shell.nix file:
{ pkgs ? import ./nix { }
, useClang ? false
, ae_name ? "ae"
}:
with pkgs;
(if useClang then tvb.aeClangStdenv else tvb.aeGccStdenv).mkDerivation rec {
name = ae_name;
nativeBuildInputs = tvb.cppNativeBuildInputs;
buildInputs = tvb.rustBuildInputs
++ tvb.cppBuildInputs
++ tvb.rBuildInputs
;
TZDIR = "${tzdata}/share/zoneinfo";
LOCALE_ARCHIVE = "${glibcLocales}/lib/locale/locale-archive";
out_dir = (toString ./out);
cur_dir = (toString ./.);
shellHook = ''
export PS1="\[\033[38;5;10m\]\u#\h[${name} nix-shell]\[$(tput sgr0)\]\[\033[38;5;15m\]:\[$(tput sgr0)\]\[\033[38;5;39m\]\w\[$(tput sgr0)\]\\$\[$(tput sgr0)\] \[$(tput sgr0)\]"
# for tools only bin paths are needed
for prog in ${toString tvb.shellTools}; do
export PATH="$prog/bin:$PATH"
done
export DEPLOY_CFG=${cur_dir}/.deploy.json
export LD_LIBRARY_PATH="${out_dir}/lib:${fts5-snowball}/lib"
export PATH="${cur_dir}/lua/bin:${out_dir}/bin:$PATH"
export AE_SHARE="${out_dir}/share/ae"
export AE_LIBEXEC="${out_dir}/libexec/ae"
## LuaJIT
export LUA_PATH="$LUA_PATH;${cur_dir}/lua/lib/?.lua;${out_dir}/share/lua/5.1/?.lua;;"
export LUA_CPATH="$LUA_CPATH;${out_dir}/lib/lua/5.1/?.so;;"
## Lua box
export LUABOX_UNIT_PATH="${out_dir}/share/ae/box/units/?.lua;"
## Python
export PYTHONPATH="${out_dir}/lib/python2.7:$PYTHONPATH"
'';
}
and I have the seconds shell.nix file:
let
jupyter = import (builtins.fetchGit {
url = https://github.com/tweag/jupyterWith;
rev = "37cd8caefd951eaee65d9142544aa4bd9dfac54f";
}) {};
iPython = jupyter.kernels.iPythonWith {
name = "python";
packages = p: with p; [ numpy ];
};
iHaskell = jupyter.kernels.iHaskellWith {
extraIHaskellFlags = "--codemirror Haskell"; # for jupyterlab syntax highlighting
name = "haskell";
packages = p: with p; [ hvega formatting ];
};
jupyterEnvironment =
jupyter.jupyterlabWith {
kernels = [ iPython iHaskell ];
};
in
jupyterEnvironment.env
Firstly, I tried to append the second to the first one, but then I received the following error:
jbezdek#ubuntu:~$ nix-shell
error: syntax error, unexpected ID, expecting '{', at /home/jbezdek/shell.nix:51:3
After that, I tried many other combinations how to put those two together, but I have never been successful. Could you help me with that, please?
Merging two shell.nix files in full generality is tricky, and unlikely to be solved off the shelf.
To solve the case in point, I think you will just have to dig into the Nix expression language a little more to write a syntactically valid .nix file, that contains the content of both files. Something along the lines of this could work:
{ pkgs ? import ./nix { }
, useClang ? false
, ae_name ? "ae"
}:
with pkgs;
let
jupyter = import (builtins.fetchGit { ... })
...
jupyterEnvironment = ...
in
{
first_file = (if useClang ...).mkDerivation rec {
name = ae_name;
...
};
second_file = jupyterEnvironment.env;
}

Where Debug info stored in Framework?

As the title mentioned, I'm confusing about where is the debug info stored in .Framework file.
I googled for serval days, what I gots are:
Framework binary compiled by debug mode will include a debug info segment, to indicate the symbol location. Release mode compiling will move it to a dSYM file.
But, what confused me is, I build a framework with ninja, and it doesn't generate dSYM file. Meanwhile I can't find the symbol location by dwarfdump command or MachOView app. As Regards strings command can get some relative file path results, like ../../flutter/fml/memory/task_runner_checker.cc.
Here dwarfdump prints:
Flutter.framework/Flutter: file format Mach-O arm64
.debug_info contents:
Here is my questions:
When I triggered breakpoint at somewhere in the framework, the source code still shows. Why?
When I run lldb command, it shows:
(lldb) image lookup -a $pc --verbose
Address: Flutter[0x0000000001964f18] (Flutter.__TEXT.__text + 26604184)
Summary: Flutter`dart::BootstrapNatives::DN_LoadLibraryFromTypedData(dart::Thread*, dart::Zone*, dart::NativeArguments*) + 44 [inlined] dart::NativeArguments::NativeArgAt(int) const at object.cc:537
Flutter`dart::BootstrapNatives::DN_LoadLibraryFromTypedData(dart::Thread*, dart::Zone*, dart::NativeArguments*) + 44 [inlined] dart::DN_HelperLoadLibraryFromTypedData(dart::Isolate*, dart::Thread*, dart::Zone*, dart::NativeArguments*) at object.cc:534
Flutter`dart::BootstrapNatives::DN_LoadLibraryFromTypedData(dart::Thread*, dart::Zone*, dart::NativeArguments*) + 44 at object.cc:534
Module: file = "/Users/xx/Library/Developer/Xcode/DerivedData/XXX-ddigzjlnuypwnydlawevfrkmdsov/Build/Products/Debug-iphoneos/XXX.app/Frameworks/Flutter.framework/Flutter", arch = "arm64"
CompileUnit: id = {0x00000000}, file = "/Users/xx/Documents/workspace/aion/flutter_engine/src/third_party/dart/runtime/lib/object.cc", language = "c++14"
Function: id = {0x7d40006244d}, name = "dart::BootstrapNatives::DN_LoadLibraryFromTypedData(dart::Thread*, dart::Zone*, dart::NativeArguments*)", mangled = "_ZN4dart16BootstrapNatives27DN_LoadLibraryFromTypedDataEPNS_6ThreadEPNS_4ZoneEPNS_15NativeArgumentsE", range = [0x0000000117310eec-0x0000000117311490)
FuncType: id = {0x7d40006244d}, byte-size = 0, decl = bootstrap_natives.h:507, compiler_type = "class dart::ObjectPtr (class dart::Thread *, class dart::Zone *, class dart::NativeArguments *)"
Blocks: id = {0x7d40006244d}, range = [0x117310eec-0x117311490)
id = {0x7d40006249b}, ranges = [0x117310f18-0x1173113e0)[0x117311404-0x117311490), name = "DN_HelperLoadLibraryFromTypedData", decl = object.cc:534, mangled = _ZN4dartL33DN_HelperLoadLibraryFromTypedDataEPNS_7IsolateEPNS_6ThreadEPNS_4ZoneEPNS_15NativeArgumentsE, demangled = dart::DN_HelperLoadLibraryFromTypedData(dart::Isolate*, dart::Thread*, dart::Zone*, dart::NativeArguments*)
id = {0x7d40006253a}, range = [0x117310f18-0x117310f24), name = "NativeArgAt", decl = native_arguments.h:129, mangled = _ZNK4dart15NativeArguments11NativeArgAtEi, demangled = dart::NativeArguments::NativeArgAt(int) const
LineEntry: [0x0000000117310f18-0x0000000117310f24): /Users/xx/Documents/workspace/xxx/flutter_engine/src/third_party/dart/runtime/vm/native_arguments.h:132:14
Symbol: id = {0x0013fd0f}, range = [0x0000000117310eec-0x0000000117311490), name="dart::BootstrapNatives::DN_LoadLibraryFromTypedData(dart::Thread*, dart::Zone*, dart::NativeArguments*)", mangled="_ZN4dart16BootstrapNatives27DN_LoadLibraryFromTypedDataEPNS_6ThreadEPNS_4ZoneEPNS_15NativeArgumentsE"
Variable: id = {0x7d400062553}, name = "this", type = "const dart::NativeArguments *", location = DW_OP_reg20 W20, decl =
Variable: id = {0x7d40006255c}, name = "index", type = "int", location = <decoding error> 00 00 00, decl = native_arguments.h:129
Variable: id = {0x7d4000624a8}, name = "isolate", type = "dart::Isolate *", location = , decl = object.cc:534
Variable: id = {0x7d4000624ad}, name = "thread", type = "dart::Thread *", location = , decl = object.cc:534
Variable: id = {0x7d4000624b2}, name = "zone", type = "dart::Zone *", location = DW_OP_reg19 W19, decl = object.cc:534
Variable: id = {0x7d4000624bb}, name = "arguments", type = "dart::NativeArguments *", location = DW_OP_reg20 W20, decl = object.cc:534
Variable: id = {0x7d4000624c4}, name = "program", type = "unique_ptr<dart::xx_kernel::Program, std::__1::default_delete<dart::xx_kernel::Program> >", location = DW_OP_breg31 WSP+64, decl = object.cc:556
Variable: id = {0x7d400062468}, name = "thread", type = "dart::Thread *", location = DW_OP_reg24 W24, decl = object.cc:534
Variable: id = {0x7d400062479}, name = "zone", type = "dart::Zone *", location = DW_OP_reg19 W19, decl = object.cc:534
Variable: id = {0x7d40006248a}, name = "arguments", type = "dart::NativeArguments *", location = DW_OP_reg20 W20, decl = object.cc:534
So, where the lldb get Compile Unit and LineEntry outputs?
Debug information on Darwin systems exists in one of two places: In the .o files, and later after dsymutil is run to create a .dSYM, it exists in the .dSYM bundle, all collected together, relocated to the actual binary's addresses.
This was a build-link-debug performance enhancement. Linking all of the debug information -- updating all the symbol addresses, copying it all around -- is very slow, so leaving the debug information in the .o files for this common iterative development cycle, and having the debugger locate the .o files and update the addresses of the functions internally, allows for rapid development.
Leaving all of the debug information in the .o files requires that they all be present, of course! And at the same file paths. So it is not good when you need to move a binary between computers, or save it for later debugging. For these cases, you link the debug information with dsymutil and you get a .dSYM bundle.

Version increment using gradle task

I want to increase the version number of my project from 1.0.0. to 1.0.1 automatically whenever a new build is made through bash command. I only need to increase path number and others i will be increasing manually during manual build.
i want to change
this :
version=1.0.0
to
This:
version=1.0.1
using gradle task.
any help that how can i do this .
Is there any way to update this using regex or using substring function.
Here is an example task:
version='1.0.0' //version we need to change
task increment<<{
def v=buildFile.getText().find(version) //get this build file's text and extract the version value
String minor=v.substring(v.lastIndexOf('.')+1) //get last digit
int m=minor.toInteger()+1 //increment
String major=v.substring(0,v.length()-1) //get the beginning
//println m
String s=buildFile.getText().replaceFirst("version='$version'","version='"+major+m+"'")
//println s
buildFile.setText(s) //replace the build file's text
}
Run this task several times and you should see the version change.
A variant:
version='1.0.0'
task incrementVersion<<{
String minor=version.substring(version.lastIndexOf('.')+1)
int m=minor.toInteger()+1
String major=version.substring(0,version.length()-1)
String s=buildFile.getText().replaceFirst("version='$version'","version='"+major+m+"'")
buildFile.setText(s)
}
Here's a custom task for version bumps in Gradle (Android project):
class Version {
private int major
private int minor
private int patch
private int code
Version(int code, String version) {
this.code = code
def (major, minor, patch) = version.tokenize('.')
this.major = major.toInteger()
this.minor = minor.toInteger()
this.patch = patch.toInteger()
}
#SuppressWarnings("unused")
void bumpMajor() {
major += 1
minor = 0
patch = 0
code += 1
}
#SuppressWarnings("unused")
void bumpMinor() {
minor += 1
patch = 0
code += 1
}
#SuppressWarnings("unused")
void bumpPatch() {
patch += 1
code += 1
}
String getName() { "$major.$minor.$patch" }
int getCode() { code }
}
tasks.addRule("Pattern: bump<TYPE>Version") { String taskName ->
if (taskName.matches("bump(Major|Minor|Patch)Version")) {
task(taskName) {
doLast {
String type = (taskName - 'bump' - 'Version')
println "Bumping ${type.toLowerCase()} version…"
int oldVersionCode = android.defaultConfig.versionCode
String oldVersionName = android.defaultConfig.versionName
version = new Version(oldVersionCode, oldVersionName)
version."bump$type"()
String newVersionName = version.getName()
String newVersionCode = version.getCode()
println "$oldVersionName ($oldVersionCode) → $newVersionName ($newVersionCode)"
def updated = buildFile.getText()
updated = updated.replaceFirst("versionName '$oldVersionName'", "versionName '$newVersionName'")
updated = updated.replaceFirst("versionCode $oldVersionCode", "versionCode $newVersionCode")
buildFile.setText(updated)
}
}
}
}
See this Kanji learning Android app for completeness.
Prerequisites
Following format required (note the single quotes):
android {
defaultConfig {
versionCode 3
versionName '0.3.13'
}
}
Usage
$ ./gradlew bumpPatchVersion
> Task :app:bumpPatchVersion
Bumping patch version…
0.3.13 (3) → 0.3.14 (4)
BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed
$ ./gradlew bumpMinorVersion
> Task :app:bumpMinorVersion
Bumping minor version…
0.3.14 (4) → 0.4.0 (5)
BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed
$ ./gradlew bumpMajorVersion
> Task :app:bumpMajorVersion
Bumping major version…
0.4.0 (5) → 1.0.0 (6)
BUILD SUCCESSFUL in 0s
1 actionable task: 1 executed
You could also use split with a increment-matrix, that could be changed depending on the amount of changes:
def version = '1.0.0'
def incstep = '0.0.1'.split(/\./).collect{it.toInteger()}
def indexedVersionList = version.split(/\./).toList().withIndex()
def updatedVersionList = indexedVersionList.collect{num, idx -> num.toInteger()+incstep[idx]}
def updatedVersion = updatedVersionList.join(".")
This is how I did it with Kotlin DSL (build.gradle.kts):
tasks.create("incrementVersion") {
group = "my tasks"
description = "Increments the version in this build file everywhere it is used."
fun generateVersion(): String {
val updateMode = properties["mode"] ?: "minor" // By default, update the minor
val (oldMajor, oldMinor, oldPatch) = version.split(".").map(String::toInt)
var (newMajor, newMinor, newPatch) = arrayOf(oldMajor, oldMinor, 0)
when (updateMode) {
"major" -> newMajor = (oldMajor + 1).also { newMinor = 0 }
"minor" -> newMinor = oldMinor + 1
else -> newPatch = oldPatch + 1
}
return "$newMajor.$newMinor.$newPatch"
}
doLast {
val newVersion = properties["overrideVersion"] as String? ?: generateVersion()
val oldContent = buildFile.readText()
val newContent = oldContent.replace("""= "$version"""", """= "$newVersion"""")
buildFile.writeText(newContent)
}
}
Usage:
./gradlew incrementVersion [-P[mode=major|minor|patch]|[overrideVersion=x]]
Examples:
./gradlew incrementVersion -Pmode=minor
./gradlew incrementVersion -PoverrideVersion=2.5.11
That is given that you have something like this in your build script:
version = "1.2.3"
... and the patch part of the version is just a number (not containing letters like alpha, rc, etc.).
Below solution will not create an issue evern last number exceed from 9-10 and so on
version='1.0.11.1001'
task incrementrevsion{
def v = version
println v
String minor=v.substring(v.lastIndexOf('.')+1) //get last digit
int m=minor.toInteger()+1 //increment
println m
String major=v.substring(0,v.lastIndexOf(".")); //get the beginning
println major
String s=buildFile.getText().replaceFirst("version='$version'","version='"+major+ "." +m+"'")
//println s
buildFile.setText(s) //replace the build file's text
}
def patch = version.substring(version.lastIndexOf('.') + 1)
def p = patch.toInteger() + 1
def major = version.substring(0, version.length() - p.toString().length())
def s = buildFile.getText().replaceFirst("version = '$version'", "version = '" + major + p + "'")
buildFile.setText(s)
The only difference with Alexiy's answer that line 3 contains m.toString().length() as if minor version > 10, i.e 1.0.12 and you will use that approach it will change it to 1.0.113. We need to calculate the length of minor version instead of chopping off only 1 symbol.
And one more thing, usually the last number is called patch, minor is a middle one :)
My Solution where the version will be set by a Parameter.
version = '4.0.0' // I have whitespaces between the equals-sign
task setVersion << {
group = 'Versioning'
description = "Sets the version to the new number specified with -PnewVersion=\'x.x.x\'"
println version
if(project.hasProperty('newVersion')) {
println 'Set Project to new Version '+newVersion
String s=buildFile.getText().replaceFirst("version = '$version'","version = '"+newVersion+"'")
buildFile.setText(s)
}
}
Call Gradle Task with:
gradle setVersion -PnewVersion='5.1.1'
As for me work this solution.
You need add this code into build.gradle file:
version='1.0.1'
tasks.register("incrementVersion") {
doLast {
def ver = version
println ver
String lastNumber = ver.substring(ver.lastIndexOf('.') + 1)
int increment = lastNumber.toInteger() + 1
println increment
String firstNumber = ver.substring(0, ver.lastIndexOf("."))
println firstNumber
String result = buildFile.getText().replaceFirst("version='$version'","version='" + firstNumber + "." + increment + "'")
buildFile.setText(result)
}
}
I know I am posting this quite late, but the answers mentioned above work well upto '1.0.99'. After which it starts misbehaving.
If any one is still interested, I found a different approach.
task increment {
def v = buildFile.getText().find(version)
def (major, minor, patch) = v.tokenize('.')
int newPatch = patch.toInteger() + 1
String newVersion = major + "." + minor + "." + newPatch
String updatedVersion = buildFile.getText().replaceFirst("version='"+v+"'","version='"+newVersion+"'")
buildFile.setText(updatedVersion)
}
This is an example of same think but with KTS(Kotlin Script).
val newVersion: String? by project
tasks.register("bumpVersion") {
this.doFirst {
println("Old version $version")
val newVersion = takeIf { newVersion.isNullOrBlank() }?.let {
val versionArray = version.toString().split(".")
"${versionArray[0]}.${versionArray[1]}.${versionArray.last().toInt().plus(1)}"
} ?: newVersion
buildFile.readText().apply {
println("Bump to $newVersion")
val content = this.replaceFirst("version = \"$version\"", "version = \"$newVersion\"")
buildFile.writeText(content)
}
}
}
Increment automatic the patch or it is possible to send new version as property.
./gradlew bumpVersion -PnewVersion=0.2.0
Kotlin dsl:
tasks.create("incrementPatch") {
group = "version"
description = "Автоматически поднять патч версию в файле VERSION"
doFirst {
incrementVersion("patch")
}
}
tasks.create("incrementMinor") {
group = "version"
description = "Автоматически поднять минор версию в файле VERSION"
doFirst {
incrementVersion("minor")
}
}
tasks.create("incrementMajor") {
group = "version"
description = "Автоматически поднять мажор версию в файле VERSION"
doFirst {
incrementVersion("major")
}
}
tasks.named("compileKotlin") {
dependsOn(":incrementPatch")
}
fun incrementVersion(updateMode: String){
val versions = file("version").readText().trim()
println("read version = $versions")
val (oldMajor, oldMinor, oldPatch) = versions.substringBefore("-").split(".").map(String::toInt)
var (newMajor, newMinor, newPatch) = arrayOf(oldMajor, oldMinor, 0)
when (updateMode) {
"major" -> newMajor = (oldMajor + 1).also { newMinor = 0 }
"minor" -> newMinor = oldMinor + 1
else -> newPatch = oldPatch + 1
}
val newVersion ="$newMajor.$newMinor.$newPatch-SNAPSHOT"
println("new version = $newVersion")
file("version").writeText(newVersion)
}

Nix: Compile Vim with Ruby

I am using the Nix package manager on OS X. Let's say for the sake of argument I have a config.nix file that uses a pattern like so, allowing me to install the vimEnv no problem.
# ~/.nixpkgs/config.nix
{ pkgs }: {
# Looking around I have seen overrides something along these lines...
# nixpkgs.config.packageOverrides = pkgs: rec {
# vim = pkgs.vim_configurable.override {
# ruby = true;
# };
# };
packageOverrides = super: let pkgs = super.pkgs; in with pkgs; rec {
myEnv = pkgs.buildEnv {
name = "myEnv";
paths = [
# ...snip
vim
# ...snip
];
};
};
}
I know that there are elaborate options available for maintaining a .vimrc and vim plugins using Nix and by overriding vim_configurable options and so forth (for example), and it would be nice to find the time to do that at some point. However, all I want to do for now is to install via Nix a version of Vim which is compiled with Ruby support.
What would be the easiest or most concise way for me to achieve this in my config.nix?
And, after some hacking, here is the simplest solution I have found:
# ~/.nixpkgs/config.nix
{ pkgs }: {
packageOverrides = super: let pkgs = super.pkgs; in with pkgs; rec {
myVim = pkgs.vim_configurable.override {
config.vim = {
ruby = true;
};
ruby = ruby;
};
myEnv = pkgs.buildEnv {
name = "myEnv";
paths = [
myVim
];
};
};
}
And install it with nix-env -i myEnv.
You can try to compile vim yourself. In order to get ruby support this way all you have to do is add the --rubyinterp flag when you run ./configure

Resources