├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── README.md ├── default.nix ├── example ├── src │ └── main.rs ├── src2 │ └── main.rs └── src3 │ └── main.rs └── src └── main.rs /.gitignore: -------------------------------------------------------------------------------- 1 | nix-crates-index/ 2 | # Compiled files 3 | *.o 4 | *.so 5 | *.rlib 6 | *.dll 7 | *.swp 8 | 9 | # Executables 10 | *.exe 11 | 12 | # Generated by Cargo 13 | target/ 14 | 15 | # Generated by Nix 16 | **/result 17 | 18 | core 19 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | [root] 2 | name = "cratesParser" 3 | version = "0.1.0" 4 | dependencies = [ 5 | "rustache 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", 6 | "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", 7 | "walkdir 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)", 8 | ] 9 | 10 | [[package]] 11 | name = "aho-corasick" 12 | version = "0.5.3" 13 | source = "registry+https://github.com/rust-lang/crates.io-index" 14 | dependencies = [ 15 | "memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", 16 | ] 17 | 18 | [[package]] 19 | name = "kernel32-sys" 20 | version = "0.2.2" 21 | source = "registry+https://github.com/rust-lang/crates.io-index" 22 | dependencies = [ 23 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 24 | "winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", 25 | ] 26 | 27 | [[package]] 28 | name = "libc" 29 | version = "0.2.18" 30 | source = "registry+https://github.com/rust-lang/crates.io-index" 31 | 32 | [[package]] 33 | name = "memchr" 34 | version = "0.1.11" 35 | source = "registry+https://github.com/rust-lang/crates.io-index" 36 | dependencies = [ 37 | "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", 38 | ] 39 | 40 | [[package]] 41 | name = "regex" 42 | version = "0.1.80" 43 | source = "registry+https://github.com/rust-lang/crates.io-index" 44 | dependencies = [ 45 | "aho-corasick 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", 46 | "memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", 47 | "regex-syntax 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)", 48 | "thread_local 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)", 49 | "utf8-ranges 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)", 50 | ] 51 | 52 | [[package]] 53 | name = "regex-syntax" 54 | version = "0.3.9" 55 | source = "registry+https://github.com/rust-lang/crates.io-index" 56 | 57 | [[package]] 58 | name = "rustache" 59 | version = "0.1.0" 60 | source = "registry+https://github.com/rust-lang/crates.io-index" 61 | dependencies = [ 62 | "regex 0.1.80 (registry+https://github.com/rust-lang/crates.io-index)", 63 | "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", 64 | ] 65 | 66 | [[package]] 67 | name = "rustc-serialize" 68 | version = "0.3.22" 69 | source = "registry+https://github.com/rust-lang/crates.io-index" 70 | 71 | [[package]] 72 | name = "thread-id" 73 | version = "2.0.0" 74 | source = "registry+https://github.com/rust-lang/crates.io-index" 75 | dependencies = [ 76 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 77 | "libc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)", 78 | ] 79 | 80 | [[package]] 81 | name = "thread_local" 82 | version = "0.2.7" 83 | source = "registry+https://github.com/rust-lang/crates.io-index" 84 | dependencies = [ 85 | "thread-id 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)", 86 | ] 87 | 88 | [[package]] 89 | name = "utf8-ranges" 90 | version = "0.1.3" 91 | source = "registry+https://github.com/rust-lang/crates.io-index" 92 | 93 | [[package]] 94 | name = "walkdir" 95 | version = "1.0.3" 96 | source = "registry+https://github.com/rust-lang/crates.io-index" 97 | dependencies = [ 98 | "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", 99 | "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", 100 | ] 101 | 102 | [[package]] 103 | name = "winapi" 104 | version = "0.2.8" 105 | source = "registry+https://github.com/rust-lang/crates.io-index" 106 | 107 | [[package]] 108 | name = "winapi-build" 109 | version = "0.1.1" 110 | source = "registry+https://github.com/rust-lang/crates.io-index" 111 | 112 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "cratesParser" 3 | version = "0.1.0" 4 | authors = ["Paul Seitz "] 5 | 6 | [dependencies] 7 | walkdir = "1" 8 | rustc-serialize = "0.3" 9 | rustache = "0.1" 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nixcrates 2 | An early stage drop-in replacement for `cargo` which uses crates.io index. 3 | 4 | The very awesome guys over at https://nixcloud.io implemented this for fractalide. Please do consider contracting them for your hardcore nix related jobs! 5 | 6 | # Usage 7 | 8 | ## Iterative updates (you'll mostly need this) 9 | 10 | 1. initial setup of environment, thereafter not needed: 11 | 12 | ``` 13 | $ cd $dev # your development directory 14 | $ mkdir nixcrates && cd nixcrates 15 | $ git clone https://github.com/rust-lang/crates.io-index 16 | $ git clone https://github.com/fractalide/nix-crates-index.git 17 | $ fork https://github.com/fractalide/nixcrates.git 18 | $ git clone https://github.com/your_account/nixcrates.git 19 | $ cd nixcrates 20 | $ nix-env -f default.nix -iA nixcrates 21 | ``` 22 | 23 | 2. update the crates.io-index repository: 24 | 25 | ``` 26 | $ cd crates.io-index 27 | $ git pull 28 | $ git rev-parse master 29 | $ fc336466a7ede6f14ce427deb5a64c5d02d14be0 30 | ``` 31 | 32 | 3. use `nixcrates` to update it 33 | 34 | ``` 35 | $ cd nix-crates-index/ 36 | $ rm -r */ 37 | $ nixcrates ../crates.io-index/ ./ 38 | $ git add * 39 | # just use the rev from the crates.io-index below 40 | $ git commit -m 'crate.io rev @ fc3364, ' 41 | ``` 42 | 43 | 4. send a pull request! 44 | 45 | 5. for added security add your crates to the `allTargets` attribute `nixcrates/default.nix` to check that they built properly 46 | 47 | nix-build -A allTargets 48 | 49 | # Build examples 50 | 51 | Currently we use `rustc nightly` from most recent `nipxkgs master`! 52 | 53 | Example targets: 54 | 55 | git clone https://github.com/fractalide/nixcrates.git 56 | cd nixcrates 57 | nix-build default.nix -A nixcrates 58 | nix-build default.nix -A allTargets 59 | nix-build default.nix -A allCrates.rustache 60 | nix-build default.nix -A allCrates.serde 61 | 62 | **Warning**: there are horrible hack in this project just to make this minimal set of packages work. we were under a lot of time-pressure and low in funding. on judgement day, hopefully god didn't see it! 63 | 64 | # How it works 65 | Parse the JSON files of `github.com/rust-lang/crates.io-index` repository and translating them into nix files. Considering dependencies we are currently only supporting versioning via `~` and `^` as well as single versions. If anything else is used we switch to the newest version. In case of `^` and `~` we are using the highest allowed version. 66 | 67 | ## What do versions look like when created? 68 | `{package_name}` points on the newest version. 69 | `all__{package_name}` contains a set of all versions. 70 | 71 | There are also several shortcuts to address the newest subversion. For every missing semver version number simply the newest is used. 72 | For example `all__{package_name}.{package_name}_0_1` points the the version of `{package_name}` with `0.1.X` where `X` is the highest number found. 73 | 74 | ## What failes and why? 75 | 76 | ### Missing dependencies 77 | For some reason sometimes the crates.io json file is not listing all the dependencies. If this occurs the missing dependency has to be added by hand. However editing an autogenerated file is a pain. 78 | Therefore this can be done in the `nix-crates-index/default.nix` file. At the bottom of the file you can append additional dependencies. For this see the `rusqlite` crate example where `pkg-config` was added. 79 | 80 | ### Resolving dependencies 81 | Currently semver is resolved by choosing the highest allowed version from `rust-lang/cartes.io-index` repository. This works for targets called `allTargets`. 82 | However here is a constructed case that would fail: 83 | 84 | For example your project has 2 dependencies `{dep_a}` and `{dep_b}`. 85 | Lets assume: 86 | 87 | * `{dep_a}` depends on `{dep_c}` with 0.1.1 <= version <= 0.2.0 88 | * `{dep_b}` depends on `{dep_c}` with 0.0.1 <= version <= 0.1.2 89 | 90 | Now our repo would compile `dep_a` with `dep_c_0_2_0` and `dep_b` with `dep_c_0_1_2`. This is a problem as soon as `{dep_a}` as well as `{dep_b}` are exposing types from `{dep_c}` in their interfaces. 91 | 92 | ### Not supported stuff... yet please do help out with this 93 | 94 | #### Bundled C-code 95 | 96 | The `flate2-example` uses `miniz-sys` which uses `bundled c code` that is something we don't support yet. To see the error: 97 | 98 | nix-build -A allCrates.miniz-sys 99 | 100 | #### Override x_crate with a local x_crate, this helps develop locally 101 | #### Xml-rs != xml, crate name and extern names don't match, a mapping file needs to be passed in. 102 | #### What about build.rs files? 103 | 104 | #### Tests 105 | 106 | Crates come with `tests` but we didn't have time to implement even though we would have loved to do that. Building `crates` with `tests` requires `dev-dependencies` to be around. We currently just remove them because they caused a lot `cyclic dependencies` which `Nix` (and even `cargo`) can't handle. 107 | 108 | ### Dependencies 109 | 110 | Say a crate you want does not build since a dependency is not set correctly, then you can use `lib.recursiveUpdate` in `nix-crates-index/default.nix` to change/extend them. This holds also true for `pkgs` from nixpkgs! 111 | -------------------------------------------------------------------------------- /default.nix: -------------------------------------------------------------------------------- 1 | { 2 | pkgs ? ( 3 | let 4 | pkgs = import ; 5 | pkgs_ = (pkgs {}); 6 | rustOverlay = (pkgs_.fetchFromGitHub { 7 | owner = "mozilla"; 8 | repo = "nixpkgs-mozilla"; 9 | rev = "4779fb7776c3d38d78b5ebcee62165e6d1350f74"; 10 | sha256 = "04q6pwlz82qsm81pp7kk7i6ngrslq193v5wchdsrdifbn8cdqgbs"; 11 | }); 12 | in (pkgs { 13 | overlays = [ 14 | (import (builtins.toPath "${rustOverlay}/rust-overlay.nix")) 15 | (self: super: { 16 | rust = { 17 | rustc = super.rustChannels.nightly.rust; 18 | cargo = super.rustChannels.nightly.cargo; 19 | }; 20 | rustPlatform = super.recurseIntoAttrs (super.makeRustPlatform { 21 | rustc = super.rustChannels.nightly.rust; 22 | cargo = super.rustChannels.nightly.cargo; 23 | }); 24 | }) 25 | ]; 26 | })) 27 | }: 28 | with pkgs; 29 | 30 | with stdenv.lib; 31 | 32 | let 33 | allCrates = recurseIntoAttrs (callPackage ../nix-crates-index { }); 34 | normalizeName = builtins.replaceStrings [ "-"] ["_"]; 35 | depsStringCalc = pkgs.lib.fold ( dep: str: "${str} --extern ${normalizeName dep.name}=${dep}/lib${normalizeName dep.name}.rlib") ""; 36 | cratesDeps = pkgs.lib.fold ( recursiveDeps : newCratesDeps: newCratesDeps ++ recursiveDeps.cratesDeps ); 37 | # symlinkCalc creates a mylibs folder and symlinks all the buildInputs's libraries from there for rustc to link them into the final binary 38 | symlinkCalc = pkgs.lib.fold ( dep: str: "${str} ln -fs ${dep}/lib${normalizeName dep.name}.rlib mylibs/ \n") "mkdir mylibs\n "; 39 | rustNightly = rust.rustc; 40 | in 41 | 42 | rec { 43 | nixcrates = stdenv.mkDerivation rec { 44 | name = "nixcrates"; 45 | src = ./src; 46 | 47 | deps = [ allCrates.walkdir allCrates.rustc-serialize allCrates.rustache ]; 48 | crates = depsStringCalc deps; 49 | crateDeps = cratesDeps [] deps; 50 | buildInputs = with allCrates; crateDeps ++ deps; 51 | buildPhase = '' 52 | ${symlinkCalc buildInputs} 53 | # du -a 54 | ${rustNightly}/bin/rustc $src/main.rs --crate-type "bin" --emit=dep-info,link --crate-name nixcrates -L dependency=mylibs ${depsStringCalc deps} 55 | ''; 56 | installPhase = '' 57 | mkdir -p $out/bin 58 | cp nixcrates $out/bin 59 | ''; 60 | }; 61 | 62 | getopts-example = stdenv.mkDerivation rec { 63 | name = "getopts-example"; 64 | src = ./example/src; 65 | 66 | depsString = depsStringCalc buildInputs; 67 | buildInputs = with allCrates; [ getopts ]; 68 | 69 | buildPhase = '' 70 | ${rustNightly}/bin/rustc $src/main.rs ${depsString} 71 | ./main 72 | 73 | ''; 74 | installPhase='' 75 | mkdir $out 76 | ''; 77 | }; 78 | 79 | # flate2 example uses native c code (not using nipxkgs's packages but brings its own bundled c-code instead) 80 | # FIXME still fails to build 81 | flate2-example = stdenv.mkDerivation rec { 82 | name = "flate2-example"; 83 | src = ./example/src2; 84 | depsString = depsStringCalc buildInputs; 85 | buildInputs = with allCrates; [ flate2 libc miniz-sys gcc ]; 86 | 87 | buildPhase = '' 88 | ${symlinkCalc buildInputs} 89 | # du -a mylibs 90 | # ls -lathr mylibs 91 | # echo ${depsString} 92 | # [pid 14162] execve("/nix/store/fff3jbf9vbqhmf6qjrmzhliq516x7yrf-rustc-1.11.0/bin/rustc", ["rustc", "src/main.rs", "--crate-name", "hello_flate2", "--crate-type", "bin", "-g", "--out-dir", "/home/joachim/Desktop/projects/fractalide/fetchUrl/hello_flate2/target/debug", "--emit=dep-info,link", "-L", "dependency=/home/joachim/Desktop/projects/fractalide/fetchUrl/hello_flate2/target/debug", "-L", "dependency=/home/joachim/Desktop/projects/fractalide/fetchUrl/hello_flate2/target/debug/deps", "--extern", "flate2=/home/joachim/Desktop/projects/fractalide/fetchUrl/hello_flate2/target/debug/deps/libflate2-d719035eaa7c6a88.rlib", "-L", "native=/home/joachim/Desktop/projects/fractalide/fetchUrl/hello_flate2/target/debug/build/miniz-sys-60c8d67696f63a43/out"], [/* 105 vars */]) = 0 93 | 94 | ${rustNightly}/bin/rustc $src/main.rs --crate-type "bin" --emit=dep-info,link --crate-name main -L dependency=mylibs ${depsString} -L native= #flate2=${allCrates.flate2_0_2_14}/libflate2.rlib 95 | ./main 96 | exit 1 97 | ''; 98 | }; 99 | 100 | tar-example = stdenv.mkDerivation rec { 101 | name = "tar-example"; 102 | src = ./example/src3; 103 | buildInputs = with allCrates; [ tar filetime libc xattr ]; 104 | buildPhase = '' 105 | ${symlinkCalc buildInputs} 106 | 107 | echo "hu" > file1.txt 108 | echo "bar" > file2.txt 109 | echo "batz" > file3.txt 110 | 111 | ${rustNightly}/bin/rustc $src/main.rs --crate-type "bin" --emit=dep-info,link --crate-name main -L dependency=mylibs --extern tar=${allCrates.tar}/libtar.rlib 112 | # du -a 113 | # /run/current-system/sw/bin/ldd ./main 114 | ./main 115 | # du -a 116 | if [ -f foo.tar ]; then 117 | echo -e "---------\nSUCCESS: tar-example was executed successfully! \n--------" 118 | else 119 | echo "FAIL: not working!" 120 | fi 121 | ''; 122 | installPhase='' 123 | mkdir $out 124 | ''; 125 | }; 126 | # with this you can do: nix-build -A allCrates.getopts to compile single dependencies 127 | inherit allCrates; 128 | 129 | allTargets = stdenv.mkDerivation rec { 130 | name="allTargets"; 131 | version="1"; 132 | buildInputs = with allCrates; [ nixcrates nom capnp regex json tiny_http tar-example getopts-example rustfbp rusqlite ]; 133 | src = ./.; 134 | buildPhase='' 135 | ''; 136 | installPhase='' 137 | mkdir $out 138 | ''; 139 | }; 140 | E0557 = stdenv.mkDerivation rec { # https://doc.rust-lang.org/error-index.html#E0557 141 | name="allTargets"; 142 | version="1"; 143 | buildInputs = with allCrates; [ 144 | soa stack_dst 145 | ]; 146 | src = ./.; 147 | buildPhase='' 148 | ''; 149 | installPhase='' 150 | mkdir $out 151 | ''; 152 | }; 153 | E0519 = stdenv.mkDerivation rec { # https://doc.rust-lang.org/error-index.html#E0519 154 | name="allTargets"; 155 | version="1"; 156 | buildInputs = with allCrates; [ 157 | juju 158 | ]; 159 | src = ./.; 160 | buildPhase='' 161 | ''; 162 | installPhase='' 163 | mkdir $out 164 | ''; 165 | }; 166 | E0518 = stdenv.mkDerivation rec { # https://doc.rust-lang.org/error-index.html#E0518 167 | name="allTargets"; 168 | version="1"; 169 | buildInputs = with allCrates; [ 170 | unicode_names ao 171 | ]; 172 | src = ./.; 173 | buildPhase='' 174 | ''; 175 | installPhase='' 176 | mkdir $out 177 | ''; 178 | }; 179 | E0512 = stdenv.mkDerivation rec { # https://doc.rust-lang.org/error-index.html#E0512 180 | name="allTargets"; 181 | version="1"; 182 | buildInputs = with allCrates; [ 183 | all__crossbeam.crossbeam_0_1_6 # dependency of simple_parallel 184 | ]; 185 | src = ./.; 186 | buildPhase='' 187 | ''; 188 | installPhase='' 189 | mkdir $out 190 | ''; 191 | }; 192 | E0463 = stdenv.mkDerivation rec { # https://doc.rust-lang.org/error-index.html#E0463 193 | name="allTargets"; 194 | version="1"; 195 | buildInputs = with allCrates; [ kernel32-sys gdi32-sys advapi32-sys user32-sys 196 | ws2_32-sys gl_generator wayland-scanner # very important libs 197 | dbghelp-sys dwmapi-sys xmltree tendril piston-viewport vecmath rpassword jsonrpc-core ethabi ktmw32-sys 198 | crypt32-sys psapi-sys secur32-sys native-tls ole32-sys flate2 rust_sodium-sys userenv-sys d3d11-sys winmm-sys 199 | geojson app_dirs dwrite-sys d3dcompiler-sys uuid-sys xinput-sys mpr-sys r2d2_sqlite plist ssdp alpm 200 | comctl32-sys dxgi-sys oleaut32-sys comdlg32-sys json_io rusoto_codegen simple_gaussian aligned_alloc 201 | netapi32-sys serde-hjson named_pipe hid-sys rustlex_codegen gtk-rs-lgpl-docs d3d12-sys 202 | all__rusqlite.rusqlite_0_6_0 # dependency of ostn02_phf lonlat_bng 203 | all__rusqlite.rusqlite_0_7_3 # dependency of nickel_sqlite 204 | runtimeobject-sys rquery native-tls probor os_pipe piston-texture codespawn millefeuille 205 | serde_codegen xmlJSON clippy 206 | ]; 207 | src = ./.; 208 | buildPhase='' 209 | ''; 210 | installPhase='' 211 | mkdir $out 212 | ''; 213 | }; 214 | E0460 = stdenv.mkDerivation rec { # https://doc.rust-lang.org/error-index.html#E0460 215 | name="allTargets"; 216 | version="1"; 217 | buildInputs = with allCrates; [ 218 | regex # important to fix 219 | iron # important to fix 220 | gfx_core nickel slog-term lalrpop-snap hyper_serde 221 | postgres_array capnp-rpc rs-es ignore rustful inth-oauth2 elastic_hyper 222 | rocket 223 | all__regex_dfa.regex_dfa_0_4_0 # dependency of cfg-regex 224 | vulkano ease theban_db_server phant linea modbus googl 225 | ]; 226 | src = ./.; 227 | buildPhase='' 228 | ''; 229 | installPhase='' 230 | mkdir $out 231 | ''; 232 | }; 233 | E0457 = stdenv.mkDerivation rec { # https://doc.rust-lang.org/error-index.html#E0457 234 | name="allTargets"; 235 | version="1"; 236 | buildInputs = with allCrates; [ easy-plugin-plugins oil_shared worldgen 237 | punkt 238 | 239 | ]; 240 | src = ./.; 241 | buildPhase='' 242 | ''; 243 | installPhase='' 244 | mkdir $out 245 | ''; 246 | }; 247 | E0455 = stdenv.mkDerivation rec { # https://doc.rust-lang.org/error-index.html#E0455 248 | name="allTargets"; 249 | version="1"; 250 | buildInputs = with allCrates; [ core-graphics objc-foundation fsevent-sys coreaudio-sys 251 | 252 | ]; 253 | src = ./.; 254 | buildPhase='' 255 | ''; 256 | installPhase='' 257 | mkdir $out 258 | ''; 259 | }; 260 | E0433 = stdenv.mkDerivation rec { # https://doc.rust-lang.org/error-index.html#E0433 261 | name="allTargets"; 262 | version="1"; 263 | buildInputs = with allCrates; [ html5ever_macros 264 | all__syntex_syntax.syntex_syntax_0_24_0 # dependency of rusty-cheddar 265 | collenchyma-blas ion intrusive-containers intovec trie hotspot 266 | 267 | ]; 268 | src = ./.; 269 | buildPhase='' 270 | ''; 271 | installPhase='' 272 | mkdir $out 273 | ''; 274 | }; 275 | E0432 = stdenv.mkDerivation rec { # https://doc.rust-lang.org/error-index.html#E0432 276 | name="allTargets"; 277 | version="1"; 278 | buildInputs = with allCrates; [ tokio-core pnacl-build-helper heapsize_plugin serde_yaml ipc-channel string_cache_plugin 279 | all__quasi.quasi_0_11_0 futures-cpupool serde_item rust-base58 rblas mod_path bio phf_mac simplelog rustfft 280 | fractal-dto shoggoth_macros 281 | all__image.image_0_6_1 #dependency of glyph_packer 282 | external_mixin_umbrella connected_socket beanstalkd error_def 283 | all__qcollect-traits.qcollect-traits_0_4_1 #dependency of qindex_multi 284 | phloem mudpie uil_shared yaml gc_plugin rosalind unreliable-message 285 | all__bincode.bincode_0_3_0 #dependency of font-atlas-image 286 | all__leveldb.leveldb_0_6_1 #dependency of drossel-journal 287 | duktape_sys gfx_macros zip-longest 288 | all__image.image_0_6_1 #dependency of jamkit 289 | lazy resources_package 290 | all__fern.fern_0_1_12 #dependency of fern_macros 291 | maybe_utf8 power-assert dsl_macros compile_msg nock currency trace uil_parsers screenshot 292 | soundchange bytekey forkjoin kwarg_macros brainfuck_macros raw webplatform_concat_bytes 293 | plugger-macros algs4 rust-netmap sdr draw_state fractran_macros crdt cli storage leveldb-sys 294 | static_assert parse-generics-poc sfunc serial-win export_cstr membuf sha cef-sys hyperdex 295 | unify fourcc 296 | all__image.image_0_7_2 # dependency of cuticula 297 | 298 | ]; 299 | src = ./.; 300 | buildPhase='' 301 | ''; 302 | installPhase='' 303 | mkdir $out 304 | ''; 305 | }; 306 | E0425 = stdenv.mkDerivation rec { # https://doc.rust-lang.org/error-index.html#E0425 307 | name="allTargets"; 308 | version="1"; 309 | buildInputs = with allCrates; [ 310 | env_logger # critical library 311 | serde_codegen_internals log4rs post-expansion fern syslog 312 | nat_traversal #caused by no lib.rs file 313 | simple_logger security-framework json_macros rand_macros nanomsg libsodium-sys 314 | spaceapi libmultilog rustspec_assertions libimagstore stderrlog libimagstore kernlog 315 | postgres-derive-codegen ocl-core mowl geoip diesel_codegen_syntex 316 | confsolve replace-map 317 | 318 | ]; 319 | src = ./.; 320 | buildPhase='' 321 | ''; 322 | installPhase='' 323 | mkdir $out 324 | ''; 325 | }; 326 | E0412 = stdenv.mkDerivation rec { # https://doc.rust-lang.org/error-index.html#E0412 327 | name="allTargets"; 328 | version="1"; 329 | buildInputs = with allCrates; [ aster quasi clippy_lints easy-plugin-parsers svd 330 | all__blas.blas_0_9_1 #dependency for numeric 331 | cursive ber bitfield bson-rs netio hyphenation_commons redis 332 | ]; 333 | src = ./.; 334 | buildPhase='' 335 | ''; 336 | installPhase='' 337 | mkdir $out 338 | ''; 339 | }; 340 | E0405 = stdenv.mkDerivation rec { # https://doc.rust-lang.org/error-index.html#E0405 341 | name="allTargets"; 342 | version="1"; 343 | buildInputs = with allCrates; [ quack bits ]; 344 | src = ./.; 345 | buildPhase='' 346 | ''; 347 | installPhase='' 348 | mkdir $out 349 | ''; 350 | }; 351 | E0369 = stdenv.mkDerivation rec { # https://doc.rust-lang.org/error-index.html#E0369 352 | name="allTargets"; 353 | version="1"; 354 | buildInputs = with allCrates; [ gazetta-render-ext gazetta-render-ext ]; 355 | src = ./.; 356 | buildPhase='' 357 | ''; 358 | installPhase='' 359 | mkdir $out 360 | ''; 361 | }; 362 | E0308 = stdenv.mkDerivation rec { # https://doc.rust-lang.org/error-index.html#E0308 363 | name="allTargets"; 364 | version="1"; 365 | buildInputs = with allCrates; [ eventfd ]; 366 | src = ./.; 367 | buildPhase='' 368 | ''; 369 | installPhase='' 370 | mkdir $out 371 | ''; 372 | }; 373 | E0282 = stdenv.mkDerivation rec { # https://doc.rust-lang.org/error-index.html#E0282 374 | name="allTargets"; 375 | version="1"; 376 | buildInputs = with allCrates; [ ears ]; 377 | src = ./.; 378 | buildPhase='' 379 | ''; 380 | installPhase='' 381 | mkdir $out 382 | ''; 383 | }; 384 | E0271 = stdenv.mkDerivation rec { # https://doc.rust-lang.org/error-index.html#E0271 385 | name="allTargets"; 386 | version="1"; 387 | buildInputs = with allCrates; [ qcollect-traits ]; 388 | src = ./.; 389 | buildPhase='' 390 | ''; 391 | installPhase='' 392 | mkdir $out 393 | ''; 394 | }; 395 | E0259 = stdenv.mkDerivation rec { # https://doc.rust-lang.org/error-index.html#E0259 396 | name="allTargets"; 397 | version="1"; 398 | buildInputs = with allCrates; [ quickersort ]; 399 | src = ./.; 400 | buildPhase='' 401 | ''; 402 | installPhase='' 403 | mkdir $out 404 | ''; 405 | }; 406 | E0244 = stdenv.mkDerivation rec { # https://doc.rust-lang.org/error-index.html#E0244 407 | name="allTargets"; 408 | version="1"; 409 | buildInputs = with allCrates; [ ncollide_entities ]; 410 | src = ./.; 411 | buildPhase='' 412 | ''; 413 | installPhase='' 414 | mkdir $out 415 | ''; 416 | }; 417 | E0277 = stdenv.mkDerivation rec { # https://doc.rust-lang.org/error-index.html#E0277 418 | name="allTargets"; 419 | version="1"; 420 | buildInputs = with allCrates; [ seax_svm temperature mm_image fiz-math 421 | mm_video acacia cortex pool 422 | ]; 423 | src = ./.; 424 | buildPhase='' 425 | ''; 426 | installPhase='' 427 | mkdir $out 428 | ''; 429 | }; 430 | E0112 = stdenv.mkDerivation rec { # https://doc.rust-lang.org/error-index.html#E0112 431 | name="allTargets"; 432 | version="1"; 433 | buildInputs = with allCrates; [ ioc ]; 434 | src = ./.; 435 | buildPhase='' 436 | ''; 437 | installPhase='' 438 | mkdir $out 439 | ''; 440 | }; 441 | E0107 = stdenv.mkDerivation rec { # https://doc.rust-lang.org/error-index.html#E0107 442 | name="allTargets"; 443 | version="1"; 444 | buildInputs = with allCrates; [ syntaxext_lint ]; 445 | src = ./.; 446 | buildPhase='' 447 | ''; 448 | installPhase='' 449 | mkdir $out 450 | ''; 451 | }; 452 | E0061 = stdenv.mkDerivation rec { # https://doc.rust-lang.org/error-index.html#E0061 453 | name="allTargets"; 454 | version="1"; 455 | buildInputs = with allCrates; [ linenoise-sys ]; 456 | src = ./.; 457 | buildPhase='' 458 | ''; 459 | installPhase='' 460 | mkdir $out 461 | ''; 462 | }; 463 | E0050 = stdenv.mkDerivation rec { # https://doc.rust-lang.org/error-index.html#E0244 464 | name="allTargets"; 465 | version="1"; 466 | buildInputs = with allCrates; [ ncollide_geometry]; 467 | src = ./.; 468 | buildPhase='' 469 | ''; 470 | installPhase='' 471 | mkdir $out 472 | ''; 473 | }; 474 | E0046 = stdenv.mkDerivation rec { # https://doc.rust-lang.org/error-index.html#E0246 475 | name="allTargets"; 476 | version="1"; 477 | buildInputs = with allCrates; [ extprim ]; 478 | src = ./.; 479 | buildPhase='' 480 | ''; 481 | installPhase='' 482 | mkdir $out 483 | ''; 484 | }; 485 | issue27783 = stdenv.mkDerivation rec { # https://github.com/rust-lang/rust/issues/27783 486 | name="allTargets"; 487 | version="1"; 488 | buildInputs = with allCrates; [ term_size gl_common clock_ticks ]; 489 | src = ./.; 490 | buildPhase='' 491 | ''; 492 | installPhase='' 493 | mkdir $out 494 | ''; 495 | }; 496 | no_such_file_or_directory = stdenv.mkDerivation rec { 497 | name="allTargets"; 498 | version="1"; 499 | buildInputs = with allCrates; [ mime_guess llvm-sys ffmpeg-sys hotspot rl-sys 500 | all__typenum.typenum_1_2_0 # dependency of static-buffer 501 | all__typenum.typenum_1_1_0 # dependency of dimensioned 502 | libtar-sys tar-sys mcpat-sys repl cargo-clippy crc24 octavo-digest 503 | pdf mavlink ntru 504 | ]; 505 | src = ./.; 506 | buildPhase='' 507 | ''; 508 | installPhase='' 509 | mkdir $out 510 | ''; 511 | }; 512 | not_found_librs = stdenv.mkDerivation rec { # uncomment ln 116 of nix-crates-index/default.nix then test these 513 | name="allTargets"; 514 | version="1"; 515 | buildInputs = with allCrates; [ c_vec compiletest_rs untrusted 516 | encoding_index_tests # critical library... insanely critical 517 | lodepng 518 | protobuf xdg # patch sent to protobuf, whitequark changed xdg 519 | all__libc.libc_0_1_12 # dependency of allegro_util allegro_font-sys get_if_addrs allegro bson harfbuzz ctest hprof 520 | # sound_stream minifb docker allegro_audio-sys request mongodb gpgme-sys allegro_font 521 | all__sdl2.sdl2_0_27_3 # dependency of sdl2 orbclient 522 | all__sdl2.sdl2_0_25_0 # dependency of sdl2_ttf sdl2_mixer 523 | all__sdl2.sdl2_0_15_0 # dependency of sdl2_image 524 | rustsym gtypes rust-libcore xsv cargo-check pretty gtypes xargo base32 rusty-tags 525 | sysinfo maxminddb cargo-outdated jit_macros bencode partial bloomfilter gcollections 526 | cereal_macros cargo-graph nickel_macros c_str anybar_rs cargo-count scgi reminisce 527 | cargo-local-pkgs cow 528 | all__cargo-multi.cargo-multi_0_5_0 # dependency of cargo-multi 529 | cargo-do hyperloglog ncurses vobject sufdb dining_philosophers cargo-apk 530 | wheel_timer coinaddress rustbook cargo-expand pwrs 531 | ]; 532 | src = ./.; 533 | buildPhase='' 534 | ''; 535 | installPhase='' 536 | mkdir $out 537 | ''; 538 | }; 539 | panicOnNotPresent = stdenv.mkDerivation rec { 540 | name="allTargets"; 541 | version="1"; 542 | buildInputs = with allCrates; [ openssl-sys html5ever-atoms 543 | libz-sys # critical library 544 | harfbuzz-sys ring # (ring depends on "untrusted" that seems to be why it fails) 545 | termbox-sys openblas-provider openblas-src rustbox vorbis-encoder expectest rust-crypto backtrace-sys 546 | all__lmdb-sys.lmdb-sys_0_2_1 lmdb-sys # dependency of lmdb 547 | libgpg-error-sys netlib-provider assert_cli 548 | libsystemd-sys systemd # also in EnvNotSet due to error message 549 | liquid debugtrace tcod-sys carboxyl tcod snappy-sys xcb chomp rust-htslib 550 | hdf5-sys i2cdev cld2-sys cld2 cronparse gmp-sys zlib-src-sys nix-test freeimage-sys neovim-rs parsell 551 | parasail-sys arrayfire po netlib-blas-provider hdf5-sys nanny-sys skia-sys xcb 552 | 553 | 554 | ]; 555 | src = ./.; 556 | buildPhase='' 557 | ''; 558 | installPhase='' 559 | mkdir $out 560 | ''; 561 | }; 562 | OSDepNotFoundConfig = stdenv.mkDerivation rec { 563 | name="allTargets"; 564 | version="1"; 565 | buildInputs = with allCrates; [ glib-sys dbus cairo-sys-rs clang-sys portaudio 566 | alsa-sys fuse libusb-sys libarchive3-sys 567 | zmq-sys 568 | libudev-sys pico-sys wren-sys notify-rust c-ares-sys rust-lzma ruby-sys 569 | netlib-src neon-sys gexiv2-sys ruster_unsafe python3-sys python27-sys 570 | mcpat-sys erlang_nif-sys dns-sd 571 | all__bindgen.bindgen_0_16_0 # dependency of bindgen_plugin 572 | fontconfig-sys gexiv2-sys rustler opusfile-sys 573 | libfa-sys gphoto2-sys libraw-sys silverknife-fontconfig-sys pocketsphinx-sys 574 | opencv wiringpi libudt4-sys blip_buf-sys qmlrs ejdb-sys gnutls-sys tinysnark 575 | va_list-test 576 | 577 | ]; 578 | src = ./.; 579 | buildPhase='' 580 | ''; 581 | installPhase='' 582 | mkdir $out 583 | ''; 584 | }; 585 | EnvVarNotSet = stdenv.mkDerivation rec { 586 | name="allTargets"; 587 | version="1"; 588 | buildInputs = with allCrates; [ x11 miniz-sys bzip2-sys expat-sys servo-freetype-sys glfw-sys hbs-builder context 589 | heartbeats-simple-sys hoedown liblmdb-sys lua52-sys brotli-sys linenoise-rust brotli2 hlua 590 | libsystemd-sys systemd # also in NotPresent due to error message 591 | rocksdb assimp-sys secp256k1 onig_sys hdrhistogram stemmer sys-info lzma-sys sass-sys 592 | http-muncher imgui-sys pdcurses-sys decimal file-lock afl-plugin objc_exception magic 593 | td_clua chipmunk-sys mrusty objc_test_utils nanovg afl-sys blip_buf-sys chip8_vm 594 | td_clua libudt4-sys chemfiles-sys chamkho unqlite-sys tweetnacl-sys xxhash-sys 595 | libxm oxipng ntrumls va_list-helper 596 | ]; 597 | src = ./.; 598 | buildPhase='' 599 | ''; 600 | installPhase='' 601 | mkdir $out 602 | ''; 603 | }; 604 | UnstableLibraryFeature = stdenv.mkDerivation rec { 605 | name="allTargets"; 606 | version="1"; 607 | buildInputs = with allCrates; [ mmap sorted-collections fn_box ]; 608 | src = ./.; 609 | buildPhase='' 610 | ''; 611 | installPhase='' 612 | mkdir $out 613 | ''; 614 | }; 615 | MismatchSHA256 = stdenv.mkDerivation rec { 616 | name="allTargets"; 617 | version="1"; 618 | buildInputs = with allCrates; [ multipart pbr lz4-sys uchardet-sys slog-serde 619 | uchardet google-gmail1 water lcov-parser google-groupsmigration1 google-calendar3 google-identitytoolkit3 620 | google-storage1 google-cloudmonitoring2_beta2 google-youtubeanalytics1 google-plusdomains1 621 | google-groupssettings1 google-spectrum1_explorer google-youtube3 google-mirror1 622 | google-prediction1d6 google-translate2 google-pagespeedonline2 google-replicapoolupdater1_beta1 google-sqladmin1_beta4 623 | google-doubleclicksearch2 google-siteverification1 ffmpeg google-appstate1 google-taskqueue1_beta2 624 | google-admin1_reports google-manager1_beta2 google-bigquery2 google-licensing1 google-qpxexpress1 625 | google-gamesmanagement1_management google-tasks1 google-admin1_directory google-tagmanager1 google-drive2 google-analytics3 626 | google-adsense1d4 google-androidenterprise1 google-customsearch1 google-androidpublisher2 google-webmasters3 627 | google-adsensehost4d1 google-urlshortener1 google-fitness1 google-games1 google-adexchangeseller2 google-content2 628 | google-webfonts1 google-adexchangebuyer1d3 google-appsactivity1 google-gamesconfiguration1_configuration 629 | google-resourceviews1_beta2 google-coordinate1 google-replicapool1_beta2 google-autoscaler1_beta2 630 | google-reseller1_sandbox google-blogger3 google-fusiontables2 google-plus1 google-civicinfo2 631 | google-oauth2_v2 google-doubleclickbidmanager1 google-gan1_beta1 google-pubsub1_beta2 google-freebase1 632 | google-cloudlatencytest2 google-compute1 google-discovery1 google-datastore1_beta2 google-dns1 633 | google-dfareporting2d1 google-logging1_beta3 dns google-genomics1 google-cloudresourcemanager1_beta1 634 | google-deploymentmanager2_beta2 http ql2 fastcgi 635 | ]; 636 | src = ./.; 637 | buildPhase='' 638 | ''; 639 | installPhase='' 640 | mkdir $out 641 | ''; 642 | }; 643 | not_eq = stdenv.mkDerivation rec { 644 | name="allTargets"; 645 | version="1"; 646 | buildInputs = with allCrates; [ RustyXML glutin_core_foundation glutin_cocoa rustc-test glutin_core_graphics 647 | rust-gmp gstreamer rust-sqlite basic-hll rust-tcl ]; 648 | src = ./.; 649 | buildPhase='' 650 | ''; 651 | installPhase='' 652 | mkdir $out 653 | ''; 654 | }; 655 | retired_experimental_deprecated = stdenv.mkDerivation rec { 656 | name="allTargets"; 657 | version="1"; 658 | buildInputs = with allCrates; [ tenacious scm utils dsound-sys usp10-sys vssapi-sys winspool-sys winhttp-sys 659 | httpapi-sys bcrypt-sys d2d1-sys credui-sys setupapi-sys winscard-sys wevtapi-sys odbc32-sys shlwapi-sys 660 | posix-ipc fromxml utmp pdh-sys xdg-rs winusb-sys bitflags 661 | ]; 662 | src = ./.; 663 | buildPhase='' 664 | ''; 665 | installPhase='' 666 | mkdir $out 667 | ''; 668 | }; 669 | WTF = stdenv.mkDerivation rec { 670 | name="allTargets"; 671 | version="1"; 672 | buildInputs = with allCrates; [ valico # rustless uses it 673 | ncollide_geometry diesel_codegen 674 | all__url.url_0_5_10 #dependency of jsonrpc-http-server and many many others 675 | buildable doapi ramp 676 | 677 | ]; 678 | src = ./.; 679 | buildPhase='' 680 | ''; 681 | installPhase='' 682 | mkdir $out 683 | ''; 684 | }; 685 | shebangs = stdenv.mkDerivation rec { 686 | name="allTargets"; 687 | version="1"; 688 | buildInputs = with allCrates; [ stb_image superlu-sys rocksdb-sys freetype 689 | superlu threed-ice-sys postgres_macros sel4-sys imagequant sel4-sys 690 | ]; 691 | src = ./.; 692 | buildPhase='' 693 | ''; 694 | installPhase='' 695 | mkdir $out 696 | ''; 697 | }; 698 | panicOnNoneOption = stdenv.mkDerivation rec { 699 | name="allTargets"; 700 | version="1"; 701 | buildInputs = with allCrates; [ sodium-sys barnacl_sys lua barnacl_sys 702 | nanny-sys ]; 703 | src = ./.; 704 | buildPhase='' 705 | ''; 706 | installPhase='' 707 | mkdir $out 708 | ''; 709 | }; 710 | noMethodNamed = stdenv.mkDerivation rec { 711 | name="allTargets"; 712 | version="1"; 713 | buildInputs = with allCrates; [ heapsize_derive synstructure conduit-cookie 714 | sha1-hasher discotech_zookeeper netopt changecase asexp cowrc rctree 715 | 716 | ]; 717 | src = ./.; 718 | buildPhase='' 719 | ''; 720 | installPhase='' 721 | mkdir $out 722 | ''; 723 | }; 724 | syntaxError = stdenv.mkDerivation rec { 725 | name="allTargets"; 726 | version="1"; 727 | buildInputs = with allCrates; [ xxhash free_macros phantom epsilonz_algebra metafactory 728 | grabbag_macros interval monad_macros expression event simple-signal crc32 tojson_macros 729 | gluster fftw3-sys 730 | all__rustc-serialize.rustc-serialize_0_2_15 # dependency of cson 731 | i3 mdbm-sys kissfft hexfloat core-nightly cppStream grabbag_macros 732 | incrust num link-config metafactory derive-new doc_file openssl2-sys 733 | ]; 734 | src = ./.; 735 | buildPhase='' 736 | ''; 737 | installPhase='' 738 | mkdir $out 739 | ''; 740 | }; 741 | shouldBeRunWithCargo = stdenv.mkDerivation rec { 742 | name="allTargets"; 743 | version="1"; 744 | buildInputs = with allCrates; [ libjit-sys ]; 745 | src = ./.; 746 | buildPhase='' 747 | ''; 748 | installPhase='' 749 | mkdir $out 750 | ''; 751 | }; 752 | unknownCompilerVersion = stdenv.mkDerivation rec { 753 | name="allTargets"; 754 | version="1"; 755 | buildInputs = with allCrates; [ core_collections ]; 756 | src = ./.; 757 | buildPhase='' 758 | ''; 759 | installPhase='' 760 | mkdir $out 761 | ''; 762 | }; 763 | linkingError = stdenv.mkDerivation rec { 764 | name="allTargets"; 765 | version="1"; 766 | buildInputs = with allCrates; [ libhdf5-sys ]; 767 | src = ./.; 768 | buildPhase='' 769 | ''; 770 | installPhase='' 771 | mkdir $out 772 | ''; 773 | }; 774 | missingNixDep = stdenv.mkDerivation rec { 775 | name="allTargets"; 776 | version="1"; 777 | buildInputs = with allCrates; [ slog-json slog-envlogger ]; 778 | src = ./.; 779 | buildPhase='' 780 | ''; 781 | installPhase='' 782 | mkdir $out 783 | ''; 784 | }; 785 | mustHave = stdenv.mkDerivation rec { 786 | name="allTargets"; 787 | version="1"; 788 | buildInputs = with allCrates; [ github capnp-futures bio skeletal_animation tokio-http2 tokio-graphql nanomsg ]; 789 | src = ./.; 790 | buildPhase='' 791 | ''; 792 | installPhase='' 793 | mkdir $out 794 | ''; 795 | }; 796 | 797 | 798 | } 799 | -------------------------------------------------------------------------------- /example/src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate getopts; 2 | use getopts::Options; 3 | use std::env; 4 | 5 | fn do_work(inp: &str, out: Option) { 6 | println!("{}", inp); 7 | match out { 8 | Some(x) => println!("{}", x), 9 | None => println!("No Output"), 10 | } 11 | } 12 | 13 | fn print_usage(program: &str, opts: Options) { 14 | let brief = format!("Usage: {} FILE [options]", program); 15 | print!("{}", opts.usage(&brief)); 16 | } 17 | 18 | fn main() { 19 | let args: Vec = env::args().collect(); 20 | let program = args[0].clone(); 21 | 22 | let mut opts = Options::new(); 23 | opts.optopt("o", "", "set output file name", "NAME"); 24 | opts.optflag("h", "help", "print this help menu"); 25 | let matches = match opts.parse(&args[1..]) { 26 | Ok(m) => { m } 27 | Err(f) => { panic!(f.to_string()) } 28 | }; 29 | if matches.opt_present("h") { 30 | print_usage(&program, opts); 31 | return; 32 | } 33 | let output = matches.opt_str("o"); 34 | let input = if !matches.free.is_empty() { 35 | matches.free[0].clone() 36 | } else { 37 | print_usage(&program, opts); 38 | return; 39 | }; 40 | do_work(&input, output); 41 | } 42 | -------------------------------------------------------------------------------- /example/src2/main.rs: -------------------------------------------------------------------------------- 1 | extern crate flate2; 2 | 3 | use std::io::prelude::*; 4 | use flate2::Compression; 5 | use flate2::write::ZlibEncoder; 6 | 7 | fn main() { 8 | let mut e = ZlibEncoder::new(Vec::new(), Compression::Default); 9 | e.write(b"foo"); 10 | e.write(b"bar"); 11 | let compressed_bytes = e.finish(); 12 | } 13 | -------------------------------------------------------------------------------- /example/src3/main.rs: -------------------------------------------------------------------------------- 1 | extern crate tar; 2 | 3 | use std::io::prelude::*; 4 | use std::fs::File; 5 | use tar::Builder; 6 | 7 | fn main() { 8 | let file = File::create("foo.tar").unwrap(); 9 | let mut a = Builder::new(file); 10 | 11 | a.append_path("file1.txt").unwrap(); 12 | a.append_file("file2.txt", &mut File::open("file3.txt").unwrap()).unwrap(); 13 | } 14 | 15 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | extern crate rustache; 2 | use rustache::{HashBuilder, Render}; 3 | 4 | extern crate rustc_serialize; 5 | use rustc_serialize::{json , Decodable, Decoder}; 6 | 7 | extern crate walkdir; 8 | use walkdir::{DirEntry, WalkDir, WalkDirIterator}; 9 | 10 | use std::io::BufReader; 11 | use std::io::BufRead; 12 | use std::io::Cursor; 13 | use std::io::Write; 14 | 15 | use std::fs; 16 | use std::fs::File; 17 | 18 | use std::collections::BTreeMap; 19 | 20 | use std::env; 21 | 22 | 23 | #[derive(Clone)] 24 | struct Dep{ 25 | name: String, 26 | optional: bool, 27 | kind: String, 28 | req: String, 29 | target: String, 30 | } 31 | 32 | 33 | impl Decodable for Dep { 34 | fn decode(d: &mut D) -> Result { 35 | d.read_struct("Dep", 5, |d| { 36 | let name = try!(d.read_struct_field("name", 0, |d| { d.read_str() })); 37 | let optional = try!(d.read_struct_field("optional", 1, |d| { 38 | Ok( match d.read_bool(){ 39 | Ok(opt) => opt, 40 | Err(_) => false, 41 | })})); 42 | let kind = try!(d.read_struct_field("kind", 2, |d| { 43 | Ok( match d.read_str(){ 44 | Ok(opt) => opt, 45 | Err(_) => "".to_string(), 46 | }) })); 47 | 48 | let req = try!(d.read_struct_field("req", 3, |d| { d.read_str() })); 49 | 50 | let target = try!(d.read_struct_field("target", 4, |d| { 51 | Ok(match d.read_str() { 52 | Ok(opt) => opt, 53 | Err(_) => "".to_string(), 54 | })})); 55 | 56 | let ret = Dep{name: name, optional: optional, kind: kind, target: target, req: req }; 57 | return Ok(ret); 58 | }) 59 | } 60 | } 61 | 62 | #[derive(RustcDecodable, Clone)] 63 | struct MyCrate{ 64 | name: String, 65 | vers: String, 66 | deps: Vec, 67 | cksum: String, 68 | } 69 | 70 | fn is_hidden(entry: &DirEntry) -> bool { 71 | entry.file_name() 72 | .to_str() 73 | .map(|s| s.starts_with(".")) 74 | .unwrap_or(false) 75 | } 76 | 77 | //converts the version string into an array of u32s 78 | fn convert_version(version: &str) -> Vec { 79 | return version.split(&['.'][..]).map(|s| match s.parse::(){ 80 | Ok(x) => x, 81 | Err(_) => 0_u32, 82 | }).collect(); 83 | } 84 | 85 | //Parses one single crates.io file 86 | fn parseCrates(f: &File) -> BTreeMap,MyCrate>{ 87 | let mut all_versions = BTreeMap::new(); 88 | let mut reader = BufReader::new(f); 89 | //parse all crates 90 | for line in reader.lines(){ 91 | let l = line.unwrap(); 92 | 93 | let mut next_crate: MyCrate = match json::decode(&l){ 94 | Ok(x) => x, 95 | Err(err) => { println!("ERROR while parsing a crate: {}", err); continue} , 96 | }; 97 | 98 | // if next_crate.vers.contains("-"){ 99 | //skip beta versions 100 | // continue; 101 | // } 102 | 103 | //remove everything after an `+` since those vallues can be ignored for versioning 104 | //remove everything after an `-` those versions are unstable pre-release versions. 105 | //we allow them but only ceep the latest. 106 | let prep_for_split = next_crate.vers.clone(); 107 | let split: Vec<&str> = prep_for_split.split(&['+', '-'][..]).collect(); 108 | let v: &str = split[0]; 109 | next_crate.vers = v.to_string(); 110 | 111 | let version = convert_version(&next_crate.vers); 112 | //insert the latest version, discard the previous value (if there is one) 113 | all_versions.insert(version, next_crate); 114 | } 115 | return all_versions; 116 | } 117 | 118 | //convert a vector of deps into a string and resolve the given versions. 119 | fn create_dep_string(deps: &Vec) -> String{ 120 | let mut dep_str = "".to_string(); 121 | for d in deps { 122 | //FIXME this breaks things for windows ans macos 123 | if !d.optional && d.kind != "dev" && !d.target.contains("windows") && !d.target.contains("macos"){ 124 | if d.req.contains("<") || d.req.contains("=") || d.req.contains(">") || d.req.contains("*"){ 125 | //Cant resolve use newest version 126 | dep_str = dep_str + " " + &(d.name); 127 | continue; 128 | } 129 | let mut x: Vec<&str> = d.req.split(".").collect(); 130 | 131 | if x.len() > 3 { 132 | //Cant resolve use newest version 133 | dep_str = dep_str + " " + &(d.name); 134 | continue; 135 | } 136 | if d.req.starts_with("~") { 137 | if x.len() == 1 { 138 | dep_str = dep_str + " all__" + &(d.name) + "." + &(d.name) + "_" + x[0].trim_left_matches("~"); 139 | }else { 140 | dep_str = dep_str + " all__" + &(d.name) + "." + &(d.name) + "_" + x[0].trim_left_matches("~") + "_" + x[1]; 141 | } 142 | }else if d.req.starts_with("^") { 143 | dep_str = dep_str + " all__" + &(d.name) + "." + &(d.name) + "_" + x[0].trim_left_matches("^"); 144 | x.remove(0); 145 | for i in x { 146 | dep_str = dep_str + "_" + i; 147 | if i != "0" { 148 | break; 149 | } 150 | } 151 | 152 | }else { 153 | if x.len() > 3 { 154 | //Cant resolve use newest version 155 | dep_str = dep_str + " " + &(d.name); 156 | }else{ 157 | dep_str = dep_str + " all__" + &(d.name) + "." + &(d.name); 158 | for i in x { 159 | dep_str = dep_str + "_" + i; 160 | } 161 | } 162 | } 163 | } 164 | } 165 | return dep_str; 166 | } 167 | 168 | 169 | fn main() { 170 | //check arguments 171 | let args: Vec<_> = env::args().collect(); 172 | if args.len() < 3 { 173 | println!("The first argument should be the path of the crates.io-index"); 174 | println!("The second argument should be the path for the nixcrates index"); 175 | return; 176 | }else{ 177 | println!("Inputh path is {}", args[1]); 178 | println!("Output path is {}", args[2]); 179 | } 180 | 181 | let input = &args[1]; 182 | let output = &args[2]; 183 | 184 | //template for the nix file 185 | let template = r#" 186 | {{package_name}} = buildCratesLib { 187 | name = "{{name}}"; 188 | version = "{{vers}}"; 189 | hash = "{{cksum}}"; 190 | deps = with allCrates; [ {{deps}} ]; 191 | };"#; 192 | 193 | let packages_path = output.to_string() + "/generated-crates.nix"; 194 | let mut packages = File::create(packages_path).unwrap(); 195 | write!(packages, "#DON'T EDIT. AUTOGENERATED FILE"); 196 | write!(packages, "\n{{"); 197 | write!(packages, "\n allCrates = self: super: rec {{"); 198 | 199 | //traverse through the crates.io index 200 | for entry in WalkDir::new(input).into_iter().filter_entry(|e| !is_hidden(e)) { 201 | let entry = entry.unwrap(); 202 | if entry.file_type().is_dir(){ 203 | //create the equivalent folder for the nix index 204 | let new_path = "".to_string() + output + &(entry.path().to_str().unwrap().trim_left_matches(input)); 205 | fs::create_dir_all(new_path); 206 | }else if entry.file_type().is_file(){ 207 | //create the equivalent nix file for the nix index 208 | 209 | //check if the file is the config.json 210 | if entry.path().to_str().unwrap().ends_with("config.json") || 211 | entry.path().to_str().unwrap().contains(".git") || 212 | entry.path().to_str().unwrap().ends_with(".nix"){ 213 | continue; 214 | } 215 | //Open file 216 | let f = match File::open(entry.path()){ 217 | Ok(x) => x, 218 | Err(_) => continue, 219 | }; 220 | println!("{}", entry.path().to_str().unwrap()); 221 | 222 | 223 | //btree is used to store all versions (sorted). 224 | let mut all_versions = parseCrates(&f); 225 | 226 | if all_versions.len() == 0{ 227 | println!("WARNING: empty package"); 228 | continue; 229 | } 230 | 231 | let new_sub_path = (entry.path().to_str().unwrap().trim_left_matches(input)).to_string() + ".nix"; 232 | let new_path = output.to_string() + &new_sub_path; 233 | 234 | let mut buffer = File::create(new_path).unwrap(); 235 | 236 | write!(buffer, "#DON'T EDIT. AUTOGENERATED FILE"); 237 | write!(buffer, "\n{{buildCratesLib, allCrates}}:"); 238 | write!(buffer, "\nrec {{"); 239 | 240 | let (first_key, first_value) = all_versions.iter().next().unwrap(); 241 | let mut prev = first_value.clone(); 242 | let mut prev_version = first_key.clone(); 243 | let mut prev_path = new_sub_path.clone(); 244 | 245 | let name = first_value.name.clone(); 246 | write!(packages, "\n \"all__{}\" = self.callPackage ./{} {};", name , new_sub_path, "{ }"); 247 | for (version, c) in &all_versions { 248 | let next_crate = c.clone(); 249 | //create a string containing all deps 250 | let dep_str = create_dep_string(&next_crate.deps); 251 | 252 | let full_version = "_".to_string() + &next_crate.vers.replace(".", "_"); 253 | let package_name = next_crate.name.clone() + &full_version; 254 | let data = HashBuilder::new() 255 | .insert("package_name", package_name.clone()) 256 | .insert("name", next_crate.name.clone()) 257 | .insert("vers", next_crate.vers) 258 | .insert("cksum", next_crate.cksum) 259 | .insert("deps", dep_str); 260 | 261 | //write nix file 262 | let mut rv = Cursor::new(Vec::new()); 263 | data.render(template, &mut rv).unwrap(); 264 | let res = String::from_utf8(rv.into_inner()).unwrap(); 265 | 266 | write!(buffer, "{}", res); 267 | //add entry to the generated-crates.nix 268 | // write!(packages, "\n\"{}\" = all__{}.\"{}\";", package_name, name, package_name); 269 | 270 | let full_version = "_".to_string() + &prev_version[0].to_string() + "_" + &prev_version[1].to_string() + "_" + &prev_version[2].to_string(); 271 | 272 | if prev_version[0] < version[0] { 273 | let smal_version = "_".to_string() + &prev_version[0].to_string() + "_" + &prev_version[1].to_string(); 274 | let package_name = prev.name.clone() + &smal_version; 275 | // write!(packages, "\n\"{}\" = all__{}.\"{}\";", package_name, name, prev.name.clone() + &full_version); 276 | write!(buffer, "\n \"{}\" = {};", package_name, prev.name.clone() + &full_version); 277 | 278 | let smal_version = "_".to_string() + &prev_version[0].to_string(); 279 | let package_name = prev.name.clone() + &smal_version; 280 | // write!(packages, "\n\"{}\" = all__{}.\"{}\";", package_name, name, prev.name.clone() + &full_version); 281 | write!(buffer, "\n \"{}\" = {};", package_name, prev.name.clone() + &full_version); 282 | }else if prev_version[1] < version[1] { 283 | let smal_version = "_".to_string() + &prev_version[0].to_string() + "_" + &prev_version[1].to_string(); 284 | let package_name = prev.name.clone() + &smal_version; 285 | // write!(packages, "\n\"{}\" = all__{}.\"{}\";", package_name, name, prev.name.clone() + &full_version); 286 | write!(buffer, "\n \"{}\" = {};", package_name, prev.name.clone() + &full_version); 287 | } 288 | 289 | 290 | prev_version = version.clone(); 291 | prev = c.clone(); 292 | } 293 | //add more versions to the generated-crates.nix file 294 | let full_version = "_".to_string() + &prev_version[0].to_string() + "_" + &prev_version[1].to_string() + "_" + &prev_version[2].to_string(); 295 | 296 | let smal_version = "_".to_string() + &prev_version[0].to_string() + "_" + &prev_version[1].to_string(); 297 | let package_name = prev.name.clone() + &smal_version; 298 | // write!(packages, "\n\"{}\" = all__{}.\"{}\";", package_name, name, prev.name.clone() + &full_version); 299 | write!(buffer, "\n \"{}\" = {};", package_name, prev.name.clone() + &full_version); 300 | let smal_version = "_".to_string() + &prev_version[0].to_string(); 301 | let package_name = prev.name.clone() + &smal_version; 302 | // write!(packages, "\n\"{}\" = all__{}.\"{}\";", package_name, name, prev.name.clone() + &full_version); 303 | write!(buffer, "\n \"{}\" = {};", package_name, prev.name.clone() + &full_version); 304 | 305 | write!(packages, "\n \"{}\" = all__{}.\"{}\";", prev.name.clone(), name, prev.name.clone() + &full_version); 306 | 307 | 308 | //closing brace for the crates - nix expression 309 | write!(buffer, "}}"); 310 | 311 | } 312 | } 313 | // closing braces for teh generated crates.nix file 314 | write!(packages, "\n }};"); 315 | write!(packages, "\n }}"); 316 | } 317 | --------------------------------------------------------------------------------