Sbt in project plugin, how to structure them? - sbt

We do have a custom plugin as a single file in our project folder:
acme-project
|- ...
|- project
| |- CustomPlugin.scala
object CustomPlugin extends AutoPlugin {
// ...
That was simple and easy until that plugin started to grow...
In the first step, we added more classes/objects to the same source file. However, it continues to grow and I would like to add more structure via packages.
acme-project
|- ...
|- project
| |- CustomPlugin.scala
| |- SupportingClass.scala
| |- acme
| | |- plugin
| | | |- PackagedClass.scala
My CustomPlugin seems to be able to use the SupportingClass from the folder, whenever this class declare another package. However, I cannot use the PackagedClass :
[error] /~/acme-project/project/CustomPlugin.scala:1:8: not found: object acme
[error] import mega.plugin.PackagedClass
[error]             ^
I tried to add one src/main/scala folder but have the same kind of import errors.
So, I would like to know if there are ways to create large/structured plugins inside a project without making a complete one?
I would like to keep the simplicity of this format where I do not have to publish my plugin. Having it inside a dedicated module would be ok.
Thanks

One way to do this is to restructure your plugin as its own sbt project, then load it as a module dependency in your project's plugins.sbt.
Move the code to its own directory. This can be anywhere you like, e.g.:
acme-project/project/my-custom-plugin/
acme-project/my-custom-plugin/
some-other-path/my-custom-plugin/
Write a my-custom-plugin/build.sbt with at least these settings:
enablePlugins(SbtPlugin)
sbtPlugin := true
scalaVersion := "2.12.16"
name := "my-custom-plugin"
Add it to your project as a module dependency in acme-project/project/plugins.sbt:
// For acme-project/project/my-custom-plugin/
val myCustomPlugin =
project in file("my-custom-plugin")
// For acme-project/my-custom-plugin/
val myCustomPlugin =
ProjectRef(file("../../my-custom-plugin"), "my-custom-plugin")
// For some-other-path/my-custom-plugin/
val myCustomPlugin =
ProjectRef(file("/path/to/my-custom-plugin", "my-custom-plugin")
dependsOn(myCustomPlugin)
You only need one of those val myCustomPlugin = lines, depending on where you put your my-custom-plugin/ directory.

Related

Next.js Sub-Pages for parameterized routes

Right now, my routing looks like this:
https://app.com/users opens pages/users/index.js
https://app.com/users/:userid opens pages/users/[id].js
I want to create route, for example:
https://app.com/users/:id/friends -> show all friends for the user
or even
https://app.com/users/:id/friends/:friendId -> show a specific friend
I have tried
pages
users
index.js
[id].js
friends
index.js
[friendId].js
but i can only reach users/friends and not `users/:id/friends``
How do i set my pages directory so i can use this sort of routing?
Also, I want to be able to access id and friendId in the context of getServerSideProps...
If you don't get the answer description well, pls follow the diagram I made.
If you want this https://app.com/users/:id/friends, then you should create something like this:
pages/users/index.js/[id]/index.js/friends.js
So to make this clear, you have a folder name pages (where all pages folder and files are), then you have a user folder (this takes an index.js which means user path). Now in the user folder, you have to create a folder named [id], in this folder you should create a file name index.js, this index.js stand for the :id. The last thing is to create the friend.js in the [id] folder.
Something like this.
pages ----------------- Main folder
users ------------- A folder inside `pages` folder
index.js ------- A file inside `users` folder == `https://app.com/users`
[id] ----------- A folder inside `users` folder
index.js ---- A file inside `[id]` folder ==`https://app.com/users/:id`
friends.js -- A file inside `[id]` folder == `https://app.com/users/:id/friends`
If you want something like this https://app.com/users/:id/friends/:friendId
Then you will have to do something like this:
pages ------------------------- Main folder
users --------------------- A folder inside `pages` folder
index.js --------------- A file inside `users` folder == `https://app.com/users`
[id] ------------------- A folder inside `users` folder
index.js ------------ A file inside `[id]` folder ==`https://app.com/users/:id`
[friends] -------- A folder inside `[id]` folder
index.js ------ A file inside `[friends]` folder
friendId.js --- A file inside `[friends]` folder
You can use Dynamic Routing syntax in your folders instead of a file in order to nest them (create a folder [id] instead of a file [id].js). For your specific example it would look like this:
pages
users
index.js
[id]
friends
[friendId].js

NextJS i18next Nextjs Localize Routes

I've fully implemented next-i18next for my NextJS website. Everything is working as it should be:
Automatically detects language using i18next middleware
Changes language with language select button
Translations with only loading in relevant namespaces etc etc
However, I would like to localise the route names so that they reflect the set language.
I understand how this can be done using next-routes and this exchange was particularly useful:
How do I localize routes with next.js and next-i18next?
In that example, routes are set up like:
routes.add('en-home', '/', 'index')
routes.add('de-home', '/de', 'index')
routes.add('en-test', '/test', 'test')
routes.add('de-test', '/de/prufung', 'test')
I tried to implement Route and Link from next-routes using the following pattern as an example:
Get current language from i18n.language
Set link url according to language set
<Link route={`${lang}-home`}></Link>
And again, using a similar pattern for next-routes Router such as:
Router.pushRoute(`${lang}-home`)
However, this is not working.
I noticed in the referenced thread that #samuelg0rd0n commented that he created a custom Link component.
Please can anybody guide me how to change all the routes according to which language the website is set to?
Thanks!
I strongly recommend you trying an official Next.js example:
Next.js -- Named routes example (next-routes)
https://github.com/zeit/next.js/tree/canary/examples/with-next-routes
But I'm seen that it needs an additional server and also will fail if we custom our app structure as my own project example:
| src/app
| -- pages
| -- post.js
| -- category.js
| -- server.js (for routes)
| src/functions
| -- index.js (lambda function for server-side)
And if I run next src/app it will fail with the following error:
Error: > Couldn't find a `pages` directory. Please create one under the project root
at findPagesDir (/home/paneladm/projects/paneladm-dev/travel-website/node_modules/next/dist/lib/find-pages-dir.js:3:170)
at new DevServer (/home/paneladm/projects/paneladm-dev/travel-website/node_modules/next/dist/server/next-dev-server.js:1:3491)
at createServer (/home/paneladm/projects/paneladm-dev/travel-website/node_modules/next/dist/server/next.js:2:105)
at Object.<anonymous> (/home/paneladm/projects/paneladm-dev/travel-website/src/app/server.js:14:13)
at Module._compile (module.js:653:30)
at Object.Module._extensions..js (module.js:664:10)
at Module.load (module.js:566:32)
at tryModuleLoad (module.js:506:12)
at Function.Module._load (module.js:498:3)
at Function.Module.runMain (module.js:694:10)
Next.js team is working in a simple solution now
This adds an example showing how to remove the need for a custom server for an existing application using next-routes by leveraging the new custom routes support built-in to Next.js
You should update next to 9.1.+ and implement your own routes as following:
const nextRoutes = require('next-routes');
const routes = (module.exports = nextRoutes());
routes.add('category', '/category/:slug');
routes.add('post', '/post/:lang/:slug');
In your next.config.js file, enable experimental property and implement rewrites method as below:
const { routes } = require('./routes');
...
experimental: {
rewrites() {
const rewrites = [];
for (const route of routes) {
if (route.pattern !== route.page) {
rewrites.push({
source: route.pattern,
destination: route.page,
});
}
}
return rewrites;
}
},
Now your structure should be:
| src/app
| -- pages
| -- post.js
| -- category.js
But if you want to custom your pages, try change the routes like this:
...
routes.add('category/[slug]', '/category/:slug');
routes.add('post/[slug]', '/post/:lang/:slug');
It will point to pages --> category --> [slug].js file instead.
See more details in the new PR implementation files.
References
Next.js PR 9519 - Add next-routes/custom-routes example

Is it possible to add properties to multiple files after they have been uploaded to artifactory?

As the title says. Due to a lack of understanding about how best to query files in artifactory I now have a situation where I have a few hundred files I need to add the same properties to.
Can this be done in bulk?
the folder structure looks like this:
repository
|
|- main folder
|
|- type
|
|- language1
|
|-sub-folder1
|-sub-folder2
|-file1
|-file2
...
...
...
Each sub-folder can have around 5 files, each language folder can have many sub-folders.
Sure it is.
You have two main options.
The first one is to use the Set Item Properties REST API on the relevant folder with the "recursiveProperties=1".
The second option, which I believe is better, will be to use the JFrog CLI to set properties on existing artifacts. This options will provide you with the ability to define a more complex logic on setting the properties.

Testing a file upload to a form in a Behat feature file

I am quite new to writing Behat test suites and I am currently trying to flesh out my existing feature file with an added test to test an uploaded file.
This is what I have come up with so far.
Scenario: Submitting a valid asset form and uploading a file
When I submit a asset form with values:
| name | type | position | active | file |
| St Andrews Release | image | 1 | 1 | /web/images/product/icon/default.jpg |
Then the form should be valid
And the entity form entity should have the following values
| name | type | position | active | file |
| St Andrews Release | image | 1 | 1 | /web/images/product/icon/default.jpg |
Failed asserting that null matches expected '/web/images/product/icon/default.jpg'.
And the entity form entity should be persisted correctly
This is the method handling the scenario:
/**
* #When I submit a asset form with values:
*/
public function iSubmitAssetFormWithValues(TableNode $table)
{
$data = $table->getColumnsHash()[0];
$this->form = $this->submitTheForm('crmpicco.asset.type', $this->entity, $data);
}
The submitTheForm method returns a Symfony\Component\Form\FormInterface.
Am I along the right lines? I am currently getting an error:
Failed asserting that null matches expected
'/web/images/product/swatch/default.jpg'.
I suggest you to create a dedicated folder structure for files which will be used in behat tests right in your application root because tests and the files used in tests must be consistent for all developers. I sometimes see people writing tests to upload files that exist on their local desktop:) My desktop and your desktop would be different hence reason the test would fail.
Structure
football #your application name/root
build
dummy
document
hello.doc
world.xls
image
test.jpg
behat.yml
Apart from other common setting, you must define file_path.
....
....
default:
extensions:
Behat\MinkExtension\Extension:
files_path: %behat.paths.base%/build/dummy/
....
....
Example Gherkin scenario
Feature: I can upload a file which is stored in my generic "dummy" folder
Scenario: I can upload image
Given I am on "/"
When I attach the file "image/test.jpg" to "league_flag"
And I press "Submit"
Then I should see "Succeeded."

<h:outputStylesheet> and relative references

I have a JSF project setup in the typical fashion:
myproject
|-- src/main/webapps
| |-- resources
| | |-- css
| | | |-- 3rdparty.css
| | |
| | |-- fonts
| | |
| | |-- myspecialfont.woff
| |
And then in my JSF html:
<h:outputStylesheet name="3rdparty.css" library="css"/>
This works well, since I can keep the directories consistent if I need to upgrade.
However, in this case, the 3rdparty.css file contains a relative reference:
#font-face {
font-family: 'Lato';
src: url('../fonts/myspecialfont.woff');
}
As h:outputStylesheet constructs the URI to use mywebapp/javax.faces.resource/3rdparty.css this will break the relative references inside it since that path will now refer to mywebapp/fonts/myspecialfont.woff.
Is there a good way to keep these locally hosted 3rd party libraries referenced by JSF to handle this kind of relative reference without resorting to manually changing the CSS?
You have two options:
Do not use outputStyleSheet and instead include it directly in your template
Modify the CSS file content (as TemarV suggested)
Unfortunately there isn't much else that can be done, because resources are rendered using a different path where-in the library & resource reference are specified as URL parameters instead of being part of the URL.
Edit: I would like to highlight a 3rd option as well - writing a custom ResourceHandler. I had to do something on these lines. You can read more about it at -
http://roguexz.blogspot.in/2013/10/jsf-2-returning-resource-url-that-is.html

Resources